Snap for 8730993 from c4fdff78b9d22c9d81fe6a862fbd06596185fbac to mainline-tzdata3-release

Change-Id: If1a64749f9df5cae3d6e5701d815668a1d5ad0e1
diff --git a/Android.bp b/Android.bp
index fab53d1..9aa92f9 100644
--- a/Android.bp
+++ b/Android.bp
@@ -14,19 +14,32 @@
 
 
 package {
-    // See: http://go/android-license-faq
-    default_applicable_licenses: [
-        "Android-Apache-2.0",
-        "frameworks_opt_telephony_license",
-    ],
+    default_applicable_licenses: ["frameworks_opt_telephony_license"],
 }
 
+// Added automatically by a large-scale-change that took the approach of
+// 'apply every license found to every target'. While this makes sure we respect
+// every license restriction, it may not be entirely correct.
+//
+// e.g. GPL in an MIT project might only apply to the contrib/ directory.
+//
+// Please consider splitting the single license below into multiple licenses,
+// taking care not to lose any license_kind information, and overriding the
+// default license using the 'licenses: [...]' property on targets as needed.
+//
+// For unused files, consider creating a 'fileGroup' with "//visibility:private"
+// to attach the license to, and including a comment whether the files may be
+// used in the current project.
+// See: http://go/android-license-faq
 license {
     name: "frameworks_opt_telephony_license",
     visibility: [":__subpackages__"],
     license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+        "SPDX-license-identifier-BSD",
         "legacy_not_a_contribution",
     ],
+    // large-scale-change unable to identify any license_text files
 }
 
 filegroup {
@@ -57,6 +70,14 @@
     srcs: ["jarjar-rules-shared.txt"],
 }
 
+genrule {
+    name: "statslog-telephony-java-gen",
+    tools: ["stats-log-api-gen"],
+    cmd: "$(location stats-log-api-gen) --java $(out) --module telephony"
+        + " --javaPackage com.android.internal.telephony --javaClass TelephonyStatsLog",
+    out: ["com/android/internal/telephony/TelephonyStatsLog.java"],
+}
+
 java_library {
     name: "telephony-common",
     installable: true,
@@ -68,6 +89,7 @@
         ":opt-telephony-common-srcs",
         ":framework-telephony-common-shared-srcs",
         ":net-utils-telephony-common-srcs",
+        ":statslog-telephony-java-gen",
         ":statslog-cellbroadcast-java-gen",
         "src/java/**/I*.aidl",
         "src/java/**/*.logtags",
@@ -83,13 +105,6 @@
         "android.hardware.radio-V1.4-java",
         "android.hardware.radio-V1.5-java",
         "android.hardware.radio-V1.6-java",
-        "android.hardware.radio.config-V1-java",
-        "android.hardware.radio.data-V1-java",
-        "android.hardware.radio.messaging-V1-java",
-        "android.hardware.radio.modem-V1-java",
-        "android.hardware.radio.network-V1-java",
-        "android.hardware.radio.sim-V1-java",
-        "android.hardware.radio.voice-V1-java",
         "voip-common",
         "ims-common",
         "unsupportedappusage",
@@ -106,7 +121,6 @@
         "net-utils-framework-common",
         "telephony-protos",
         "modules-utils-build_system",
-        "modules-utils-statemachine",
     ],
 
     product_variables: {
@@ -115,11 +129,4 @@
             enabled: false,
         },
     },
-
-    optimize: {
-        enabled: true,
-        shrink: true,
-        obfuscate: false,
-        proguard_flags_files: ["proguard.flags"],
-    },
 }
diff --git a/OWNERS b/OWNERS
index 94509fe..003cc3c 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,22 +1,16 @@
-amagup@google.com
-amallampati@google.com
-amruthr@google.com
+amitmahajan@google.com
 breadley@google.com
-chinmayd@google.com
 fionaxu@google.com
-huiwang@google.com
 jackyu@google.com
-jayachandranc@google.com
-linggm@google.com
-mtelang@google.com
 rgreenwalt@google.com
-sarahchin@google.com
-sasindran@google.com
 tgunn@google.com
-tjstuart@google.com
+jminjie@google.com
+shuoq@google.com
+nazaninb@google.com
+sarahchin@google.com
 xiaotonj@google.com
-
-
-
-
+huiwang@google.com
+jayachandranc@google.com
+chinmayd@google.com
+amruthr@google.com
 
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 55f1ccc..75b9d49 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -10,38 +10,6 @@
     },
     {
       "name": "CarrierAppIntegrationTestCases"
-    },
-    {
-      "name": "CtsTelephony2TestCases",
-      "options": [
-        {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
-        }
-      ]
-    },
-    {
-      "name": "CtsTelephony3TestCases",
-      "options": [
-        {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
-        }
-      ]
-    },
-    {
-      "name": "CtsSimRestrictedApisTestCases",
-      "options": [
-        {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
-        }
-      ]
-    },
-    {
-      "name": "CtsTelephonyProviderTestCases",
-      "options": [
-        {
-          "exclude-annotation": "androidx.test.filters.FlakyTest"
-        }
-      ]
     }
   ]
 }
diff --git a/jarjar-rules-shared.txt b/jarjar-rules-shared.txt
index 2353507..4f3f617 100644
--- a/jarjar-rules-shared.txt
+++ b/jarjar-rules-shared.txt
@@ -15,6 +15,7 @@
 rule com.android.internal.util.HexDump* com.android.internal.telephony.HexDump@1
 rule com.android.internal.util.IState* com.android.internal.telephony.IState@1
 rule com.android.internal.util.IndentingPrintWriter* com.android.internal.telephony.IndentingPrintWriter@1
+rule com.android.internal.util.Preconditions* com.android.internal.telephony.Preconditions@1
 rule com.android.internal.util.State* com.android.internal.telephony.State@1
 rule com.android.internal.util.StateMachine* com.android.internal.telephony.StateMachine@1
 rule com.android.internal.util.UserIcons* com.android.internal.telephony.UserIcons@1
diff --git a/proguard.flags b/proguard.flags
deleted file mode 100644
index ebc8922..0000000
--- a/proguard.flags
+++ /dev/null
@@ -1,29 +0,0 @@
-# Uncomment the following to show all included rules during build
-#-printconfiguration
-
-# Generate usage file (for shrinking)
--printusage
-
-# Keep deprecated GSM SMS API
--keepclasseswithmembers class android.telephony.gsm.SmsManager,android.telephony.gsm.SmsManager$* {
-public *;
-}
--keepclasseswithmembers class android.telephony.gsm.SmsMessage,android.telephony.gsm.SmsMessage$* {
-public protected *;
-}
-
-# Keep telephony sysprop
--keepclasseswithmembers class android.internal.telephony.sysprop.TelephonyProperties {
-public *;
-}
-
-# Keep public classes and public/protected members
--keepclasseswithmembers class com.android.internal.telephony.** {
-public protected *;
-}
-
-# Keep classes and members that have the @UnsupportedAppUsage annotation
--keep @**.UnsupportedAppUsage class *
--keepclassmembers class * {
-@**.UnsupportedAppUsage *;
-}
diff --git a/proto/src/persist_atoms.proto b/proto/src/persist_atoms.proto
index c10eeb5..1701318 100644
--- a/proto/src/persist_atoms.proto
+++ b/proto/src/persist_atoms.proto
@@ -23,7 +23,7 @@
 
 // Holds atoms to store on persist storage in case of power cycle or process crash.
 // NOTE: using int64 rather than google.protobuf.Timestamp for timestamps simplifies implementation.
-// Next id: 50
+// Next id: 22
 message PersistAtoms {
     /* Aggregated RAT usage during the call. */
     repeated VoiceCallRatUsage voice_call_rat_usage = 1;
@@ -89,94 +89,10 @@
     optional string build_fingerprint = 21;
 
     /* Summary of received network requests. */
-    repeated NetworkRequests network_requests = 22 [deprecated = true];
+    repeated NetworkRequests network_requests = 22;
 
     /* Timestamp of last network_requests pull. */
-    optional int64 network_requests_pull_timestamp_millis = 23 [deprecated = true];
-
-    /* RCS single registrtions feature tag information. */
-    repeated ImsRegistrationFeatureTagStats ims_registration_feature_tag_stats = 24;
-
-    /* Timestamp of last ims_registration_feature_tag_stats pull. */
-    optional int64 ims_registration_feature_tag_stats_pull_timestamp_millis = 25;
-
-    /* RCS client provisioning statistics and information. */
-    repeated RcsClientProvisioningStats rcs_client_provisioning_stats = 26;
-
-    /* Timestamp of last rcs_client_provisioning_stats pull. */
-    optional int64 rcs_client_provisioning_stats_pull_timestamp_millis = 27;
-
-    /* RCS configuration statistics and information based ACS. */
-    repeated RcsAcsProvisioningStats rcs_acs_provisioning_stats = 28;
-
-    /* Timestamp of last rcs_acs_provisioning_stats pull. */
-    optional int64 rcs_acs_provisioning_stats_pull_timestamp_millis = 29;
-
-    /* SIP delegate statistics and information. */
-    repeated SipDelegateStats sip_delegate_stats = 30;
-
-    /* Timestamp of last sip_delegate_stats pull. */
-    optional int64 sip_delegate_stats_pull_timestamp_millis = 31;
-
-    /* SIP Transport featuere tag statistics and information. */
-    repeated SipTransportFeatureTagStats sip_transport_feature_tag_stats = 32;
-
-    /* Timestamp of last sip_transport_feature_tag_stats pull. */
-    optional int64 sip_transport_feature_tag_stats_pull_timestamp_millis = 33;
-
-    /* SIP Message response statistics and information. */
-    repeated SipMessageResponse sip_message_response = 34;
-
-    /* Timestamp of last sip_message_response pull. */
-    optional int64 sip_message_response_pull_timestamp_millis = 35;
-
-    /* SIP Transport session statistics and information. */
-    repeated SipTransportSession sip_transport_session = 36;
-
-    /* Timestamp of last sip_transport_session pull. */
-    optional int64 sip_transport_session_pull_timestamp_millis = 37;
-
-    /* Dedicated bearer listener statistics and information. */
-    repeated ImsDedicatedBearerListenerEvent ims_dedicated_bearer_listener_event = 38;
-
-    /* Timestamp of last ims_dedicated_bearer_listener_event pull. */
-    optional int64 ims_dedicated_bearer_listener_event_pull_timestamp_millis = 39;
-
-    /* Dedicated bearer event statistics and information. */
-    repeated ImsDedicatedBearerEvent ims_dedicated_bearer_event = 40;
-
-    /* Timestamp of last ims_dedicated_bearer_event pull. */
-    optional int64 ims_dedicated_bearer_event_pull_timestamp_millis = 41;
-
-    /* Publish featere tag statistics and information. */
-    repeated ImsRegistrationServiceDescStats ims_registration_service_desc_stats = 42;
-
-    /* Timestamp of last ims_registration_service_desc_stats pull. */
-    optional int64 ims_registration_service_desc_stats_pull_timestamp_millis = 43;
-
-    /* UCE event stats statistics and information. */
-    repeated UceEventStats uce_event_stats = 44;
-
-    /* Timestamp of last uce_event_stats pull. */
-    optional int64 uce_event_stats_pull_timestamp_millis = 45;
-
-    /* Presence notify event statistics and information. */
-    repeated PresenceNotifyEvent presence_notify_event = 46;
-
-    /* Timestamp of last presence_notify_event pull. */
-    optional int64 presence_notify_event_pull_timestamp_millis = 47;
-
-    /* GBA event statistics and information. */
-    repeated GbaEvent gba_event = 48;
-
-    /* Timestamp of last gba_event pull. */
-    optional int64 gba_event_pull_timestamp_millis = 49;
-
-    /* Summary of received network requests. */
-    repeated NetworkRequestsV2 network_requests_v2 = 50;
-
-    /* Timestamp of last network_requests_v2 pull. */
-    optional int64 network_requests_v2_pull_timestamp_millis = 51;
+    optional int64 network_requests_pull_timestamp_millis = 23;
 }
 
 // The canonical versions of the following enums live in:
@@ -218,7 +134,7 @@
     optional bool video_enabled = 29;
     optional int32 rat_at_connected = 30;
     optional bool is_multiparty = 31;
-    optional int32 call_duration = 32;
+
     // Internal use only
     optional int64 setup_begin_millis = 10001;
 }
@@ -261,7 +177,6 @@
     optional int32 carrier_id = 11;
     optional int64 message_id = 12;
     optional int32 retry_id = 13;
-    optional int64 interval_millis = 14;
 }
 
 message CarrierIdMismatch {
@@ -291,7 +206,6 @@
     optional int64 duration_minutes = 17;
     optional bool ongoing = 18;
     optional int32 band_at_end = 19;
-    repeated int32 handover_failure_causes = 20;
 }
 
 message CellularServiceState {
@@ -304,7 +218,6 @@
     optional bool is_multi_sim = 7;
     optional int32 carrier_id = 8;
     optional int64 total_time_millis = 9; // Duration needs to be rounded when pulled
-    optional bool is_emergency_only = 10;
 
     // Internal use only
     optional int64 last_used_millis = 10001;
@@ -355,146 +268,8 @@
     optional int64 last_used_millis = 10001;
 }
 
-// deprecated - please use NetworkRequestsV2 instead
 message NetworkRequests {
     optional int32 carrier_id = 1;
     optional int32 enterprise_request_count = 2;
     optional int32 enterprise_release_count = 3;
 }
-
-message NetworkRequestsV2 {
-    enum NetworkCapability {
-        UNKNOWN = 0;
-        PRIORITIZE_LATENCY = 1;
-        PRIORITIZE_BANDWIDTH = 2;
-        CBS = 3;
-        ENTERPRISE = 4;
-    }
-    optional int32 carrier_id = 1;
-    optional NetworkCapability capability = 2;
-    optional int32 request_count = 3;
-}
-
-message ImsRegistrationFeatureTagStats {
-    optional int32 carrier_id = 1;
-    optional int32 slot_id = 2;
-    optional int32 feature_tag_name = 3;
-    optional int32 registration_tech = 4;
-    optional int64 registered_millis = 5;
-}
-
-message RcsClientProvisioningStats {
-    optional int32 carrier_id = 1;
-    optional int32 slot_id = 2;
-    optional int32 event = 3;
-    optional int32 count = 4;
-}
-
-message RcsAcsProvisioningStats {
-    optional int32 carrier_id = 1;
-    optional int32 slot_id = 2;
-    optional int32 response_code = 3;
-    optional int32 response_type = 4;
-    optional bool is_single_registration_enabled = 5;
-    optional int32 count = 6;
-    optional int64 state_timer_millis = 7;
-}
-
-message SipDelegateStats {
-    optional int32 dimension = 1;
-    optional int32 carrier_id = 2;
-    optional int32 slot_id = 3;
-    optional int32 destroy_reason = 4;
-    optional int64 uptime_millis = 5;
-}
-
-message SipTransportFeatureTagStats {
-    optional int32 carrier_id = 1;
-    optional int32 slot_id = 2;
-    optional int32 feature_tag_name = 3;
-    optional int32 sip_transport_denied_reason = 4;
-    optional int32 sip_transport_deregistered_reason = 5;
-    optional int64 associated_millis = 6;
-}
-
-message SipMessageResponse {
-    optional int32 carrier_id = 1;
-    optional int32 slot_id = 2;
-    optional int32 sip_message_method = 3;
-    optional int32 sip_message_response = 4;
-    optional int32 sip_message_direction = 5;
-    optional int32 message_error = 6;
-    optional int32 count = 7;
-}
-
-message SipTransportSession {
-    optional int32 carrier_id = 1;
-    optional int32 slot_id = 2;
-    optional int32 session_method = 3;
-    optional int32 sip_message_direction = 4;
-    optional int32 sip_response = 5;
-    optional int32 session_count = 6;
-    optional int32 ended_gracefully_count = 7;
-
-    // Internal use only
-    optional bool is_ended_gracefully = 10001;
-}
-
-message ImsDedicatedBearerListenerEvent {
-    optional int32 carrier_id = 1;
-    optional int32 slot_id = 2;
-    optional int32 rat_at_end = 3;
-    optional int32 qci = 4;
-    optional bool dedicated_bearer_established = 5;
-    optional int32 event_count = 6;
-}
-
-message ImsDedicatedBearerEvent {
-    optional int32 carrier_id = 1;
-    optional int32 slot_id = 2;
-    optional int32 rat_at_end = 3;
-    optional int32 qci = 4;
-    optional int32 bearer_state = 5;
-    optional bool local_connection_info_received = 6;
-    optional bool remote_connection_info_received = 7;
-    optional bool has_listeners = 8;
-    optional int32 count = 9;
-}
-
-message ImsRegistrationServiceDescStats {
-    optional int32 carrier_id = 1;
-    optional int32 slot_id = 2;
-    optional int32 service_id_name = 3;
-    optional float service_id_version = 4;
-    optional int32 registration_tech = 5;
-    optional int64 published_millis = 6;
-}
-
-message UceEventStats {
-    optional int32 carrier_id = 1;
-    optional int32 slot_id = 2;
-    optional int32 type = 3;
-    optional bool successful = 4;
-    optional int32 command_code = 5;
-    optional int32 network_response = 6;
-    optional int32 count = 7;
-}
-
-message PresenceNotifyEvent {
-    optional int32 carrier_id = 1;
-    optional int32 slot_id = 2;
-    optional int32 reason = 3;
-    optional bool content_body_received = 4;
-    optional int32 rcs_caps_count = 5;
-    optional int32 mmtel_caps_count = 6;
-    optional int32 no_caps_count = 7;
-    optional int32 count = 8;
-}
-
-message GbaEvent {
-    optional int32 carrier_id = 1;
-    optional int32 slot_id = 2;
-    optional bool successful = 3;
-    optional int32 failed_reason = 4;
-    optional int32 count = 5;
-}
diff --git a/proto/src/telephony.proto b/proto/src/telephony.proto
index 6d3d711..0d9ee80 100644
--- a/proto/src/telephony.proto
+++ b/proto/src/telephony.proto
@@ -2297,28 +2297,6 @@
       // after call is connected
       optional bool tx_silence_detected = 14;
 
-      // the number of Voice frames sent by jitter buffer to audio
-      optional int32 voice_frames = 15;
-
-      // the number of NO_DATA frames sent by jitter buffer to audio
-      optional int32 no_data_frames = 16;
-
-      // the number of RTP voice packets dropped by jitter buffer
-      optional int32 rtp_dropped_packets = 17;
-
-      // the minimum playout delay in the reporting interval, in milliseconds
-      optional int64 min_playout_delay_millis = 18;
-
-      // the maximum playout delay in the reporting interval, in milliseconds
-      optional int64 max_playout_delay_millis = 19;
-
-      // the total number of RTP SID packets received by this device
-      // for an ongoing call
-      optional int32 rx_rtp_sid_packets = 20;
-
-      // the total number of RTP duplicate packets received by this device
-      // for an ongoing call
-      optional int32 rtp_duplicate_packets = 21;
     }
 
     message CallQualitySummary {
diff --git a/src/java/com/android/internal/telephony/AppSmsManager.java b/src/java/com/android/internal/telephony/AppSmsManager.java
index d2225ff..64a5bdc 100644
--- a/src/java/com/android/internal/telephony/AppSmsManager.java
+++ b/src/java/com/android/internal/telephony/AppSmsManager.java
@@ -33,11 +33,11 @@
 import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
 
 import java.security.SecureRandom;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.Objects;
 import java.util.concurrent.TimeUnit;
 
 
@@ -116,10 +116,9 @@
             @NonNull String callingPackageName,
             @Nullable String prefixes,
             @NonNull PendingIntent intent) {
-        if (TextUtils.isEmpty(callingPackageName)) {
-            throw new IllegalArgumentException("callingPackageName cannot be null or empty.");
-        }
-        Objects.requireNonNull(intent, "intent cannot be null");
+        Preconditions.checkStringNotEmpty(callingPackageName,
+                "callingPackageName cannot be null or empty.");
+        Preconditions.checkNotNull(intent, "intent cannot be null");
         // Check calling uid matches callingpkg.
         AppOpsManager appOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
         appOps.checkPackage(Binder.getCallingUid(), callingPackageName);
@@ -205,8 +204,8 @@
                     // do nothing
                 }
                 // Remove from mTokenMap and mPackageMap
-                mPackageMap.remove(entry.getValue().packageName);
                 iterator.remove();
+                mPackageMap.remove(entry.getValue().packageName);
             }
         }
     }
diff --git a/src/java/com/android/internal/telephony/BaseCommands.java b/src/java/com/android/internal/telephony/BaseCommands.java
index 972884a..02530da 100644
--- a/src/java/com/android/internal/telephony/BaseCommands.java
+++ b/src/java/com/android/internal/telephony/BaseCommands.java
@@ -55,7 +55,6 @@
     protected RegistrantList mNetworkStateRegistrants = new RegistrantList();
     protected RegistrantList mDataCallListChangedRegistrants = new RegistrantList();
     protected RegistrantList mApnUnthrottledRegistrants = new RegistrantList();
-    protected RegistrantList mSlicingConfigChangedRegistrants = new RegistrantList();
     @UnsupportedAppUsage
     protected RegistrantList mVoiceRadioTechChangedRegistrants = new RegistrantList();
     @UnsupportedAppUsage
@@ -320,16 +319,6 @@
     }
 
     @Override
-    public void registerForSlicingConfigChanged(Handler h, int what, Object obj) {
-        mSlicingConfigChangedRegistrants.addUnique(h, what, obj);
-    }
-
-    @Override
-    public void unregisterForSlicingConfigChanged(Handler h) {
-        mSlicingConfigChangedRegistrants.remove(h);
-    }
-
-    @Override
     public void registerForVoiceRadioTechChanged(Handler h, int what, Object obj) {
         mVoiceRadioTechChangedRegistrants.addUnique(h, what, obj);
     }
diff --git a/src/java/com/android/internal/telephony/BtSmsInterfaceManager.java b/src/java/com/android/internal/telephony/BtSmsInterfaceManager.java
index b340bcf..40e9a1c 100644
--- a/src/java/com/android/internal/telephony/BtSmsInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/BtSmsInterfaceManager.java
@@ -25,14 +25,10 @@
 import android.content.Context;
 import android.net.Uri;
 import android.telecom.PhoneAccount;
-import android.telephony.Rlog;
 import android.telephony.SmsManager;
 import android.telephony.SubscriptionInfo;
 import android.util.Log;
 
-import java.util.Collection;
-import java.util.Collections;
-
 
 /**
  * BtSmsInterfaceManager to provide a mechanism for sending SMS over Bluetooth
@@ -54,7 +50,7 @@
         }
         BluetoothDevice device = btAdapter.getRemoteDevice(info.getIccId());
         if (device == null) {
-            Log.d(LOG_TAG, "Bluetooth device addr invalid: " + Rlog.pii(LOG_TAG, info.getIccId()));
+            Log.d(LOG_TAG, "Bluetooth device addr invalid: " + info.getIccId());
             sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_INVALID_BLUETOOTH_ADDRESS);
             return;
         }
@@ -81,7 +77,7 @@
 
     private class MapMessageSender implements BluetoothProfile.ServiceListener {
 
-        final Collection<Uri> mDestAddr;
+        final Uri[] mDestAddr;
         private String mMessage;
         final BluetoothDevice mDevice;
         final PendingIntent mSentIntent;
@@ -90,10 +86,10 @@
         MapMessageSender(final String destAddr, final String message, final BluetoothDevice device,
                 final PendingIntent sentIntent, final PendingIntent deliveryIntent) {
             super();
-            mDestAddr = Collections.singleton(new Uri.Builder()
+            mDestAddr = new Uri[]{new Uri.Builder()
                     .appendPath(destAddr)
                     .scheme(PhoneAccount.SCHEME_TEL)
-                    .build());
+                    .build()};
             mMessage = message;
             mDevice = device;
             mSentIntent = sentIntent;
diff --git a/src/java/com/android/internal/telephony/Call.java b/src/java/com/android/internal/telephony/Call.java
index 7fb4abf..d04dd43 100644
--- a/src/java/com/android/internal/telephony/Call.java
+++ b/src/java/com/android/internal/telephony/Call.java
@@ -24,7 +24,6 @@
 
 import java.util.ArrayList;
 import java.util.List;
-import java.util.stream.Collectors;
 
 /**
  * {@hide}
@@ -122,17 +121,6 @@
         }
     }
 
-    /**
-     * @return returns a summary of the connections held in this call.
-     */
-    public String getConnectionSummary() {
-        synchronized (mLock) {
-            return mConnections.stream()
-                    .map(c -> c.getTelecomCallId() + "/objId:" + System.identityHashCode(c))
-                    .collect(Collectors.joining(", "));
-        }
-    }
-
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public abstract Phone getPhone();
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
diff --git a/src/java/com/android/internal/telephony/CallManager.java b/src/java/com/android/internal/telephony/CallManager.java
index 9d19c17..d2b1bdd 100644
--- a/src/java/com/android/internal/telephony/CallManager.java
+++ b/src/java/com/android/internal/telephony/CallManager.java
@@ -28,8 +28,8 @@
 import android.telephony.PhoneStateListener;
 import android.telephony.ServiceState;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.imsphone.ImsPhoneConnection;
+import com.android.internal.telephony.sip.SipPhone;
 import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
@@ -61,14 +61,14 @@
     private static final boolean VDBG = false;
 
     private static final int EVENT_DISCONNECT = 100;
-    @VisibleForTesting static final int EVENT_PRECISE_CALL_STATE_CHANGED = 101;
+    private static final int EVENT_PRECISE_CALL_STATE_CHANGED = 101;
     private static final int EVENT_NEW_RINGING_CONNECTION = 102;
     private static final int EVENT_UNKNOWN_CONNECTION = 103;
     private static final int EVENT_INCOMING_RING = 104;
-    @VisibleForTesting static final int EVENT_RINGBACK_TONE = 105;
+    private static final int EVENT_RINGBACK_TONE = 105;
     private static final int EVENT_IN_CALL_VOICE_PRIVACY_ON = 106;
     private static final int EVENT_IN_CALL_VOICE_PRIVACY_OFF = 107;
-    @VisibleForTesting static final int EVENT_CALL_WAITING = 108;
+    private static final int EVENT_CALL_WAITING = 108;
     private static final int EVENT_DISPLAY_INFO = 109;
     private static final int EVENT_SIGNAL_INFO = 110;
     private static final int EVENT_CDMA_OTA_STATUS_CHANGE = 111;
@@ -500,6 +500,11 @@
                 }
 
                 int newAudioMode = AudioManager.MODE_IN_CALL;
+                if (offhookPhone instanceof SipPhone) {
+                    Rlog.d(LOG_TAG, "setAudioMode Set audio mode for SIP call!");
+                    // enable IN_COMMUNICATION audio mode instead for sipPhone
+                    newAudioMode = AudioManager.MODE_IN_COMMUNICATION;
+                }
                 int currMode = audioManager.getMode();
                 if (currMode != newAudioMode || mSpeedUpAudioForMtCall) {
                     // request audio focus before setting the new mode
@@ -734,7 +739,9 @@
 
         Phone fgPhone = getFgPhone(subId);
         if (fgPhone != null) {
-            if (canConference(heldCall)) {
+            if (fgPhone instanceof SipPhone) {
+                ((SipPhone) fgPhone).conference(heldCall);
+            } else if (canConference(heldCall)) {
                 fgPhone.conference();
             } else {
                 throw(new CallStateException("Can't conference foreground and selected background call"));
@@ -1665,7 +1672,8 @@
     }
 
     /**
-     * Return true if there is at least one active foreground call on a particular subId
+     * Return true if there is at least one active foreground call
+     * on a particular subId or an active sip call
      */
     @UnsupportedAppUsage
     public boolean hasActiveFgCall(int subId) {
@@ -1683,7 +1691,8 @@
     }
 
     /**
-     * Return true if there is at least one active background call on a particular subId
+     * Return true if there is at least one active background call
+     * on a particular subId or an active sip call
      */
     @UnsupportedAppUsage
     public boolean hasActiveBgCall(int subId) {
@@ -1760,7 +1769,8 @@
     private Call getFirstNonIdleCall(List<Call> calls, int subId) {
         Call result = null;
         for (Call call : calls) {
-            if (call.getPhone().getSubId() == subId) {
+            if ((call.getPhone().getSubId() == subId) ||
+                    (call.getPhone() instanceof SipPhone)) {
                 if (!call.isIdle()) {
                     return call;
                 } else if (call.getState() != Call.State.IDLE) {
@@ -1801,7 +1811,8 @@
      *
      * Active call means the call is NOT idle defined by Call.isIdle()
      *
-     * 1. If there is only one active background call on given sub, return it
+     * 1. If there is only one active background call on given sub or
+     *    on SIP Phone, return it
      * 2. If there is more than one active background call, return the background call
      *    associated with the active sub.
      * 3. If there is no background call at all, return null.
@@ -1971,7 +1982,8 @@
      */
     private  Call getFirstActiveCall(ArrayList<Call> calls, int subId) {
         for (Call call : calls) {
-            if ((!call.isIdle()) && (call.getPhone().getSubId() == subId)) {
+            if ((!call.isIdle()) && ((call.getPhone().getSubId() == subId) ||
+                    (call.getPhone() instanceof SipPhone))) {
                 return call;
             }
         }
@@ -1996,7 +2008,9 @@
     private Call getFirstCallOfState(ArrayList<Call> calls, Call.State state,
             int subId) {
         for (Call call : calls) {
-            if ((call.getState() == state) || (call.getPhone().getSubId() == subId)) {
+            if ((call.getState() == state) ||
+                ((call.getPhone().getSubId() == subId) ||
+                (call.getPhone() instanceof SipPhone))) {
                 return call;
             }
         }
@@ -2017,14 +2031,17 @@
     /**
      * @return true if more than one active ringing call exists on
      * the active subId.
-     * This checks for the active calls on provided subId.
+     * This checks for the active calls on provided
+     * subId and also active calls on SIP Phone.
      *
      */
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private boolean hasMoreThanOneRingingCall(int subId) {
         int count = 0;
         for (Call call : mRingingCalls) {
-            if ((call.getState().isRinging()) && (call.getPhone().getSubId() == subId)) {
+            if ((call.getState().isRinging()) &&
+                ((call.getPhone().getSubId() == subId) ||
+                (call.getPhone() instanceof SipPhone))) {
                 if (++count > 1) return true;
             }
         }
@@ -2034,13 +2051,16 @@
     /**
      * @return true if more than one active background call exists on
      * the provided subId.
-     * This checks for the background calls on provided subId.
+     * This checks for the background calls on provided
+     * subId and also background calls on SIP Phone.
      *
      */
     private boolean hasMoreThanOneHoldingCall(int subId) {
         int count = 0;
         for (Call call : mBackgroundCalls) {
-            if ((call.getState() == Call.State.HOLDING) && (call.getPhone().getSubId() == subId)) {
+            if ((call.getState() == Call.State.HOLDING) &&
+                ((call.getPhone().getSubId() == subId) ||
+                (call.getPhone() instanceof SipPhone))) {
                 if (++count > 1) return true;
             }
         }
diff --git a/src/java/com/android/internal/telephony/CallTracker.java b/src/java/com/android/internal/telephony/CallTracker.java
index 38c6672..cfa6767 100644
--- a/src/java/com/android/internal/telephony/CallTracker.java
+++ b/src/java/com/android/internal/telephony/CallTracker.java
@@ -24,7 +24,6 @@
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
-import android.telephony.ServiceState;
 import android.text.TextUtils;
 
 import java.io.FileDescriptor;
@@ -178,11 +177,8 @@
                 phone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
         PersistableBundle bundle = configManager.getConfigForSubId(phone.getSubId());
         if (bundle != null) {
-            convertMaps = (shouldPerformInternationalNumberRemapping(phone, bundle))
-                    ? bundle.getStringArray(CarrierConfigManager
-                            .KEY_INTERNATIONAL_ROAMING_DIAL_STRING_REPLACE_STRING_ARRAY)
-                    : bundle.getStringArray(CarrierConfigManager
-                            .KEY_DIAL_STRING_REPLACE_STRING_ARRAY);
+            convertMaps =
+                    bundle.getStringArray(CarrierConfigManager.KEY_DIAL_STRING_REPLACE_STRING_ARRAY);
         }
         if (convertMaps == null) {
             // By default no replacement is necessary
@@ -237,30 +233,6 @@
 
     }
 
-    /**
-     * Helper function to determine if the phones service is in ROAMING_TYPE_INTERNATIONAL.
-     * @param phone object that contains the service state.
-     * @param bundle object that contains the bundle with mapped dial strings.
-     * @return  true if the phone is in roaming state with a set bundle. Otherwise, false.
-     */
-    private boolean shouldPerformInternationalNumberRemapping(Phone phone,
-            PersistableBundle bundle) {
-        if (phone == null || phone.getDefaultPhone() == null) {
-            log("shouldPerformInternationalNumberRemapping: phone was null");
-            return false;
-        }
-
-        if (bundle.getStringArray(CarrierConfigManager
-                .KEY_INTERNATIONAL_ROAMING_DIAL_STRING_REPLACE_STRING_ARRAY) == null) {
-            log("shouldPerformInternationalNumberRemapping: did not set the "
-                    + "KEY_INTERNATIONAL_ROAMING_DIAL_STRING_REPLACE_STRING_ARRAY");
-            return false;
-        }
-
-        return phone.getDefaultPhone().getServiceState().getVoiceRoamingType()
-                == ServiceState.ROAMING_TYPE_INTERNATIONAL;
-    }
-
     private boolean compareGid1(Phone phone, String serviceGid1) {
         String gid1 = phone.getGroupIdLevel1();
         int gid_length = serviceGid1.length();
diff --git a/src/java/com/android/internal/telephony/CarrierActionAgent.java b/src/java/com/android/internal/telephony/CarrierActionAgent.java
index 42a4f23..a87925d 100644
--- a/src/java/com/android/internal/telephony/CarrierActionAgent.java
+++ b/src/java/com/android/internal/telephony/CarrierActionAgent.java
@@ -73,9 +73,9 @@
     private RegistrantList mRadioEnableRegistrants = new RegistrantList();
     private RegistrantList mDefaultNetworkReportRegistrants = new RegistrantList();
     /** local log for carrier actions */
-    private LocalLog mMeteredApnEnabledLog = new LocalLog(8);
-    private LocalLog mRadioEnabledLog = new LocalLog(8);
-    private LocalLog mReportDefaultNetworkStatusLog = new LocalLog(8);
+    private LocalLog mMeteredApnEnabledLog = new LocalLog(10);
+    private LocalLog mRadioEnabledLog = new LocalLog(10);
+    private LocalLog mReportDefaultNetworkStatusLog = new LocalLog(10);
     /** carrier actions */
     private Boolean mCarrierActionOnMeteredApnEnabled = true;
     private Boolean mCarrierActionOnRadioEnabled = true;
diff --git a/src/java/com/android/internal/telephony/CarrierInfoManager.java b/src/java/com/android/internal/telephony/CarrierInfoManager.java
index 3e2baa5..00f8c39 100644
--- a/src/java/com/android/internal/telephony/CarrierInfoManager.java
+++ b/src/java/com/android/internal/telephony/CarrierInfoManager.java
@@ -69,7 +69,6 @@
     public static ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType,
                                                                      Context context,
                                                                      String operatorNumeric,
-                                                                     int carrierId,
                                                                      boolean fallback,
                                                                      int subId) {
         String mcc = "";
@@ -89,8 +88,7 @@
             ContentResolver mContentResolver = context.getContentResolver();
             String[] columns = {Telephony.CarrierColumns.PUBLIC_KEY,
                     Telephony.CarrierColumns.EXPIRATION_TIME,
-                    Telephony.CarrierColumns.KEY_IDENTIFIER,
-                    Telephony.CarrierColumns.CARRIER_ID};
+                    Telephony.CarrierColumns.KEY_IDENTIFIER};
             findCursor = mContentResolver.query(Telephony.CarrierColumns.CONTENT_URI, columns,
                     "mcc=? and mnc=? and key_type=?",
                     new String[]{mcc, mnc, String.valueOf(keyType)}, null);
@@ -143,29 +141,16 @@
                 Pair<PublicKey, Long> keyInfo =
                         CarrierKeyDownloadManager.getKeyInformation(keyString.getBytes());
                 return new ImsiEncryptionInfo(mcc, mnc, keyType, keyId,
-                        keyInfo.first, new Date(keyInfo.second), carrierId);
+                        keyInfo.first, new Date(keyInfo.second));
             }
             if (findCursor.getCount() > 1) {
                 Log.e(LOG_TAG, "More than 1 row found for the keyType: " + keyType);
-                // Lookup for the carrier_id
-                String carrierIdStr = "";
-                while (findCursor.moveToNext()) {
-                    carrierIdStr = findCursor.getString(3);
-                    int cursorCarrierId = (TextUtils.isEmpty(carrierIdStr))
-                            ? TelephonyManager.UNKNOWN_CARRIER_ID : Integer.parseInt(
-                            carrierIdStr);
-                    if (cursorCarrierId != TelephonyManager.UNKNOWN_CARRIER_ID
-                            && cursorCarrierId == carrierId) {
-                        return getImsiEncryptionInfo(findCursor, mcc, mnc, keyType,
-                                cursorCarrierId);
-                    }
-                }
-                findCursor.moveToFirst();
             }
-            String carrierIdStr = findCursor.getString(3);
-            int cursorCarrierId = (TextUtils.isEmpty(carrierIdStr))
-                    ? TelephonyManager.UNKNOWN_CARRIER_ID : Integer.parseInt(carrierIdStr);
-            return getImsiEncryptionInfo(findCursor, mcc, mnc, keyType, cursorCarrierId);
+            byte[] carrier_key = findCursor.getBlob(0);
+            Date expirationTime = new Date(findCursor.getLong(1));
+            String keyIdentifier = findCursor.getString(2);
+            return new ImsiEncryptionInfo(mcc, mnc, keyType, keyIdentifier, carrier_key,
+                    expirationTime);
         } catch (IllegalArgumentException e) {
             Log.e(LOG_TAG, "Bad arguments:" + e);
         } catch (Exception e) {
@@ -178,22 +163,6 @@
         return null;
     }
 
-    private static ImsiEncryptionInfo getImsiEncryptionInfo(Cursor findCursor, String mcc,
-            String mnc, int keyType, int carrierId) {
-        byte[] carrier_key = findCursor.getBlob(0);
-        Date expirationTime = new Date(findCursor.getLong(1));
-        String keyIdentifier = findCursor.getString(2);
-        ImsiEncryptionInfo imsiEncryptionInfo = null;
-        try {
-            imsiEncryptionInfo = new ImsiEncryptionInfo(mcc, mnc,
-                    keyType, keyIdentifier, carrier_key,
-                    expirationTime, carrierId);
-        } catch (Exception exp) {
-            Log.e(LOG_TAG, "Exception = " + exp.getMessage());
-        }
-        return imsiEncryptionInfo;
-    }
-
     /**
      * Inserts or update the Carrier Key in the database
      * @param imsiEncryptionInfo ImsiEncryptionInfo object.
@@ -209,7 +178,6 @@
         ContentValues contentValues = new ContentValues();
         contentValues.put(Telephony.CarrierColumns.MCC, imsiEncryptionInfo.getMcc());
         contentValues.put(Telephony.CarrierColumns.MNC, imsiEncryptionInfo.getMnc());
-        contentValues.put(Telephony.CarrierColumns.CARRIER_ID, imsiEncryptionInfo.getCarrierId());
         contentValues.put(Telephony.CarrierColumns.KEY_TYPE,
                 imsiEncryptionInfo.getKeyType());
         contentValues.put(Telephony.CarrierColumns.KEY_IDENTIFIER,
@@ -232,11 +200,10 @@
             try {
                 int nRows = mContentResolver.update(Telephony.CarrierColumns.CONTENT_URI,
                         updatedValues,
-                        "mcc=? and mnc=? and key_type=? and carrier_id=?", new String[]{
+                        "mcc=? and mnc=? and key_type=?", new String[]{
                                 imsiEncryptionInfo.getMcc(),
                                 imsiEncryptionInfo.getMnc(),
-                                String.valueOf(imsiEncryptionInfo.getKeyType()),
-                                String.valueOf(imsiEncryptionInfo.getCarrierId())});
+                                String.valueOf(imsiEncryptionInfo.getKeyType())});
                 if (nRows == 0) {
                     Log.d(LOG_TAG, "Error updating values:" + imsiEncryptionInfo);
                     downloadSuccessfull = false;
@@ -293,10 +260,7 @@
             Log.e(LOG_TAG, "Could not reset carrier keys, subscription for mPhoneId=" + mPhoneId);
             return;
         }
-        final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
-                .createForSubscriptionId(subIds[0]);
-        int carrierId = telephonyManager.getSimCarrierId();
-        deleteCarrierInfoForImsiEncryption(context, subIds[0], carrierId);
+        deleteCarrierInfoForImsiEncryption(context, subIds[0]);
         Intent resetIntent = new Intent(TelephonyIntents.ACTION_CARRIER_CERTIFICATE_DOWNLOAD);
         SubscriptionManager.putPhoneIdAndSubIdExtra(resetIntent, mPhoneId);
         context.sendBroadcastAsUser(resetIntent, UserHandle.ALL);
@@ -305,16 +269,11 @@
     /**
      * Deletes all the keys for a given Carrier from the device keystore.
      * @param context Context
-     * @param subId
-     * @param carrierId delete the key which matches the carrierId
-     *
      */
-    public static void deleteCarrierInfoForImsiEncryption(Context context, int subId,
-            int carrierId) {
+    public static void deleteCarrierInfoForImsiEncryption(Context context, int subId) {
         Log.i(LOG_TAG, "deleting carrier key from db for subId=" + subId);
         String mcc = "";
         String mnc = "";
-
         final TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class)
                 .createForSubscriptionId(subId);
         String simOperator = telephonyManager.getSimOperator();
@@ -325,15 +284,11 @@
             Log.e(LOG_TAG, "Invalid networkOperator: " + simOperator);
             return;
         }
-        String carriedIdStr = String.valueOf(carrierId);
         ContentResolver mContentResolver = context.getContentResolver();
         try {
-            String whereClause = "mcc=? and mnc=? and carrier_id=?";
-            String[] whereArgs = new String[] { mcc, mnc, carriedIdStr };
-            int count = mContentResolver.delete(Telephony.CarrierColumns.CONTENT_URI, whereClause,
-                    whereArgs);
-            Log.i(LOG_TAG, "Deleting the number of entries = " + count + "   for carrierId = "
-                    + carriedIdStr);
+            String whereClause = "mcc=? and mnc=?";
+            String[] whereArgs = new String[] { mcc, mnc };
+            mContentResolver.delete(Telephony.CarrierColumns.CONTENT_URI, whereClause, whereArgs);
         } catch (Exception e) {
             Log.e(LOG_TAG, "Delete failed" + e);
         }
diff --git a/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java b/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java
index edf3d5f..757530e 100644
--- a/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java
+++ b/src/java/com/android/internal/telephony/CarrierKeyDownloadManager.java
@@ -32,7 +32,6 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.PersistableBundle;
-import android.provider.Telephony;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ImsiEncryptionInfo;
 import android.telephony.SubscriptionManager;
@@ -109,12 +108,9 @@
     public final DownloadManager mDownloadManager;
     private String mURL;
     private boolean mAllowedOverMeteredNetwork = false;
-    private boolean mDeleteOldKeyAfterDownload = false;
-    private TelephonyManager mTelephonyManager;
 
     @VisibleForTesting
     public String mMccMncForDownload;
-    public int mCarrierId;
     @VisibleForTesting
     public long mDownloadId;
 
@@ -127,8 +123,6 @@
         filter.addAction(TelephonyIntents.ACTION_CARRIER_CERTIFICATE_DOWNLOAD);
         mContext.registerReceiver(mBroadcastReceiver, filter, null, phone);
         mDownloadManager = (DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
-        mTelephonyManager = mContext.getSystemService(TelephonyManager.class)
-                .createForSubscriptionId(mPhone.getSubId());
     }
 
     private final BroadcastReceiver mDownloadReceiver = new BroadcastReceiver() {
@@ -180,9 +174,8 @@
             case EVENT_DOWNLOAD_COMPLETE:
                 long carrierKeyDownloadIdentifier = (long) msg.obj;
                 String currentMccMnc = getSimOperator();
-                int carrierId = getSimCarrierId();
-                if (isValidDownload(currentMccMnc, carrierKeyDownloadIdentifier, carrierId)) {
-                    onDownloadComplete(carrierKeyDownloadIdentifier, currentMccMnc, carrierId);
+                if (isValidDownload(currentMccMnc, carrierKeyDownloadIdentifier)) {
+                    onDownloadComplete(carrierKeyDownloadIdentifier, currentMccMnc);
                     onPostDownloadProcessing(carrierKeyDownloadIdentifier);
                 }
                 break;
@@ -213,7 +206,7 @@
         } else {
             // delete any existing alarms.
             cleanupRenewalAlarms();
-            mPhone.deleteCarrierInfoForImsiEncryption(getSimCarrierId());
+            mPhone.deleteCarrierInfoForImsiEncryption();
         }
     }
 
@@ -221,7 +214,7 @@
         Log.d(LOG_TAG, "Cleaning up download info");
         mDownloadId = -1;
         mMccMncForDownload = null;
-        mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+
     }
 
     private void cleanupRenewalAlarms() {
@@ -302,15 +295,9 @@
      **/
     @VisibleForTesting
     public String getSimOperator() {
-        return mTelephonyManager.getSimOperator(mPhone.getSubId());
-    }
-
-    /**
-     * Returns the sim operator.
-     **/
-    @VisibleForTesting
-    public int getSimCarrierId() {
-        return mTelephonyManager.getSimCarrierId();
+        final TelephonyManager telephonyManager =
+                (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
+        return telephonyManager.getSimOperator(mPhone.getSubId());
     }
 
     /**
@@ -319,7 +306,7 @@
      *  instance of the phone.
      **/
     @VisibleForTesting
-    public boolean isValidDownload(String currentMccMnc, long currentDownloadId, int carrierId) {
+    public boolean isValidDownload(String currentMccMnc, long currentDownloadId) {
         if (currentDownloadId != mDownloadId) {
             Log.e(LOG_TAG, "download ID=" + currentDownloadId
                     + " for completed download does not match stored id=" + mDownloadId);
@@ -327,23 +314,19 @@
         }
 
         if (TextUtils.isEmpty(currentMccMnc) || TextUtils.isEmpty(mMccMncForDownload)
-                || !TextUtils.equals(currentMccMnc, mMccMncForDownload)
-                || mCarrierId != carrierId) {
-            Log.e(LOG_TAG, "currentMccMnc=" + currentMccMnc + " storedMccMnc =" + mMccMncForDownload
-                    + "currentCarrierId = " + carrierId + "  storedCarrierId = " + mCarrierId);
+                || !TextUtils.equals(currentMccMnc, mMccMncForDownload)) {
+            Log.e(LOG_TAG, "currentMccMnc=" + currentMccMnc + " stored=" + mMccMncForDownload);
             return false;
         }
 
-        Log.d(LOG_TAG, "Matched MccMnc =  " + currentMccMnc + ", carrierId = " + carrierId
-                + ", downloadId: " + currentDownloadId);
+        Log.d(LOG_TAG, "Matched MccMnc, downloadId: " + currentMccMnc + "," + currentDownloadId);
         return true;
     }
 
     /**
      * This method will try to parse the downloaded information, and persist it in the database.
      **/
-    private void onDownloadComplete(long carrierKeyDownloadIdentifier, String mccMnc,
-            int carrierId) {
+    private void onDownloadComplete(long carrierKeyDownloadIdentifier, String mccMnc) {
         Log.d(LOG_TAG, "onDownloadComplete: " + carrierKeyDownloadIdentifier);
         String jsonStr;
         DownloadManager.Query query = new DownloadManager.Query();
@@ -363,7 +346,7 @@
                         jsonStr = convertToStringNoGZip(mDownloadManager,
                                 carrierKeyDownloadIdentifier);
                     }
-                    parseJsonAndPersistKey(jsonStr, mccMnc, carrierId);
+                    parseJsonAndPersistKey(jsonStr, mccMnc);
                 } catch (Exception e) {
                     Log.e(LOG_TAG, "Error in download:" + carrierKeyDownloadIdentifier
                             + ". " + e);
@@ -465,10 +448,9 @@
      * @param mccMnc contains the mcc, mnc.
      */
     @VisibleForTesting
-    public void parseJsonAndPersistKey(String jsonStr, String mccMnc, int carrierId) {
-        if (TextUtils.isEmpty(jsonStr) || TextUtils.isEmpty(mccMnc)
-                || carrierId == TelephonyManager.UNKNOWN_CARRIER_ID) {
-            Log.e(LOG_TAG, "jsonStr or mcc, mnc: is empty or carrierId is UNKNOWN_CARRIER_ID");
+    public void parseJsonAndPersistKey(String jsonStr, String mccMnc) {
+        if (TextUtils.isEmpty(jsonStr) || TextUtils.isEmpty(mccMnc)) {
+            Log.e(LOG_TAG, "jsonStr or mcc, mnc: is empty");
             return;
         }
         try {
@@ -499,11 +481,7 @@
                 String identifier = key.getString(JSON_IDENTIFIER);
                 Pair<PublicKey, Long> keyInfo =
                         getKeyInformation(cleanCertString(cert).getBytes());
-                if (mDeleteOldKeyAfterDownload) {
-                    mPhone.deleteCarrierInfoForImsiEncryption(TelephonyManager.UNKNOWN_CARRIER_ID);
-                    mDeleteOldKeyAfterDownload = false;
-                }
-                savePublicKey(keyInfo.first, type, identifier, keyInfo.second, mcc, mnc, carrierId);
+                savePublicKey(keyInfo.first, type, identifier, keyInfo.second, mcc, mnc);
             }
         } catch (final JSONException e) {
             Log.e(LOG_TAG, "Json parsing error: " + e.getMessage());
@@ -550,10 +528,6 @@
             if (imsiEncryptionInfo == null) {
                 Log.d(LOG_TAG, "Key not found for: " + key_type);
                 return true;
-            } else if (imsiEncryptionInfo.getCarrierId() == TelephonyManager.UNKNOWN_CARRIER_ID) {
-                Log.d(LOG_TAG, "carrier key is unknown carrier, so prefer to reDownload");
-                mDeleteOldKeyAfterDownload = true;
-                return true;
             }
             Date imsiDate = imsiEncryptionInfo.getExpirationTime();
             long timeToExpire = imsiDate.getTime() - System.currentTimeMillis();
@@ -565,19 +539,17 @@
     private boolean downloadKey() {
         Log.d(LOG_TAG, "starting download from: " + mURL);
         String mccMnc = getSimOperator();
-        int carrierId = getSimCarrierId();
-        if (!TextUtils.isEmpty(mccMnc) || carrierId != TelephonyManager.UNKNOWN_CARRIER_ID) {
-            Log.d(LOG_TAG, "downloading key for mccmnc : " + mccMnc + ", carrierId : "
-                    + carrierId);
+
+        if (!TextUtils.isEmpty(mccMnc)) {
+            Log.d(LOG_TAG, "downloading key for mccmnc: " + mccMnc);
         } else {
-            Log.e(LOG_TAG, "mccmnc or carrierId is UnKnown");
+            Log.e(LOG_TAG, "mccmnc: is empty");
             return false;
         }
         try {
             // register the broadcast receiver to listen for download complete
             IntentFilter filter = new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
-            mContext.registerReceiver(mDownloadReceiver, filter, null, mPhone,
-                    Context.RECEIVER_EXPORTED);
+            mContext.registerReceiver(mDownloadReceiver, filter, null, mPhone);
 
             DownloadManager.Request request = new DownloadManager.Request(Uri.parse(mURL));
 
@@ -588,10 +560,9 @@
             request.addRequestHeader("Accept-Encoding", "gzip");
             Long carrierKeyDownloadRequestId = mDownloadManager.enqueue(request);
 
-            Log.d(LOG_TAG, "saving values mccmnc: " + mccMnc + ", downloadId: "
-                    + carrierKeyDownloadRequestId + ", carrierId: " + carrierId);
+            Log.d(LOG_TAG, "saving values mccmnc, downloadId: " + mccMnc
+                    + ", " + carrierKeyDownloadRequestId);
             mMccMncForDownload = mccMnc;
-            mCarrierId = carrierId;
             mDownloadId = carrierKeyDownloadRequestId;
         } catch (Exception e) {
             Log.e(LOG_TAG, "exception trying to download key from url: " + mURL);
@@ -626,9 +597,9 @@
      **/
     @VisibleForTesting
     public void savePublicKey(PublicKey publicKey, int type, String identifier, long expirationDate,
-            String mcc, String mnc, int carrierId) {
-        ImsiEncryptionInfo imsiEncryptionInfo = new ImsiEncryptionInfo(mcc, mnc,
-                type, identifier, publicKey, new Date(expirationDate), carrierId);
+                               String mcc, String mnc) {
+        ImsiEncryptionInfo imsiEncryptionInfo = new ImsiEncryptionInfo(mcc, mnc, type, identifier,
+                publicKey, new Date(expirationDate));
         mPhone.setCarrierInfoForImsiEncryption(imsiEncryptionInfo);
     }
 
diff --git a/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java b/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
index 3144229..8709047 100644
--- a/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
+++ b/src/java/com/android/internal/telephony/CarrierPrivilegesTracker.java
@@ -21,22 +21,13 @@
 import static android.telephony.CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY;
 import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
-import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
-import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
 import static android.telephony.TelephonyManager.EXTRA_SIM_STATE;
 import static android.telephony.TelephonyManager.SIM_STATE_ABSENT;
 import static android.telephony.TelephonyManager.SIM_STATE_LOADED;
 import static android.telephony.TelephonyManager.SIM_STATE_NOT_READY;
-import static android.telephony.TelephonyManager.SIM_STATE_READY;
 import static android.telephony.TelephonyManager.SIM_STATE_UNKNOWN;
 
-import static com.android.internal.telephony.SubscriptionInfoUpdater.simStateString;
-
-import android.annotation.ElapsedRealtimeLong;
 import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.ActivityManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -44,7 +35,6 @@
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ResolveInfo;
 import android.content.pm.Signature;
 import android.content.pm.UserInfo;
 import android.net.Uri;
@@ -53,29 +43,22 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.PersistableBundle;
-import android.os.Process;
 import android.os.Registrant;
 import android.os.RegistrantList;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.service.carrier.CarrierService;
-import android.telephony.Annotation.CarrierPrivilegeStatus;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
-import android.telephony.TelephonyRegistryManager;
 import android.telephony.UiccAccessRule;
 import android.text.TextUtils;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.IntArray;
 import android.util.LocalLog;
-import android.util.Pair;
 
-import com.android.internal.annotations.GuardedBy;
 import com.android.internal.telephony.uicc.IccUtils;
-import com.android.internal.telephony.uicc.UiccPort;
+import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccProfile;
 import com.android.telephony.Rlog;
 
@@ -83,17 +66,11 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
 import java.util.Set;
 import java.util.StringJoiner;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-import java.util.function.Function;
 
 /**
  * CarrierPrivilegesTracker will track the Carrier Privileges for a specific {@link Phone}.
@@ -108,26 +85,6 @@
     private static final String SHA_1 = "SHA-1";
     private static final String SHA_256 = "SHA-256";
 
-    // TODO(b/232273884): Turn feature on when find solution to handle the inter-carriers switching
-    /**
-     * Time delay to clear UICC rules after UICC is gone.
-     * This introduces the grace period to retain carrier privileges when SIM is removed.
-     *
-     * This feature is off by default due to the security concern during inter-carriers switching.
-     */
-    private static final long CLEAR_UICC_RULES_DELAY_MILLIS = TimeUnit.SECONDS.toMillis(0);
-
-    /**
-     * PackageManager flags used to query installed packages.
-     * Include DISABLED_UNTIL_USED components. This facilitates cases where a carrier app
-     * is disabled by default, and some other component wants to enable it when it has
-     * gained carrier privileges (as an indication that a matching SIM has been inserted).
-     */
-    private static final int INSTALLED_PACKAGES_QUERY_FLAGS =
-            PackageManager.GET_SIGNING_CERTIFICATES
-                    | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
-                    | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS;
-
     /**
      * Action to register a Registrant with this Tracker.
      * obj: Registrant that will be notified of Carrier Privileged UID changes.
@@ -155,138 +112,45 @@
     private static final int ACTION_SIM_STATE_UPDATED = 4;
 
     /**
-     * Action for tracking when a package is installed, replaced or changed (exclude the case
-     * disabled by user) on the device.
-     * obj: String package name that was installed, replaced or changed on the device.
+     * Action for tracking when a package is installed or replaced on the device.
+     * obj: String package name that was installed or replaced on the device.
      */
-    private static final int ACTION_PACKAGE_ADDED_REPLACED_OR_CHANGED = 5;
+    private static final int ACTION_PACKAGE_ADDED_OR_REPLACED = 5;
 
     /**
-     * Action for tracking when a package is uninstalled or disabled by user on the device.
-     * obj: String package name that was installed or disabled by user on the device.
+     * Action for tracking when a package is uninstalled on the device.
+     * obj: String package name that was installed on the device.
      */
-    private static final int ACTION_PACKAGE_REMOVED_OR_DISABLED_BY_USER = 6;
+    private static final int ACTION_PACKAGE_REMOVED = 6;
 
     /**
      * Action used to initialize the state of the Tracker.
      */
     private static final int ACTION_INITIALIZE_TRACKER = 7;
 
-    /**
-     * Action to set the test override rule through {@link TelephonyManager#setCarrierTestOverride}.
-     * obj: String of the carrierPrivilegeRules from method setCarrierTestOverride.
-     */
-    private static final int ACTION_SET_TEST_OVERRIDE_RULE = 8;
-
-    /**
-     * Action to clear UICC rules.
-     */
-    private static final int ACTION_CLEAR_UICC_RULES = 9;
-
-    /**
-     * Action to handle the case when UiccAccessRules has been loaded.
-     */
-    private static final int ACTION_UICC_ACCESS_RULES_LOADED = 10;
-
     private final Context mContext;
     private final Phone mPhone;
+    private final CarrierConfigManager mCarrierConfigManager;
     private final PackageManager mPackageManager;
     private final UserManager mUserManager;
-    private final CarrierConfigManager mCarrierConfigManager;
     private final TelephonyManager mTelephonyManager;
-    private final TelephonyRegistryManager mTelephonyRegistryManager;
+    private final RegistrantList mRegistrantList;
+    private final LocalLog mLocalLog;
 
-    @NonNull private final LocalLog mLocalLog = new LocalLog(64);
-    @NonNull private final RegistrantList mRegistrantList = new RegistrantList();
     // Stores rules for Carrier Config-loaded rules
-    @NonNull private final List<UiccAccessRule> mCarrierConfigRules = new ArrayList<>();
+    private final List<UiccAccessRule> mCarrierConfigRules;
+
     // Stores rules for SIM-loaded rules.
-    @NonNull private final List<UiccAccessRule> mUiccRules = new ArrayList<>();
-    // Stores rule from test override (through TelephonyManager#setCarrierTestOverride).
-    // - Null list indicates no test override (CC and UICC rules are respected)
-    // - Empty list indicates test override to simulate no rules (CC and UICC rules are ignored)
-    // - Non-empty list indicates test override with specific rules (CC and UICC rules are ignored)
-    @Nullable private List<UiccAccessRule> mTestOverrideRules = null;
+    private final List<UiccAccessRule> mUiccRules;
+
     // Map of PackageName -> Certificate hashes for that Package
-    @NonNull private final Map<String, Set<String>> mInstalledPackageCerts = new ArrayMap<>();
+    private final Map<String, Set<String>> mInstalledPackageCerts;
+
     // Map of PackageName -> UIDs for that Package
-    @NonNull private final Map<String, Set<Integer>> mCachedUids = new ArrayMap<>();
+    private final Map<String, Set<Integer>> mCachedUids;
 
-    // This should be used to guard critical section either with
-    // mPrivilegedPackageInfoLock.readLock() or mPrivilegedPackageInfoLock.writeLock(), but never
-    // with the mPrivilegedPackageInfoLock object itself.
-    @NonNull private final ReadWriteLock mPrivilegedPackageInfoLock = new ReentrantReadWriteLock();
-    // Package names and UIDs of apps that currently hold carrier privileges.
-    @GuardedBy(anyOf = {"mPrivilegedPackageInfoLock.readLock()",
-            "mPrivilegedPackageInfoLock.writeLock()"})
-    @NonNull private PrivilegedPackageInfo mPrivilegedPackageInfo = new PrivilegedPackageInfo();
-
-    // Uptime in millis on when the NEXT clear-up of UiccRules are scheduled
-    @ElapsedRealtimeLong
-    private long mClearUiccRulesUptimeMillis = CLEAR_UICC_RULE_NOT_SCHEDULED;
-    // Constant indicates no schedule to clear UiccRules
-    private static final long CLEAR_UICC_RULE_NOT_SCHEDULED = -1;
-
-    // Indicates SIM has reached SIM_STATE_READY but not SIM_STATE_LOADED yet. During this transient
-    // state, all the information previously loaded from SIM may be updated soon later and thus
-    // unreliable. For security's concern, any carrier privileges check should return
-    // CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED (instead of neither HAS_ACCESS nor NO_ACCESS) until
-    // SIM becomes LOADED again, or grace period specified by CLEAR_UICC_RULES_DELAY_MILLIS expires.
-    @GuardedBy(anyOf = {"mPrivilegedPackageInfoLock.readLock()",
-            "mPrivilegedPackageInfoLock.writeLock()"})
-    private boolean mSimIsReadyButNotLoaded = false;
-
-    /** Small snapshot to hold package names and UIDs of privileged packages. */
-    private static final class PrivilegedPackageInfo {
-        @NonNull final Set<String> mPackageNames;
-        @NonNull final Set<Integer> mUids;
-        // The carrier service (packageName, UID) pair
-        @NonNull final Pair<String, Integer> mCarrierService;
-
-        PrivilegedPackageInfo() {
-            mPackageNames = Collections.emptySet();
-            mUids = Collections.emptySet();
-            mCarrierService = new Pair<>(null, Process.INVALID_UID);
-        }
-
-        PrivilegedPackageInfo(@NonNull Set<String> packageNames, @NonNull Set<Integer> uids,
-                @NonNull Pair<String, Integer> carrierService) {
-            mPackageNames = packageNames;
-            mUids = uids;
-            mCarrierService = carrierService;
-        }
-
-        @Override
-        public String toString() {
-            return "{packageNames="
-                    + getObfuscatedPackages(mPackageNames, pkg -> Rlog.pii(TAG, pkg))
-                    + ", uids="
-                    + mUids
-                    + ", carrierServicePackageName="
-                    + Rlog.pii(TAG, mCarrierService.first)
-                    + ", carrierServiceUid="
-                    + mCarrierService.second
-                    + "}";
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) {
-                return true;
-            }
-            if (!(o instanceof PrivilegedPackageInfo)) {
-                return false;
-            }
-            PrivilegedPackageInfo other = (PrivilegedPackageInfo) o;
-            return mPackageNames.equals(other.mPackageNames) && mUids.equals(other.mUids)
-                    && mCarrierService.equals(other.mCarrierService);
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mPackageNames, mUids, mCarrierService);
-        }
-    }
+    // Privileged UIDs must be kept in sorted order for update-checks.
+    private int[] mPrivilegedUids;
 
     private final BroadcastReceiver mIntentReceiver =
             new BroadcastReceiver() {
@@ -318,18 +182,18 @@
 
                             if (simState != SIM_STATE_ABSENT
                                     && simState != SIM_STATE_NOT_READY
-                                    && simState != SIM_STATE_READY
-                                    && simState != SIM_STATE_LOADED) {
-                                return;
-                            }
+                                    && simState != SIM_STATE_LOADED) return;
 
                             sendMessage(obtainMessage(ACTION_SIM_STATE_UPDATED, slotId, simState));
                             break;
                         }
                         case Intent.ACTION_PACKAGE_ADDED: // fall through
                         case Intent.ACTION_PACKAGE_REPLACED: // fall through
-                        case Intent.ACTION_PACKAGE_REMOVED: // fall through
-                        case Intent.ACTION_PACKAGE_CHANGED: {
+                        case Intent.ACTION_PACKAGE_REMOVED: {
+                            int what =
+                                    (action.equals(Intent.ACTION_PACKAGE_REMOVED))
+                                            ? ACTION_PACKAGE_REMOVED
+                                            : ACTION_PACKAGE_ADDED_OR_REPLACED;
                             Uri uri = intent.getData();
                             String pkgName = (uri != null) ? uri.getSchemeSpecificPart() : null;
                             if (TextUtils.isEmpty(pkgName)) {
@@ -337,24 +201,6 @@
                                 return;
                             }
 
-                            boolean removed = action.equals(Intent.ACTION_PACKAGE_REMOVED);
-                            boolean disabledByUser = false;
-                            boolean notExist = false;
-                            try {
-                                disabledByUser = action.equals(Intent.ACTION_PACKAGE_CHANGED)
-                                        && mPackageManager.getApplicationEnabledSetting(pkgName)
-                                        == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
-                            } catch (IllegalArgumentException iae) {
-                                // Very rare case when package changed race with package removed
-                                Rlog.w(TAG, "Package does not exist: " + pkgName);
-                                notExist = true;
-                            }
-                            // When a package is explicitly disabled by the user or does not exist,
-                            // treat them as if it was removed: clear it from the cache
-                            int what = (removed || disabledByUser || notExist)
-                                    ? ACTION_PACKAGE_REMOVED_OR_DISABLED_BY_USER
-                                    : ACTION_PACKAGE_ADDED_REPLACED_OR_CHANGED;
-
                             sendMessage(obtainMessage(what, pkgName));
                             break;
                         }
@@ -366,15 +212,13 @@
             @NonNull Looper looper, @NonNull Phone phone, @NonNull Context context) {
         super(looper);
         mContext = context;
-        mPhone = phone;
-        mPackageManager = mContext.getPackageManager();
-        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         mCarrierConfigManager =
                 (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        mPackageManager = mContext.getPackageManager();
+        mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
-        mTelephonyRegistryManager =
-                (TelephonyRegistryManager)
-                        mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
+        mPhone = phone;
+        mLocalLog = new LocalLog(100);
 
         IntentFilter certFilter = new IntentFilter();
         certFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
@@ -386,13 +230,19 @@
         packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
         packageFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
         packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-        packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
 
         // For package-related broadcasts, specify the data scheme for "package" to receive the
         // package name along with the broadcast
         packageFilter.addDataScheme("package");
         mContext.registerReceiver(mIntentReceiver, packageFilter);
 
+        mRegistrantList = new RegistrantList();
+        mCarrierConfigRules = new ArrayList<>();
+        mUiccRules = new ArrayList<>();
+        mInstalledPackageCerts = new ArrayMap<>();
+        mCachedUids = new ArrayMap<>();
+        mPrivilegedUids = new int[0];
+
         sendMessage(obtainMessage(ACTION_INITIALIZE_TRACKER));
     }
 
@@ -417,33 +267,20 @@
                 handleSimStateChanged(msg.arg1, msg.arg2);
                 break;
             }
-            case ACTION_PACKAGE_ADDED_REPLACED_OR_CHANGED: {
+            case ACTION_PACKAGE_ADDED_OR_REPLACED: {
                 String pkgName = (String) msg.obj;
-                handlePackageAddedReplacedOrChanged(pkgName);
+                handlePackageAddedOrReplaced(pkgName);
                 break;
             }
-            case ACTION_PACKAGE_REMOVED_OR_DISABLED_BY_USER: {
+            case ACTION_PACKAGE_REMOVED: {
                 String pkgName = (String) msg.obj;
-                handlePackageRemovedOrDisabledByUser(pkgName);
+                handlePackageRemoved(pkgName);
                 break;
             }
             case ACTION_INITIALIZE_TRACKER: {
                 handleInitializeTracker();
                 break;
             }
-            case ACTION_SET_TEST_OVERRIDE_RULE: {
-                String carrierPrivilegeRules = (String) msg.obj;
-                handleSetTestOverrideRules(carrierPrivilegeRules);
-                break;
-            }
-            case ACTION_CLEAR_UICC_RULES: {
-                handleClearUiccRules();
-                break;
-            }
-            case ACTION_UICC_ACCESS_RULES_LOADED: {
-                handleUiccAccessRulesLoaded();
-                break;
-            }
             default: {
                 Rlog.e(TAG, "Received unknown msg type: " + msg.what);
                 break;
@@ -451,20 +288,12 @@
         }
     }
 
-    private void handleRegisterListener(@NonNull Registrant registrant) {
+    private void handleRegisterListener(Registrant registrant) {
         mRegistrantList.add(registrant);
-        mPrivilegedPackageInfoLock.readLock().lock();
-        try {
-            // Old registrant callback still takes int[] as parameter, need conversion here
-            int[] uids = intSetToArray(mPrivilegedPackageInfo.mUids);
-            registrant.notifyResult(
-                    Arrays.copyOf(uids, uids.length));
-        } finally {
-            mPrivilegedPackageInfoLock.readLock().unlock();
-        }
+        registrant.notifyResult(mPrivilegedUids);
     }
 
-    private void handleUnregisterListener(@NonNull Handler handler) {
+    private void handleUnregisterListener(Handler handler) {
         mRegistrantList.remove(handler);
     }
 
@@ -487,7 +316,6 @@
         maybeUpdateRulesAndNotifyRegistrants(mCarrierConfigRules, updatedCarrierConfigRules);
     }
 
-    @NonNull
     private List<UiccAccessRule> getCarrierConfigRules(int subId) {
         PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
         if (!mCarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) {
@@ -507,70 +335,30 @@
 
         List<UiccAccessRule> updatedUiccRules = Collections.EMPTY_LIST;
 
-        mPrivilegedPackageInfoLock.writeLock().lock();
-        try {
-            mSimIsReadyButNotLoaded = simState == SIM_STATE_READY;
-        } finally {
-            mPrivilegedPackageInfoLock.writeLock().unlock();
-        }
-
         // Only include the UICC rules if the SIM is fully loaded
         if (simState == SIM_STATE_LOADED) {
-            mLocalLog.log("SIM fully loaded, handleUiccAccessRulesLoaded.");
-            handleUiccAccessRulesLoaded();
-        } else {
-            if (!mUiccRules.isEmpty()
-                    && mClearUiccRulesUptimeMillis == CLEAR_UICC_RULE_NOT_SCHEDULED) {
-                mClearUiccRulesUptimeMillis =
-                        SystemClock.uptimeMillis() + CLEAR_UICC_RULES_DELAY_MILLIS;
-                sendMessageAtTime(obtainMessage(ACTION_CLEAR_UICC_RULES),
-                        mClearUiccRulesUptimeMillis);
-                mLocalLog.log("SIM is gone, simState=" + simStateString(simState)
-                        + ". Delay " + TimeUnit.MILLISECONDS.toSeconds(
-                        CLEAR_UICC_RULES_DELAY_MILLIS) + " seconds to clear UICC rules.");
-            } else {
-                mLocalLog.log(
-                        "Ignore SIM gone event while UiccRules is empty or waiting to be emptied.");
-            }
+            updatedUiccRules = getSimRules();
         }
-    }
 
-    private void handleUiccAccessRulesLoaded() {
-        mClearUiccRulesUptimeMillis = CLEAR_UICC_RULE_NOT_SCHEDULED;
-        removeMessages(ACTION_CLEAR_UICC_RULES);
-
-        List<UiccAccessRule> updatedUiccRules = getSimRules();
-        mLocalLog.log("UiccAccessRules loaded:"
+        mLocalLog.log("SIM State Changed:"
+                + " slotId=" + slotId
+                + " simState=" + simState
                 + " updated SIM-loaded rules=" + updatedUiccRules);
         maybeUpdateRulesAndNotifyRegistrants(mUiccRules, updatedUiccRules);
     }
 
-    /** Called when UiccAccessRules has been loaded */
-    public void onUiccAccessRulesLoaded() {
-        sendEmptyMessage(ACTION_UICC_ACCESS_RULES_LOADED);
-    }
-
-    private void handleClearUiccRules() {
-        mClearUiccRulesUptimeMillis = CLEAR_UICC_RULE_NOT_SCHEDULED;
-        removeMessages(ACTION_CLEAR_UICC_RULES);
-        maybeUpdateRulesAndNotifyRegistrants(mUiccRules, Collections.EMPTY_LIST);
-    }
-
-    @NonNull
     private List<UiccAccessRule> getSimRules() {
         if (!mTelephonyManager.hasIccCard(mPhone.getPhoneId())) {
             return Collections.EMPTY_LIST;
         }
-
-        UiccPort uiccPort = mPhone.getUiccPort();
-        if (uiccPort == null) {
+        UiccCard uiccCard = mPhone.getUiccCard();
+        if (uiccCard == null) {
             Rlog.w(
                     TAG,
-                    "Null UiccPort, but hasIccCard was present for phoneId " + mPhone.getPhoneId());
+                    "Null UiccCard, but hasIccCard was true for phoneId " + mPhone.getPhoneId());
             return Collections.EMPTY_LIST;
         }
-
-        UiccProfile uiccProfile = uiccPort.getUiccProfile();
+        UiccProfile uiccProfile = uiccCard.getUiccProfile();
         if (uiccProfile == null) {
             Rlog.w(
                     TAG,
@@ -580,32 +368,25 @@
         return uiccProfile.getCarrierPrivilegeAccessRules();
     }
 
-    private void handlePackageAddedReplacedOrChanged(@Nullable String pkgName) {
-        if (pkgName == null) return;
-
+    private void handlePackageAddedOrReplaced(String pkgName) {
         PackageInfo pkg;
         try {
-            pkg = mPackageManager.getPackageInfo(pkgName, INSTALLED_PACKAGES_QUERY_FLAGS);
+            pkg = mPackageManager.getPackageInfo(pkgName, PackageManager.GET_SIGNING_CERTIFICATES);
         } catch (NameNotFoundException e) {
             Rlog.e(TAG, "Error getting installed package: " + pkgName, e);
             return;
         }
 
         updateCertsForPackage(pkg);
-        // Invalidate cache because this may be a package already on the device but getting
-        // installed for a user it wasn't installed in before, which means there will be an
-        // additional UID.
-        getUidsForPackage(pkg.packageName, /* invalidateCache= */ true);
-        if (VDBG) {
-            Rlog.d(TAG, "Package added/replaced/changed:"
-                    + " pkg=" + Rlog.pii(TAG, pkgName)
-                    + " cert hashes=" + mInstalledPackageCerts.get(pkgName));
-        }
+        mCachedUids.put(pkg.packageName, getUidsForPackage(pkg.packageName));
+        mLocalLog.log("Package added/replaced:"
+                + " pkg=" + Rlog.pii(TAG, pkgName)
+                + " cert hashes=" + mInstalledPackageCerts.get(pkgName));
 
-        maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
+        maybeUpdatePrivilegedUidsAndNotifyRegistrants();
     }
 
-    private void updateCertsForPackage(@NonNull PackageInfo pkg) {
+    private void updateCertsForPackage(PackageInfo pkg) {
         Set<String> certs = new ArraySet<>();
         List<Signature> signatures = UiccAccessRule.getSignatures(pkg);
         for (Signature signature : signatures) {
@@ -619,19 +400,16 @@
         mInstalledPackageCerts.put(pkg.packageName, certs);
     }
 
-    private void handlePackageRemovedOrDisabledByUser(@Nullable String pkgName) {
-        if (pkgName == null) return;
-
-        if (mInstalledPackageCerts.remove(pkgName) == null || mCachedUids.remove(pkgName) == null) {
-            Rlog.e(TAG, "Unknown package was uninstalled or disabled by user: " + pkgName);
+    private void handlePackageRemoved(String pkgName) {
+        if (mInstalledPackageCerts.remove(pkgName) == null) {
+            Rlog.e(TAG, "Unknown package was uninstalled: " + pkgName);
             return;
         }
+        mCachedUids.remove(pkgName);
 
-        if (VDBG) {
-            Rlog.d(TAG, "Package removed or disabled by user: pkg=" + Rlog.pii(TAG, pkgName));
-        }
+        mLocalLog.log("Package removed: pkg=" + Rlog.pii(TAG, pkgName));
 
-        maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
+        maybeUpdatePrivilegedUidsAndNotifyRegistrants();
     }
 
     private void handleInitializeTracker() {
@@ -642,170 +420,99 @@
         mUiccRules.addAll(getSimRules());
 
         // Cache all installed packages and their certs
-        refreshInstalledPackageCache();
+        int flags =
+                PackageManager.MATCH_DISABLED_COMPONENTS
+                        | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
+                        | PackageManager.GET_SIGNING_CERTIFICATES;
+        List<PackageInfo> installedPackages =
+                mPackageManager.getInstalledPackagesAsUser(
+                        flags, UserHandle.SYSTEM.getIdentifier());
+        for (PackageInfo pkg : installedPackages) {
+            updateCertsForPackage(pkg);
+        }
 
         // Okay because no registrants exist yet
-        maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
+        maybeUpdatePrivilegedUidsAndNotifyRegistrants();
 
         String msg = "Initializing state:"
                 + " CarrierConfig rules=" + mCarrierConfigRules
                 + " SIM-loaded rules=" + mUiccRules;
         if (VDBG) {
-            msg +=
-                    " installed pkgs="
-                            + getObfuscatedPackages(
-                                    mInstalledPackageCerts.entrySet(),
-                                    e -> "pkg(" + Rlog.pii(TAG, e.getKey()) + ")=" + e.getValue());
+            msg += " installed pkgs=" + getObfuscatedPackages();
         }
         mLocalLog.log(msg);
     }
 
-    private void refreshInstalledPackageCache() {
-        List<PackageInfo> installedPackages =
-                mPackageManager.getInstalledPackagesAsUser(
-                        INSTALLED_PACKAGES_QUERY_FLAGS, UserHandle.SYSTEM.getIdentifier());
-        for (PackageInfo pkg : installedPackages) {
-            updateCertsForPackage(pkg);
-            // This may be unnecessary before initialization, but invalidate the cache all the time
-            // just in case to ensure consistency.
-            getUidsForPackage(pkg.packageName, /* invalidateCache= */ true);
+    private String getObfuscatedPackages() {
+        StringJoiner obfuscatedPkgs = new StringJoiner(",", "{", "}");
+        for (Map.Entry<String, Set<String>> pkg : mInstalledPackageCerts.entrySet()) {
+            obfuscatedPkgs.add("pkg(" + Rlog.pii(TAG, pkg.getKey()) + ")=" + pkg.getValue());
         }
+        return obfuscatedPkgs.toString();
     }
 
-    @NonNull
-    private static <T> String getObfuscatedPackages(
-            @NonNull Collection<T> packageNames, @NonNull Function<T, String> obfuscator) {
-        StringJoiner obfuscated = new StringJoiner(", ", "{", "}");
-        for (T packageName : packageNames) {
-            obfuscated.add(obfuscator.apply(packageName));
-        }
-        return obfuscated.toString();
-    }
-
-    private void maybeUpdateRulesAndNotifyRegistrants(@NonNull List<UiccAccessRule> currentRules,
-            @NonNull List<UiccAccessRule> updatedRules) {
+    private void maybeUpdateRulesAndNotifyRegistrants(
+            List<UiccAccessRule> currentRules, List<UiccAccessRule> updatedRules) {
         if (currentRules.equals(updatedRules)) return;
 
         currentRules.clear();
         currentRules.addAll(updatedRules);
 
-        maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
+        maybeUpdatePrivilegedUidsAndNotifyRegistrants();
     }
 
-    private void maybeUpdatePrivilegedPackagesAndNotifyRegistrants() {
-        PrivilegedPackageInfo currentPrivilegedPackageInfo =
-                getCurrentPrivilegedPackagesForAllUsers();
+    private void maybeUpdatePrivilegedUidsAndNotifyRegistrants() {
+        int[] currentPrivilegedUids = getCurrentPrivilegedUidsForAllUsers();
 
-        boolean carrierPrivilegesPackageNamesChanged;
-        boolean carrierPrivilegesUidsChanged;
-        boolean carrierServiceChanged;
+        // Sort UIDs for the equality check
+        Arrays.sort(currentPrivilegedUids);
+        if (Arrays.equals(mPrivilegedUids, currentPrivilegedUids)) return;
 
-        mPrivilegedPackageInfoLock.readLock().lock();
-        try {
-            if (mPrivilegedPackageInfo.equals(currentPrivilegedPackageInfo)) return;
+        mPrivilegedUids = currentPrivilegedUids;
+        mRegistrantList.notifyResult(mPrivilegedUids);
 
-            mLocalLog.log("Privileged packages info changed. New state = "
-                    + currentPrivilegedPackageInfo);
-
-            carrierPrivilegesPackageNamesChanged =
-                    !currentPrivilegedPackageInfo.mPackageNames.equals(
-                            mPrivilegedPackageInfo.mPackageNames);
-            carrierPrivilegesUidsChanged =
-                    !currentPrivilegedPackageInfo.mUids.equals(mPrivilegedPackageInfo.mUids);
-            carrierServiceChanged = !currentPrivilegedPackageInfo.mCarrierService.equals(
-                    mPrivilegedPackageInfo.mCarrierService);
-        } finally {
-            mPrivilegedPackageInfoLock.readLock().unlock();
-        }
-
-        mPrivilegedPackageInfoLock.writeLock().lock();
-        try {
-            mPrivilegedPackageInfo = currentPrivilegedPackageInfo;
-        } finally {
-            mPrivilegedPackageInfoLock.writeLock().unlock();
-        }
-
-        mPrivilegedPackageInfoLock.readLock().lock();
-        try {
-            // The obsoleted callback only care about UIDs
-            if (carrierPrivilegesUidsChanged) {
-                int[] uids = intSetToArray(mPrivilegedPackageInfo.mUids);
-                mRegistrantList.notifyResult(Arrays.copyOf(uids, uids.length));
-            }
-
-            if (carrierPrivilegesPackageNamesChanged || carrierPrivilegesUidsChanged) {
-                mTelephonyRegistryManager.notifyCarrierPrivilegesChanged(
-                        mPhone.getPhoneId(),
-                        Collections.unmodifiableSet(mPrivilegedPackageInfo.mPackageNames),
-                        Collections.unmodifiableSet(mPrivilegedPackageInfo.mUids));
-            }
-
-            if (carrierServiceChanged) {
-                mTelephonyRegistryManager.notifyCarrierServiceChanged(mPhone.getPhoneId(),
-                        mPrivilegedPackageInfo.mCarrierService.first,
-                        mPrivilegedPackageInfo.mCarrierService.second);
-            }
-        } finally {
-            mPrivilegedPackageInfoLock.readLock().unlock();
-        }
-
-        // Update set of enabled carrier apps now that the privilege rules may have changed.
-        ActivityManager am = mContext.getSystemService(ActivityManager.class);
-        CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(),
-                mTelephonyManager, am.getCurrentUser(), mContext);
+        mLocalLog.log("Privileged UIDs changed. New UIDs=" + Arrays.toString(mPrivilegedUids));
     }
 
-    @NonNull
-    private PrivilegedPackageInfo getCurrentPrivilegedPackagesForAllUsers() {
-        Set<String> privilegedPackageNames = new ArraySet<>();
+    private int[] getCurrentPrivilegedUidsForAllUsers() {
         Set<Integer> privilegedUids = new ArraySet<>();
         for (Map.Entry<String, Set<String>> e : mInstalledPackageCerts.entrySet()) {
             if (isPackagePrivileged(e.getKey(), e.getValue())) {
-                privilegedPackageNames.add(e.getKey());
-                privilegedUids.addAll(getUidsForPackage(e.getKey(), /* invalidateCache= */ false));
+                privilegedUids.addAll(getUidsForPackage(e.getKey()));
             }
         }
-        return new PrivilegedPackageInfo(privilegedPackageNames, privilegedUids,
-                getCarrierService(privilegedPackageNames));
+
+        IntArray result = new IntArray(privilegedUids.size());
+        for (int uid : privilegedUids) {
+            result.add(uid);
+        }
+        return result.toArray();
     }
 
     /**
      * Returns true iff there is an overlap between the provided certificate hashes and the
-     * certificate hashes stored in mTestOverrideRules, mCarrierConfigRules and mUiccRules.
+     * certificate hashes stored in mCarrierConfigRules and mUiccRules.
      */
-    private boolean isPackagePrivileged(@NonNull String pkgName, @NonNull Set<String> certs) {
+    private boolean isPackagePrivileged(String pkgName, Set<String> certs) {
         // Double-nested for loops, but each collection should contain at most 2 elements in nearly
         // every case.
         // TODO(b/184382310) find a way to speed this up
         for (String cert : certs) {
-            // Non-null (whether empty or not) test override rule will ignore the UICC and CC rules
-            if (mTestOverrideRules != null) {
-                for (UiccAccessRule rule : mTestOverrideRules) {
-                    if (rule.matches(cert, pkgName)) {
-                        return true;
-                    }
+            for (UiccAccessRule rule : mCarrierConfigRules) {
+                if (rule.matches(cert, pkgName)) {
+                    return true;
                 }
-            } else {
-                for (UiccAccessRule rule : mCarrierConfigRules) {
-                    if (rule.matches(cert, pkgName)) {
-                        return true;
-                    }
-                }
-                for (UiccAccessRule rule : mUiccRules) {
-                    if (rule.matches(cert, pkgName)) {
-                        return true;
-                    }
+            }
+            for (UiccAccessRule rule : mUiccRules) {
+                if (rule.matches(cert, pkgName)) {
+                    return true;
                 }
             }
         }
         return false;
     }
 
-    @NonNull
-    private Set<Integer> getUidsForPackage(@NonNull String pkgName, boolean invalidateCache) {
-        if (invalidateCache) {
-            mCachedUids.remove(pkgName);
-        }
+    private Set<Integer> getUidsForPackage(String pkgName) {
         if (mCachedUids.containsKey(pkgName)) {
             return mCachedUids.get(pkgName);
         }
@@ -825,44 +532,22 @@
         return uids;
     }
 
-    private int getPackageUid(@Nullable String pkgName) {
-        int uid = Process.INVALID_UID;
-        try {
-            uid = mPackageManager.getPackageUid(pkgName, /* flags= */0);
-        } catch (NameNotFoundException e) {
-            Rlog.e(TAG, "Unable to find uid for package " + pkgName);
-        }
-        return uid;
-    }
-
     /**
      * Dump the local log buffer and other internal state of CarrierPrivilegesTracker.
      */
-    public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
-        pw.println("CarrierPrivilegesTracker - phoneId: " + mPhone.getPhoneId());
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+        pw.println("Dump of CarrierPrivilegesTracker");
         pw.println("CarrierPrivilegesTracker - Log Begin ----");
         mLocalLog.dump(fd, pw, args);
         pw.println("CarrierPrivilegesTracker - Log End ----");
-        mPrivilegedPackageInfoLock.readLock().lock();
-        try {
-            pw.println(
-                    "CarrierPrivilegesTracker - Privileged package info: "
-                            + mPrivilegedPackageInfo);
-            pw.println("mSimIsReadyButNotLoaded: " + mSimIsReadyButNotLoaded);
-        } finally {
-            mPrivilegedPackageInfoLock.readLock().unlock();
-        }
-        pw.println("CarrierPrivilegesTracker - Test-override rules: " + mTestOverrideRules);
+        pw.println("CarrierPrivilegesTracker - Privileged UIDs: "
+                + Arrays.toString(mPrivilegedUids));
         pw.println("CarrierPrivilegesTracker - SIM-loaded rules: " + mUiccRules);
         pw.println("CarrierPrivilegesTracker - Carrier config rules: " + mCarrierConfigRules);
         if (VDBG) {
-            pw.println(
-                    "CarrierPrivilegesTracker - Obfuscated Pkgs + Certs: "
-                            + getObfuscatedPackages(
-                                    mInstalledPackageCerts.entrySet(),
-                                    e -> "pkg(" + Rlog.pii(TAG, e.getKey()) + ")=" + e.getValue()));
+            pw.println("CarrierPrivilegesTracker - Obfuscated Pkgs + Certs: "
+                    + getObfuscatedPackages());
         }
-        pw.println("mClearUiccRulesUptimeMillis: " + mClearUiccRulesUptimeMillis);
     }
 
     /**
@@ -870,223 +555,15 @@
      *
      * <p>After being registered, the Registrant will be notified with the current Carrier
      * Privileged UIDs for this Phone.
-     *
-     * @deprecated Use {@link TelephonyManager#addCarrierPrivilegesListener} instead, which also
-     *     provides package names
-     *     <p>TODO(b/211658797) migrate callers, then delete all Registrant logic from CPT
      */
-    @Deprecated
-    public void registerCarrierPrivilegesListener(@NonNull Handler h, int what,
-            @Nullable Object obj) {
+    public void registerCarrierPrivilegesListener(Handler h, int what, Object obj) {
         sendMessage(obtainMessage(ACTION_REGISTER_LISTENER, new Registrant(h, what, obj)));
     }
 
     /**
      * Unregisters the given listener with this tracker.
-     *
-     * @deprecated Use {@link TelephonyManager#removeCarrierPrivilegesListener} instead
-     *     <p>TODO(b/211658797) migrate callers, then delete all Registrant logic from CPT
      */
-    @Deprecated
-    public void unregisterCarrierPrivilegesListener(@NonNull Handler handler) {
+    public void unregisterCarrierPrivilegesListener(Handler handler) {
         sendMessage(obtainMessage(ACTION_UNREGISTER_LISTENER, handler));
     }
-
-    /**
-     * Set test carrier privilege rules which will override the actual rules on both Carrier Config
-     * and SIM.
-     *
-     * <p>{@code carrierPrivilegeRules} can be null, in which case the rules on the Carrier Config
-     * and SIM will be used and any previous overrides will be cleared.
-     *
-     * @see TelephonyManager#setCarrierTestOverride
-     */
-    public void setTestOverrideCarrierPrivilegeRules(@Nullable String carrierPrivilegeRules) {
-        sendMessage(obtainMessage(ACTION_SET_TEST_OVERRIDE_RULE, carrierPrivilegeRules));
-    }
-
-    private void handleSetTestOverrideRules(@Nullable String carrierPrivilegeRules) {
-        if (carrierPrivilegeRules == null) {
-            mTestOverrideRules = null;
-        } else if (carrierPrivilegeRules.isEmpty()) {
-            mTestOverrideRules = Collections.emptyList();
-        } else {
-            mTestOverrideRules = Arrays.asList(UiccAccessRule.decodeRulesFromCarrierConfig(
-                    new String[]{carrierPrivilegeRules}));
-            // TODO(b/215239409): remove the additional cache refresh for test override cases.
-            // Test override doesn't respect if the package for the specified cert has been removed
-            // or hidden since initialization. Refresh the cache again to get the pkg/uid with the
-            // best effort.
-            refreshInstalledPackageCache();
-        }
-        maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
-    }
-
-    /** Backing of {@link TelephonyManager#checkCarrierPrivilegesForPackage}. */
-    public @CarrierPrivilegeStatus int getCarrierPrivilegeStatusForPackage(
-            @Nullable String packageName) {
-        if (packageName == null) return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
-
-        // TODO(b/205736323) consider if/how we want to account for the RULES_NOT_LOADED and
-        // ERROR_LOADING_RULES constants. Technically those will never be returned today since those
-        // results are only from the SIM rules, but the CC rules' result (which never has these
-        // errors) always supersede them unless something goes super wrong when getting CC.
-        mPrivilegedPackageInfoLock.readLock().lock();
-        try {
-            if (mSimIsReadyButNotLoaded) {
-                return CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
-            } else if (mPrivilegedPackageInfo.mPackageNames.contains(packageName)) {
-                return CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
-            } else {
-                return CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
-            }
-        } finally {
-            mPrivilegedPackageInfoLock.readLock().unlock();
-        }
-    }
-
-    /** Backing of {@link TelephonyManager#getPackagesWithCarrierPrivileges}. */
-    @NonNull
-    public Set<String> getPackagesWithCarrierPrivileges() {
-        mPrivilegedPackageInfoLock.readLock().lock();
-        try {
-            return mSimIsReadyButNotLoaded ? Collections.emptySet() :
-                    Collections.unmodifiableSet(mPrivilegedPackageInfo.mPackageNames);
-        } finally {
-            mPrivilegedPackageInfoLock.readLock().unlock();
-        }
-    }
-
-    /**
-     * Backing of {@link TelephonyManager#hasCarrierPrivileges} and {@link
-     * TelephonyManager#getCarrierPrivilegeStatus(int)}.
-     */
-    public @CarrierPrivilegeStatus int getCarrierPrivilegeStatusForUid(int uid) {
-        // TODO(b/205736323) consider if/how we want to account for the RULES_NOT_LOADED and
-        // ERROR_LOADING_RULES constants. Technically those will never be returned today since those
-        // results are only from the SIM rules, but the CC rules' result (which never has these
-        // errors) always supersede them unless something goes super wrong when getting CC.
-        mPrivilegedPackageInfoLock.readLock().lock();
-        try {
-            if (mSimIsReadyButNotLoaded) {
-                return CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
-            } else if (mPrivilegedPackageInfo.mUids.contains(uid)) {
-                return CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
-            } else {
-                return CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
-            }
-        } finally {
-            mPrivilegedPackageInfoLock.readLock().unlock();
-        }
-    }
-
-    /**
-     * Backing of {@link TelephonyManager#getCarrierServicePackageName()} and
-     * {@link TelephonyManager#getCarrierServicePackageNameForLogicalSlot(int)}
-     */
-    @Nullable
-    public String getCarrierServicePackageName() {
-        // Return the cached one if present, it is fast and safe (no IPC call to PackageManager)
-        mPrivilegedPackageInfoLock.readLock().lock();
-        try {
-            // If SIM is READY but not LOADED, neither the cache nor the queries below are reliable,
-            // we should return null for this transient state for security/privacy's concern.
-            if (mSimIsReadyButNotLoaded) return null;
-
-            return mPrivilegedPackageInfo.mCarrierService.first;
-        } finally {
-            mPrivilegedPackageInfoLock.readLock().unlock();
-        }
-        // Do NOT query package manager, mPrivilegedPackageInfo.mCarrierService has maintained the
-        // latest CarrierService info. Querying PM will not get better result.
-    }
-
-    /**
-     * @return The UID of carrier service package. {@link Process#INVALID_UID} if not found.
-     */
-    public int getCarrierServicePackageUid() {
-        mPrivilegedPackageInfoLock.readLock().lock();
-        try {
-            if (mSimIsReadyButNotLoaded) return Process.INVALID_UID;
-
-            return mPrivilegedPackageInfo.mCarrierService.second;
-        } finally {
-            mPrivilegedPackageInfoLock.readLock().unlock();
-        }
-    }
-
-    /**
-     * Backing of {@link TelephonyManager#getCarrierPackageNamesForIntent} and {@link
-     * TelephonyManager#getCarrierPackageNamesForIntentAndPhone}.
-     */
-    @NonNull
-    public List<String> getCarrierPackageNamesForIntent(@NonNull Intent intent) {
-        mPrivilegedPackageInfoLock.readLock().lock();
-        try {
-            if (mSimIsReadyButNotLoaded) return Collections.emptyList();
-        } finally {
-            mPrivilegedPackageInfoLock.readLock().unlock();
-        }
-
-        // Do the PackageManager queries before we take the lock, as these are the longest-running
-        // pieces of this method and don't depend on the set of carrier apps.
-        List<ResolveInfo> resolveInfos = new ArrayList<>();
-        resolveInfos.addAll(mPackageManager.queryBroadcastReceivers(intent, 0));
-        resolveInfos.addAll(mPackageManager.queryIntentActivities(intent, 0));
-        resolveInfos.addAll(mPackageManager.queryIntentServices(intent, 0));
-        resolveInfos.addAll(mPackageManager.queryIntentContentProviders(intent, 0));
-
-        // Now actually check which of the resolved packages have carrier privileges.
-        mPrivilegedPackageInfoLock.readLock().lock();
-        try {
-            // Check mSimIsReadyButNotLoaded again here since the PackageManager queries above are
-            // pretty time-consuming, mSimIsReadyButNotLoaded state may change since last check
-            if (mSimIsReadyButNotLoaded) return Collections.emptyList();
-
-            Set<String> packageNames = new ArraySet<>(); // For deduping purposes
-            for (ResolveInfo resolveInfo : resolveInfos) {
-                String packageName = getPackageName(resolveInfo);
-                if (packageName != null && CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
-                        == getCarrierPrivilegeStatusForPackage(packageName)) {
-                    packageNames.add(packageName);
-                }
-            }
-            return new ArrayList<>(packageNames);
-        } finally {
-            mPrivilegedPackageInfoLock.readLock().unlock();
-        }
-    }
-
-    @Nullable
-    private static String getPackageName(@NonNull ResolveInfo resolveInfo) {
-        // Note: activityInfo covers both activities + broadcast receivers
-        if (resolveInfo.activityInfo != null) return resolveInfo.activityInfo.packageName;
-        if (resolveInfo.serviceInfo != null) return resolveInfo.serviceInfo.packageName;
-        if (resolveInfo.providerInfo != null) return resolveInfo.providerInfo.packageName;
-        return null;
-    }
-
-    @NonNull
-    private Pair<String, Integer> getCarrierService(@NonNull Set<String> privilegedPackageNames) {
-        List<ResolveInfo> carrierServiceResolveInfos = mPackageManager.queryIntentServices(
-                new Intent(CarrierService.CARRIER_SERVICE_INTERFACE), /* flags= */ 0);
-        String carrierServicePackageName = null;
-        for (ResolveInfo resolveInfo : carrierServiceResolveInfos) {
-            String packageName = getPackageName(resolveInfo);
-            if (privilegedPackageNames.contains(packageName)) {
-                carrierServicePackageName = packageName;
-                break;
-            }
-        }
-        return carrierServicePackageName == null
-                ? new Pair<>(null, Process.INVALID_UID)
-                : new Pair<>(carrierServicePackageName, getPackageUid(carrierServicePackageName));
-    }
-
-    @NonNull
-    private static int[] intSetToArray(@NonNull Set<Integer> intSet) {
-        IntArray converter = new IntArray(intSet.size());
-        intSet.forEach(converter::add);
-        return converter.toArray();
-    }
 }
diff --git a/src/java/com/android/internal/telephony/CarrierResolver.java b/src/java/com/android/internal/telephony/CarrierResolver.java
index ec6a5a0..794bb41 100644
--- a/src/java/com/android/internal/telephony/CarrierResolver.java
+++ b/src/java/com/android/internal/telephony/CarrierResolver.java
@@ -27,7 +27,6 @@
 import android.database.ContentObserver;
 import android.database.Cursor;
 import android.net.Uri;
-import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
 import android.provider.Telephony;
@@ -107,7 +106,7 @@
     private Context mContext;
     private Phone mPhone;
     private IccRecords mIccRecords;
-    private final LocalLog mCarrierIdLocalLog = new LocalLog(16);
+    private final LocalLog mCarrierIdLocalLog = new LocalLog(20);
     private final TelephonyManager mTelephonyMgr;
 
     private final ContentObserver mContentObserver = new ContentObserver(this) {
@@ -165,7 +164,7 @@
                 updateCarrierIdAndName(
                     carrierId, carrierName != null ? carrierName : "",
                     specificCarrierId, specificCarrierName != null ? carrierName : "",
-                    mnoCarrierId, false);
+                    mnoCarrierId);
             }
         }
     };
@@ -216,12 +215,12 @@
                 handleSimAbsent();
                 break;
             case IccCardConstants.INTENT_VALUE_ICC_LOADED:
-                handleSimLoaded(false);
+                handleSimLoaded();
                 break;
         }
     }
 
-    private void handleSimLoaded(boolean isSimOverride) {
+    private void handleSimLoaded() {
         if (mIccRecords != null) {
             /**
              * returns empty string to be consistent with
@@ -233,9 +232,7 @@
             loge("mIccRecords is null on SIM_LOAD_EVENT, could not get SPN");
         }
         mPreferApn = getPreferApn();
-        loadCarrierMatchingRulesOnMccMnc(
-                false /* update carrier config */,
-                isSimOverride);
+        loadCarrierMatchingRulesOnMccMnc(false /* update carrier config */);
     }
 
     private void handleSimAbsent() {
@@ -244,7 +241,7 @@
         mPreferApn = null;
         updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null,
                 TelephonyManager.UNKNOWN_CARRIER_ID, null,
-                TelephonyManager.UNKNOWN_CARRIER_ID, false);
+                TelephonyManager.UNKNOWN_CARRIER_ID);
     }
 
     private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
@@ -277,24 +274,19 @@
         if (DBG) logd("handleMessage: " + msg.what);
         switch (msg.what) {
             case SIM_LOAD_EVENT:
-                AsyncResult result = (AsyncResult) msg.obj;
-                boolean isSimOverride = false;
-                if (result != null) {
-                    isSimOverride = result.userObj instanceof Boolean && (Boolean) result.userObj;
-                }
-                handleSimLoaded(isSimOverride);
+                handleSimLoaded();
                 break;
             case CARRIER_ID_DB_UPDATE_EVENT:
                 // clean the cached carrier list version, so that a new one will be queried.
                 mCarrierListVersion = null;
-                loadCarrierMatchingRulesOnMccMnc(true /* update carrier config*/, false);
+                loadCarrierMatchingRulesOnMccMnc(true /* update carrier config*/);
                 break;
             case PREFER_APN_UPDATE_EVENT:
                 String preferApn = getPreferApn();
                 if (!equals(mPreferApn, preferApn, true)) {
                     logd("[updatePreferApn] from:" + mPreferApn + " to:" + preferApn);
                     mPreferApn = preferApn;
-                    matchSubscriptionCarrier(true /* update carrier config*/, false);
+                    matchSubscriptionCarrier(true /* update carrier config*/);
                 }
                 break;
             case ICC_CHANGED_EVENT:
@@ -309,8 +301,7 @@
                     }
                     if (newIccRecords != null) {
                         logd("new Icc object");
-                        newIccRecords.registerForRecordsOverride(this, SIM_LOAD_EVENT,
-                                /* is sim override*/true);
+                        newIccRecords.registerForRecordsOverride(this, SIM_LOAD_EVENT, null);
                         mIccRecords = newIccRecords;
                     }
                 }
@@ -321,9 +312,7 @@
         }
     }
 
-    private void loadCarrierMatchingRulesOnMccMnc(
-            boolean updateCarrierConfig,
-            boolean isSimOverride) {
+    private void loadCarrierMatchingRulesOnMccMnc(boolean updateCarrierConfig) {
         try {
             String mccmnc = mTelephonyMgr.getSimOperatorNumericForPhone(mPhone.getPhoneId());
             Cursor cursor = mContext.getContentResolver().query(
@@ -341,7 +330,7 @@
                     while (cursor.moveToNext()) {
                         mCarrierMatchingRulesOnMccMnc.add(makeCarrierMatchingRule(cursor));
                     }
-                    matchSubscriptionCarrier(updateCarrierConfig, isSimOverride);
+                    matchSubscriptionCarrier(updateCarrierConfig);
 
                     // Generate metrics related to carrier ID table version.
                     CarrierIdMatchStats.sendCarrierIdTableVersion(getCarrierListVersion());
@@ -476,7 +465,7 @@
 
     private void updateCarrierIdAndName(int cid, String name,
                                         int specificCarrierId, String specificCarrierName,
-                                        int mnoCid, boolean isSimOverride) {
+                                        int mnoCid) {
         boolean update = false;
         if (specificCarrierId != mSpecificCarrierId) {
             logd("[updateSpecificCarrierId] from:" + mSpecificCarrierId + " to:"
@@ -545,7 +534,7 @@
         // during esim profile switch, there is no sim absent thus carrier id will persist and
         // might not trigger an update if switch profiles for the same carrier. thus always update
         // subscriptioninfo db to make sure we have correct carrier id set.
-        if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId()) && !isSimOverride) {
+        if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
             // only persist carrier id to simInfo db when subId is valid.
             SubscriptionController.getInstance().setCarrierId(mCarrierId, mPhone.getSubId());
         }
@@ -838,7 +827,7 @@
     /**
      * find the best matching carrier from candidates with matched subscription MCCMNC.
      */
-    private void matchSubscriptionCarrier(boolean updateCarrierConfig, boolean isSimOverride) {
+    private void matchSubscriptionCarrier(boolean updateCarrierConfig) {
         if (!SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
             logd("[matchSubscriptionCarrier]" + "skip before sim records loaded");
             return;
@@ -881,7 +870,7 @@
                     + " name: " + null);
             updateCarrierIdAndName(TelephonyManager.UNKNOWN_CARRIER_ID, null,
                     TelephonyManager.UNKNOWN_CARRIER_ID, null,
-                    TelephonyManager.UNKNOWN_CARRIER_ID, isSimOverride);
+                    TelephonyManager.UNKNOWN_CARRIER_ID);
         } else {
             // if there is a single matching result, check if this rule has parent cid assigned.
             if ((maxRule == maxRuleParent)
@@ -895,7 +884,7 @@
                     + " name: " + maxRuleParent.mName);
             updateCarrierIdAndName(maxRuleParent.mCid, maxRuleParent.mName,
                     maxRule.mCid, maxRule.mName,
-                    (mnoRule == null) ? maxRule.mCid : mnoRule.mCid, isSimOverride);
+                    (mnoRule == null) ? maxRule.mCid : mnoRule.mCid);
 
             if (updateCarrierConfig) {
                 logd("[matchSubscriptionCarrier] - Calling updateCarrierConfig()");
@@ -962,13 +951,11 @@
     public int getCarrierListVersion() {
         // Use the cached value if it exists, otherwise retrieve it.
         if (mCarrierListVersion == null) {
-            // The auto closeable cursor will be closed after exiting try-block.
-            try (Cursor cursor = mContext.getContentResolver().query(
+            final Cursor cursor = mContext.getContentResolver().query(
                     Uri.withAppendedPath(CarrierId.All.CONTENT_URI,
-                    "get_version"), null, null, null)) {
-                cursor.moveToFirst();
-                mCarrierListVersion = cursor.getInt(0);
-            }
+                    "get_version"), null, null, null);
+            cursor.moveToFirst();
+            mCarrierListVersion = cursor.getInt(0);
         }
         return mCarrierListVersion;
     }
diff --git a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
index dfa53b3..69d59af 100644
--- a/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
+++ b/src/java/com/android/internal/telephony/CarrierServiceBindHelper.java
@@ -29,7 +29,6 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.HandlerExecutor;
 import android.os.IBinder;
 import android.os.Message;
 import android.os.Process;
@@ -39,7 +38,6 @@
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
-import android.util.LocalLog;
 import android.util.Log;
 import android.util.SparseArray;
 
@@ -48,8 +46,7 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.Set;
+import java.util.List;
 
 /**
  * Manages long-lived bindings to carrier services
@@ -58,10 +55,6 @@
 public class CarrierServiceBindHelper {
     private static final String LOG_TAG = "CarrierSvcBindHelper";
 
-    // TODO(b/201423849): Remove the UNBIND_DELAY_MILLIS and switch to CarrierPrivilegesCallback
-    // The grace period has been replaced by CarrierPrivilegesTracker. CarrierPrivilegesCallback has
-    // provided the callback for both carrier privileges change and carrier service change (with
-    // awareness of the grace period), the delay based logic here should be cleaned up.
     /**
      * How long to linger a binding after an app loses carrier privileges, as long as no new
      * binding comes in to take its place.
@@ -74,16 +67,16 @@
     public SparseArray<AppBinding> mBindings = new SparseArray();
     @VisibleForTesting
     public SparseArray<String> mLastSimState = new SparseArray<>();
-    // TODO(b/201423849): Clean up PackageChangeReceiver/UserUnlockedReceiver/SIM State change if
-    // CarrierServiceChangeCallback can cover the cases
     private final PackageChangeReceiver mPackageMonitor = new CarrierServicePackageMonitor();
-    private final LocalLog mLocalLog = new LocalLog(100);
+
+    // whether we have successfully bound to the service
+    private boolean mServiceBound = false;
 
     private BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             final String action = intent.getAction();
-            logdWithLocalLog("Received " + action);
+            log("Received " + action);
 
             if (Intent.ACTION_USER_UNLOCKED.equals(action)) {
                 // On user unlock, new components might become available, so reevaluate all
@@ -95,30 +88,6 @@
         }
     };
 
-    private class CarrierServiceChangeCallback implements
-            TelephonyManager.CarrierPrivilegesCallback {
-        final int mPhoneId;
-
-        CarrierServiceChangeCallback(int phoneId) {
-            this.mPhoneId = phoneId;
-        }
-
-        @Override
-        public void onCarrierPrivilegesChanged(Set<String> privilegedPackageNames,
-                Set<Integer> privilegedUids) {
-            // Ignored, not interested here
-        }
-
-        @Override
-        public void onCarrierServiceChanged(String carrierServicePackageName,
-                int carrierServiceUid) {
-            logdWithLocalLog("onCarrierServiceChanged, carrierServicePackageName="
-                    + carrierServicePackageName + ", carrierServiceUid=" + carrierServiceUid
-                    + ", mPhoneId=" + mPhoneId);
-            mHandler.sendMessage(mHandler.obtainMessage(EVENT_REBIND, mPhoneId));
-        }
-    }
-
     private static final int EVENT_REBIND = 0;
     @VisibleForTesting
     public static final int EVENT_PERFORM_IMMEDIATE_UNBIND = 1;
@@ -132,34 +101,31 @@
         public void handleMessage(Message msg) {
             int phoneId;
             AppBinding binding;
-            logdWithLocalLog("mHandler: " + msg.what);
+            log("mHandler: " + msg.what);
 
             switch (msg.what) {
                 case EVENT_REBIND:
                     phoneId = (int) msg.obj;
                     binding = mBindings.get(phoneId);
                     if (binding == null) return;
-                    logdWithLocalLog("Rebinding if necessary for phoneId: " + binding.getPhoneId());
+                    log("Rebinding if necessary for phoneId: " + binding.getPhoneId());
                     binding.rebind();
                     break;
                 case EVENT_PERFORM_IMMEDIATE_UNBIND:
                     phoneId = (int) msg.obj;
                     binding = mBindings.get(phoneId);
                     if (binding == null) return;
-                    logdWithLocalLog("Unbind immediate with phoneId: " + binding.getPhoneId());
                     binding.performImmediateUnbind();
                     break;
                 case EVENT_MULTI_SIM_CONFIG_CHANGED:
                     updateBindingsAndSimStates();
                     break;
-                default:
-                    Log.e(LOG_TAG, "Unsupported event received: " + msg.what);
             }
         }
     };
 
     public CarrierServiceBindHelper(Context context) {
-        mContext = context.createContextAsUser(Process.myUserHandle(), 0);
+        mContext = context;
 
         updateBindingsAndSimStates();
 
@@ -175,7 +141,7 @@
                 new IntentFilter(Intent.ACTION_USER_UNLOCKED), null /* broadcastPermission */,
                 mHandler);
         } catch (PackageManager.NameNotFoundException e) {
-            logeWithLocalLog("Package name not found: " + e.getMessage());
+            loge("Package name not found: " + e.getMessage());
         }
     }
 
@@ -193,7 +159,6 @@
 
         // If prevLen > newLen, dispose AppBinding and simState objects.
         for (int phoneId = newLen; phoneId < prevLen; phoneId++) {
-            mBindings.get(phoneId).tearDown();
             mBindings.get(phoneId).unbind(true);
             mBindings.delete(phoneId);
             mLastSimState.delete(phoneId);
@@ -201,7 +166,7 @@
     }
 
     void updateForPhoneId(int phoneId, String simState) {
-        logdWithLocalLog("update binding for phoneId: " + phoneId + " simState: " + simState);
+        log("update binding for phoneId: " + phoneId + " simState: " + simState);
         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
             return;
         }
@@ -225,23 +190,9 @@
         private String carrierPackage;
         private String carrierServiceClass;
         private long mUnbindScheduledUptimeMillis = -1;
-        private final CarrierServiceChangeCallback mCarrierServiceChangeCallback;
 
         public AppBinding(int phoneId) {
             this.phoneId = phoneId;
-            this.mCarrierServiceChangeCallback = new CarrierServiceChangeCallback(phoneId);
-            TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
-            if (tm != null) {
-                tm.registerCarrierPrivilegesCallback(phoneId, new HandlerExecutor(mHandler),
-                        mCarrierServiceChangeCallback);
-            }
-        }
-
-        public void tearDown() {
-            TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
-            if (tm != null && mCarrierServiceChangeCallback != null) {
-                tm.unregisterCarrierPrivilegesCallback(mCarrierServiceChangeCallback);
-            }
         }
 
         public int getPhoneId() {
@@ -261,25 +212,28 @@
          */
         void rebind() {
             // Get the package name for the carrier app
-            String carrierPackageName = TelephonyManager.from(
-                    mContext).getCarrierServicePackageNameForLogicalSlot(phoneId);
+            List<String> carrierPackageNames =
+                TelephonyManager.from(mContext).getCarrierPackageNamesForIntentAndPhone(
+                    new Intent(CarrierService.CARRIER_SERVICE_INTERFACE), phoneId
+                );
 
-            if (carrierPackageName == null) {
-                logdWithLocalLog("No carrier app for: " + phoneId);
+            if (carrierPackageNames == null || carrierPackageNames.size() <= 0) {
+                log("No carrier app for: " + phoneId);
                 // Unbind after a delay in case this is a temporary blip in carrier privileges.
                 unbind(false /* immediate */);
                 return;
             }
 
-            logdWithLocalLog("Found carrier app: " + carrierPackageName);
+            log("Found carrier app: " + carrierPackageNames);
+            String candidateCarrierPackage = carrierPackageNames.get(0);
             // If we are binding to a different package, unbind immediately from the current one.
-            if (!TextUtils.equals(carrierPackage, carrierPackageName)) {
+            if (!TextUtils.equals(carrierPackage, candidateCarrierPackage)) {
                 unbind(true /* immediate */);
             }
 
             // Look up the carrier service
             Intent carrierService = new Intent(CarrierService.CARRIER_SERVICE_INTERFACE);
-            carrierService.setPackage(carrierPackageName);
+            carrierService.setPackage(candidateCarrierPackage);
 
             ResolveInfo carrierResolveInfo = mContext.getPackageManager().resolveService(
                 carrierService, PackageManager.GET_META_DATA);
@@ -295,28 +249,25 @@
             // Only bind if the service wants it
             if (metadata == null ||
                 !metadata.getBoolean("android.service.carrier.LONG_LIVED_BINDING", false)) {
-                logdWithLocalLog("Carrier app does not want a long lived binding");
+                log("Carrier app does not want a long lived binding");
                 unbind(true /* immediate */);
                 return;
             }
 
             if (!TextUtils.equals(carrierServiceClass, candidateServiceClass)) {
-                logdWithLocalLog("CarrierService class changed, unbind immediately.");
                 // Unbind immediately if the carrier service component has changed.
                 unbind(true /* immediate */);
             } else if (connection != null) {
-                logdWithLocalLog(
-                        "CarrierService class unchanged with connection up, cancelScheduledUnbind");
                 // Component is unchanged and connection is up - do nothing, but cancel any
                 // scheduled unbinds.
                 cancelScheduledUnbind();
                 return;
             }
 
-            carrierPackage = carrierPackageName;
+            carrierPackage = candidateCarrierPackage;
             carrierServiceClass = candidateServiceClass;
 
-            logdWithLocalLog("Binding to " + carrierPackage + " for phone " + phoneId);
+            log("Binding to " + carrierPackage + " for phone " + phoneId);
 
             // Log debug information
             bindCount++;
@@ -326,14 +277,15 @@
 
             String error;
             try {
-                if (mContext.bindService(
-                        carrierService,
-                        Context.BIND_AUTO_CREATE
+                if (mContext.createContextAsUser(Process.myUserHandle(), 0)
+                        .bindService(carrierService,
+                                Context.BIND_AUTO_CREATE
                                 | Context.BIND_FOREGROUND_SERVICE
                                 | Context.BIND_INCLUDE_CAPABILITIES,
-                        (r) -> mHandler.post(r),
-                        connection)) {
-                    logdWithLocalLog("service bound");
+                                (r) -> mHandler.post(r),
+                                connection)) {
+                    log("service bound");
+                    mServiceBound = true;
                     return;
                 }
 
@@ -342,8 +294,8 @@
                 error = ex.getMessage();
             }
 
-            logdWithLocalLog("Unable to bind to " + carrierPackage + " for phone " + phoneId
-                    + ". Error: " + error);
+            log("Unable to bind to " + carrierPackage + " for phone " + phoneId +
+                ". Error: " + error);
             unbind(true /* immediate */);
         }
 
@@ -366,13 +318,12 @@
             // not running anyway and it may be a permanent disconnection (e.g. the app was
             // disabled).
             if (immediate || !connection.connected) {
-                logdWithLocalLog("unbind immediately or with disconnected connection");
                 cancelScheduledUnbind();
                 performImmediateUnbind();
             } else if (mUnbindScheduledUptimeMillis == -1) {
                 long currentUptimeMillis = SystemClock.uptimeMillis();
                 mUnbindScheduledUptimeMillis = currentUptimeMillis + UNBIND_DELAY_MILLIS;
-                logdWithLocalLog("Scheduling unbind in " + UNBIND_DELAY_MILLIS + " millis");
+                log("Scheduling unbind in " + UNBIND_DELAY_MILLIS + " millis");
                 mHandler.sendMessageAtTime(
                         mHandler.obtainMessage(EVENT_PERFORM_IMMEDIATE_UNBIND, phoneId),
                         mUnbindScheduledUptimeMillis);
@@ -388,17 +339,24 @@
             carrierPackage = null;
             carrierServiceClass = null;
 
-            // Always call unbindService, no matter if bindService succeed.
-            if (connection != null) {
-                mContext.unbindService(connection);
-                logdWithLocalLog("Unbinding from carrier app");
-                connection = null;
-                mUnbindScheduledUptimeMillis = -1;
+            // Actually unbind
+            if (mServiceBound) {
+                log("Unbinding from carrier app");
+                mServiceBound = false;
+                try {
+                    mContext.unbindService(connection);
+                } catch (IllegalArgumentException e) {
+                    //TODO(b/151328766): Figure out why we unbind without binding
+                    loge("Tried to unbind without binding e=" + e);
+                }
+            } else {
+                log("Not bound, skipping unbindService call");
             }
+            connection = null;
+            mUnbindScheduledUptimeMillis = -1;
         }
 
         private void cancelScheduledUnbind() {
-            logdWithLocalLog("cancelScheduledUnbind");
             mHandler.removeMessages(EVENT_PERFORM_IMMEDIATE_UNBIND);
             mUnbindScheduledUptimeMillis = -1;
         }
@@ -411,7 +369,6 @@
             pw.println("  unbindCount: " + unbindCount);
             pw.println("  lastUnbindMillis: " + lastUnbindMillis);
             pw.println("  mUnbindScheduledUptimeMillis: " + mUnbindScheduledUptimeMillis);
-            pw.println("  mCarrierServiceChangeCallback: " + mCarrierServiceChangeCallback);
             pw.println();
         }
     }
@@ -421,25 +378,25 @@
 
         @Override
         public void onServiceConnected(ComponentName name, IBinder service) {
-            logdWithLocalLog("Connected to carrier app: " + name.flattenToString());
+            log("Connected to carrier app: " + name.flattenToString());
             connected = true;
         }
 
         @Override
         public void onServiceDisconnected(ComponentName name) {
-            logdWithLocalLog("Disconnected from carrier app: " + name.flattenToString());
+            log("Disconnected from carrier app: " + name.flattenToString());
             connected = false;
         }
 
         @Override
         public void onBindingDied(ComponentName name) {
-            logdWithLocalLog("Binding from carrier app died: " + name.flattenToString());
+            log("Binding from carrier app died: " + name.flattenToString());
             connected = false;
         }
 
         @Override
         public void onNullBinding(ComponentName name) {
-            logdWithLocalLog("Null binding from carrier app: " + name.flattenToString());
+            log("Null binding from carrier app: " + name.flattenToString());
             connected = false;
         }
 
@@ -452,32 +409,27 @@
     private class CarrierServicePackageMonitor extends PackageChangeReceiver {
         @Override
         public void onPackageAdded(String packageName) {
-            logdWithLocalLog("onPackageAdded: " + packageName);
             evaluateBinding(packageName, true /* forceUnbind */);
         }
 
         @Override
         public void onPackageRemoved(String packageName) {
-            logdWithLocalLog("onPackageRemoved: " + packageName);
             evaluateBinding(packageName, true /* forceUnbind */);
         }
 
         @Override
         public void onPackageUpdateFinished(String packageName) {
-            logdWithLocalLog("onPackageUpdateFinished: " + packageName);
             evaluateBinding(packageName, true /* forceUnbind */);
         }
 
         @Override
         public void onPackageModified(String packageName) {
-            logdWithLocalLog("onPackageModified: " + packageName);
             evaluateBinding(packageName, false /* forceUnbind */);
         }
 
         @Override
         public void onHandleForceStop(String[] packages, boolean doit) {
             if (doit) {
-                logdWithLocalLog("onHandleForceStop: " + Arrays.toString(packages));
                 for (String packageName : packages) {
                     evaluateBinding(packageName, true /* forceUnbind */);
                 }
@@ -494,8 +446,7 @@
                 // is unset, in case this package change resulted in a new carrier package becoming
                 // available for binding.
                 if (isBindingForPackage) {
-                    logdWithLocalLog(
-                            carrierPackageName + " changed and corresponds to a phone. Rebinding.");
+                    log(carrierPackageName + " changed and corresponds to a phone. Rebinding.");
                 }
                 if (appBindingPackage == null || isBindingForPackage) {
                     if (forceUnbind) {
@@ -507,22 +458,16 @@
         }
     }
 
-    private void logdWithLocalLog(String msg) {
-        Log.d(LOG_TAG, msg);
-        mLocalLog.log(msg);
+    private static void log(String message) {
+        Log.d(LOG_TAG, message);
     }
 
-    private void logeWithLocalLog(String msg) {
-        Log.e(LOG_TAG, msg);
-        mLocalLog.log(msg);
-    }
+    private static void loge(String message) { Log.e(LOG_TAG, message); }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("CarrierServiceBindHelper:");
         for (int i = 0; i < mBindings.size(); i++) {
             mBindings.get(i).dump(fd, pw, args);
         }
-        pw.println("CarrierServiceBindHelperLogs=");
-        mLocalLog.dump(fd, pw, args);
     }
 }
diff --git a/src/java/com/android/internal/telephony/CarrierServicesSmsFilter.java b/src/java/com/android/internal/telephony/CarrierServicesSmsFilter.java
index 33cde4f..6bc2450 100644
--- a/src/java/com/android/internal/telephony/CarrierServicesSmsFilter.java
+++ b/src/java/com/android/internal/telephony/CarrierServicesSmsFilter.java
@@ -31,6 +31,8 @@
 import android.util.LocalLog;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.uicc.UiccCard;
+import com.android.internal.telephony.uicc.UiccController;
 import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
@@ -141,11 +143,11 @@
 
     private Optional<String> getCarrierAppPackageForFiltering() {
         List<String> carrierPackages = null;
-        CarrierPrivilegesTracker cpt = mPhone.getCarrierPrivilegesTracker();
-        if (cpt != null) {
-            carrierPackages =
-                    cpt.getCarrierPackageNamesForIntent(
-                            new Intent(CarrierMessagingService.SERVICE_INTERFACE));
+        UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
+        if (card != null) {
+            carrierPackages = card.getCarrierPackageNamesForIntent(
+                    mContext.getPackageManager(),
+                    new Intent(CarrierMessagingService.SERVICE_INTERFACE));
         } else {
             loge("getCarrierAppPackageForFiltering: UiccCard not initialized");
         }
@@ -405,7 +407,7 @@
                             .map(callback -> callback.mPackageName)
                             .collect(Collectors.joining(", "));
                     AnomalyReporter.reportAnomaly(sAnomalyNoResponseFromCarrierMessagingService,
-                            "No response from " + packages, mPhone.getCarrierId());
+                            "No response from " + packages);
                     handleFilterCallbacksTimeout();
                     break;
             }
diff --git a/src/java/com/android/internal/telephony/CarrierSignalAgent.java b/src/java/com/android/internal/telephony/CarrierSignalAgent.java
index 2914ff9..1f6385d 100644
--- a/src/java/com/android/internal/telephony/CarrierSignalAgent.java
+++ b/src/java/com/android/internal/telephony/CarrierSignalAgent.java
@@ -126,7 +126,7 @@
     private static final Map<String, String> COMPAT_ACTION_TO_NEW_MAP = NEW_ACTION_TO_COMPAT_MAP
             .entrySet().stream().collect(Collectors.toMap(Map.Entry::getValue, Map.Entry::getKey));
 
-    private final LocalLog mErrorLocalLog = new LocalLog(16);
+    private final LocalLog mErrorLocalLog = new LocalLog(20);
 
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
         public void onReceive(Context context, Intent intent) {
@@ -212,7 +212,7 @@
                 .getSystemService(Context.CARRIER_CONFIG_SERVICE);
         PersistableBundle b = null;
         if (configManager != null) {
-            b = configManager.getConfigForSubId(mPhone.getSubId());
+            b = configManager.getConfig();
         }
         if (b != null) {
             synchronized (mCachedWakeSignalConfigs) {
diff --git a/src/java/com/android/internal/telephony/CellBroadcastServiceManager.java b/src/java/com/android/internal/telephony/CellBroadcastServiceManager.java
index 73da797..30d6129 100644
--- a/src/java/com/android/internal/telephony/CellBroadcastServiceManager.java
+++ b/src/java/com/android/internal/telephony/CellBroadcastServiceManager.java
@@ -60,7 +60,7 @@
     private Phone mPhone;
     private Context mContext;
 
-    private final LocalLog mLocalLog = new LocalLog(64);
+    private final LocalLog mLocalLog = new LocalLog(100);
 
     /** New SMS cell broadcast received as an AsyncResult. */
     private static final int EVENT_NEW_GSM_SMS_CB = 0;
diff --git a/src/java/com/android/internal/telephony/CellularNetworkService.java b/src/java/com/android/internal/telephony/CellularNetworkService.java
index 19a585d..886438a 100644
--- a/src/java/com/android/internal/telephony/CellularNetworkService.java
+++ b/src/java/com/android/internal/telephony/CellularNetworkService.java
@@ -27,14 +27,8 @@
 import android.os.Message;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.AnomalyReporter;
 import android.telephony.CellIdentity;
 import android.telephony.CellIdentityCdma;
-import android.telephony.CellIdentityGsm;
-import android.telephony.CellIdentityLte;
-import android.telephony.CellIdentityNr;
-import android.telephony.CellIdentityTdscdma;
-import android.telephony.CellIdentityWcdma;
 import android.telephony.LteVopsSupportInfo;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.NetworkService;
@@ -45,17 +39,13 @@
 import android.telephony.TelephonyManager;
 import android.telephony.VopsSupportInfo;
 import android.text.TextUtils;
-import android.util.ArrayMap;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.UUID;
 
 /**
  * Implementation of network services for Cellular. It's a service that handles network requests
@@ -74,41 +64,6 @@
     // From 24.008 6.1.3.0 and 10.5.6.2 the maximum number of PDP Contexts is 16.
     private static final int MAX_DATA_CALLS = 16;
 
-    private static final Map<Class<? extends CellIdentity>, List<Integer>> sNetworkTypes;
-
-    static {
-        sNetworkTypes = new ArrayMap<>();
-        sNetworkTypes.put(CellIdentityGsm.class,
-                Arrays.asList(new Integer[]{
-                    TelephonyManager.NETWORK_TYPE_GSM,
-                    TelephonyManager.NETWORK_TYPE_GPRS,
-                    TelephonyManager.NETWORK_TYPE_EDGE}));
-        sNetworkTypes.put(CellIdentityWcdma.class,
-                Arrays.asList(new Integer[]{
-                    TelephonyManager.NETWORK_TYPE_UMTS,
-                    TelephonyManager.NETWORK_TYPE_HSDPA,
-                    TelephonyManager.NETWORK_TYPE_HSUPA,
-                    TelephonyManager.NETWORK_TYPE_HSPA,
-                    TelephonyManager.NETWORK_TYPE_HSPAP}));
-        sNetworkTypes.put(CellIdentityCdma.class,
-                Arrays.asList(new Integer[]{
-                    TelephonyManager.NETWORK_TYPE_CDMA,
-                    TelephonyManager.NETWORK_TYPE_1xRTT,
-                    TelephonyManager.NETWORK_TYPE_EVDO_0,
-                    TelephonyManager.NETWORK_TYPE_EVDO_A,
-                    TelephonyManager.NETWORK_TYPE_EVDO_B,
-                    TelephonyManager.NETWORK_TYPE_EHRPD}));
-        sNetworkTypes.put(CellIdentityLte.class,
-                Arrays.asList(new Integer[]{
-                    TelephonyManager.NETWORK_TYPE_LTE}));
-        sNetworkTypes.put(CellIdentityNr.class,
-                Arrays.asList(new Integer[]{
-                    TelephonyManager.NETWORK_TYPE_NR}));
-        sNetworkTypes.put(CellIdentityTdscdma.class,
-                Arrays.asList(new Integer[]{
-                    TelephonyManager.NETWORK_TYPE_TD_SCDMA}));
-    }
-
     private class CellularNetworkServiceProvider extends NetworkServiceProvider {
 
         private final Map<Message, NetworkServiceCallback> mCallbackMap = new HashMap<>();
@@ -136,7 +91,6 @@
                             int domain = (message.what == GET_CS_REGISTRATION_STATE_DONE)
                                     ? NetworkRegistrationInfo.DOMAIN_CS
                                     : NetworkRegistrationInfo.DOMAIN_PS;
-                            // TODO: move to RILUtils
                             NetworkRegistrationInfo netState =
                                     getRegistrationStateFromResult(ar.result, domain);
 
@@ -266,14 +220,17 @@
             final int transportType = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
             final int domain = NetworkRegistrationInfo.DOMAIN_CS;
 
-            if (result instanceof android.hardware.radio.network.RegStateResult) {
-                return getNetworkRegistrationInfoAidl(domain, transportType,
-                        (android.hardware.radio.network.RegStateResult) result);
-            } else if (result instanceof android.hardware.radio.V1_6.RegStateResult) {
-                return getNetworkRegistrationInfo1_6(domain, transportType,
+            if (result instanceof android.hardware.radio.V1_6.RegStateResult) {
+                return getNetworkRegistrationInfo1_6(
+                        domain,
+                        transportType,
                         (android.hardware.radio.V1_6.RegStateResult) result);
-            } else if (result instanceof android.hardware.radio.V1_5.RegStateResult) {
-                return getNetworkRegistrationInfo(domain, transportType,
+            }
+            // 1.5 at the top so that we can do an "early exit" from the method
+            else if (result instanceof android.hardware.radio.V1_5.RegStateResult) {
+                return getNetworkRegistrationInfo(
+                        domain,
+                        transportType,
                         (android.hardware.radio.V1_5.RegStateResult) result);
             } else if (result instanceof android.hardware.radio.V1_0.VoiceRegStateResult) {
                 android.hardware.radio.V1_0.VoiceRegStateResult voiceRegState =
@@ -288,8 +245,7 @@
                 int defaultRoamingIndicator = voiceRegState.defaultRoamingIndicator;
                 List<Integer> availableServices = getAvailableServices(
                         regState, domain, emergencyOnly);
-                CellIdentity cellIdentity =
-                        RILUtils.convertHalCellIdentity(voiceRegState.cellIdentity);
+                CellIdentity cellIdentity = CellIdentity.create(voiceRegState.cellIdentity);
                 final String rplmn = getPlmnFromCellIdentity(cellIdentity);
 
                 return new NetworkRegistrationInfo(domain, transportType, regState,
@@ -309,8 +265,7 @@
                 int defaultRoamingIndicator = voiceRegState.defaultRoamingIndicator;
                 List<Integer> availableServices = getAvailableServices(
                         regState, domain, emergencyOnly);
-                CellIdentity cellIdentity =
-                        RILUtils.convertHalCellIdentity(voiceRegState.cellIdentity);
+                CellIdentity cellIdentity = CellIdentity.create(voiceRegState.cellIdentity);
                 final String rplmn = getPlmnFromCellIdentity(cellIdentity);
 
                 return new NetworkRegistrationInfo(domain, transportType, regState,
@@ -340,14 +295,17 @@
                     new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
                             LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
 
-            if (result instanceof android.hardware.radio.network.RegStateResult) {
-                return getNetworkRegistrationInfoAidl(domain, transportType,
-                        (android.hardware.radio.network.RegStateResult) result);
-            } else if (result instanceof android.hardware.radio.V1_6.RegStateResult) {
-                return getNetworkRegistrationInfo1_6(domain, transportType,
+            if (result instanceof android.hardware.radio.V1_6.RegStateResult) {
+                return getNetworkRegistrationInfo1_6(
+                        domain,
+                        transportType,
                         (android.hardware.radio.V1_6.RegStateResult) result);
-            } else if (result instanceof android.hardware.radio.V1_5.RegStateResult) {
-                return getNetworkRegistrationInfo(domain, transportType,
+            }
+            // 1.5 at the top so that we can do an "early exit" from the method
+            else if (result instanceof android.hardware.radio.V1_5.RegStateResult) {
+                return getNetworkRegistrationInfo(
+                        domain,
+                        transportType,
                         (android.hardware.radio.V1_5.RegStateResult) result);
             } else if (result instanceof android.hardware.radio.V1_0.DataRegStateResult) {
                 android.hardware.radio.V1_0.DataRegStateResult dataRegState =
@@ -357,7 +315,7 @@
                 reasonForDenial = dataRegState.reasonDataDenied;
                 emergencyOnly = isEmergencyOnly(dataRegState.regState);
                 maxDataCalls = dataRegState.maxDataCalls;
-                cellIdentity = RILUtils.convertHalCellIdentity(dataRegState.cellIdentity);
+                cellIdentity = CellIdentity.create(dataRegState.cellIdentity);
             } else if (result instanceof android.hardware.radio.V1_2.DataRegStateResult) {
                 android.hardware.radio.V1_2.DataRegStateResult dataRegState =
                         (android.hardware.radio.V1_2.DataRegStateResult) result;
@@ -366,7 +324,7 @@
                 reasonForDenial = dataRegState.reasonDataDenied;
                 emergencyOnly = isEmergencyOnly(dataRegState.regState);
                 maxDataCalls = dataRegState.maxDataCalls;
-                cellIdentity = RILUtils.convertHalCellIdentity(dataRegState.cellIdentity);
+                cellIdentity = CellIdentity.create(dataRegState.cellIdentity);
             } else if (result instanceof android.hardware.radio.V1_4.DataRegStateResult) {
                 android.hardware.radio.V1_4.DataRegStateResult dataRegState =
                         (android.hardware.radio.V1_4.DataRegStateResult) result;
@@ -376,7 +334,7 @@
                 reasonForDenial = dataRegState.base.reasonDataDenied;
                 emergencyOnly = isEmergencyOnly(dataRegState.base.regState);
                 maxDataCalls = dataRegState.base.maxDataCalls;
-                cellIdentity = RILUtils.convertHalCellIdentity(dataRegState.base.cellIdentity);
+                cellIdentity = CellIdentity.create(dataRegState.base.cellIdentity);
                 android.hardware.radio.V1_4.NrIndicators nrIndicators = dataRegState.nrIndicators;
 
                 // Check for lteVopsInfo only if its initialized and RAT is EUTRAN
@@ -420,14 +378,17 @@
             final boolean isEmergencyOnly = isEmergencyOnly(regResult.regState);
             final List<Integer> availableServices = getAvailableServices(
                     regState, domain, isEmergencyOnly);
-            final CellIdentity cellIdentity =
-                    RILUtils.convertHalCellIdentity(regResult.cellIdentity);
+            final int rejectCause = regResult.reasonForDenial;
+            final CellIdentity cellIdentity = CellIdentity.create(regResult.cellIdentity);
             final String rplmn = regResult.registeredPlmn;
             final int reasonForDenial = regResult.reasonForDenial;
 
             int networkType = ServiceState.rilRadioTechnologyToNetworkType(regResult.rat);
-            networkType =
-                    getNetworkTypeForCellIdentity(networkType, cellIdentity, mPhone.getCarrierId());
+            if (networkType == TelephonyManager.NETWORK_TYPE_LTE_CA) {
+                // In Radio HAL v1.5, NETWORK_TYPE_LTE_CA is ignored. Callers should use
+                // PhysicalChannelConfig.
+                networkType = TelephonyManager.NETWORK_TYPE_LTE;
+            }
 
             // Conditional parameters for specific RANs
             boolean cssSupported = false;
@@ -488,82 +449,6 @@
             }
         }
 
-        private @NonNull NetworkRegistrationInfo getNetworkRegistrationInfoAidl(int domain,
-                int transportType, android.hardware.radio.network.RegStateResult regResult) {
-            // Perform common conversions that aren't domain specific
-            final int regState = getRegStateFromHalRegState(regResult.regState);
-            final boolean isEmergencyOnly = isEmergencyOnly(regResult.regState);
-            final List<Integer> availableServices = getAvailableServices(
-                    regState, domain, isEmergencyOnly);
-            final CellIdentity cellIdentity =
-                    RILUtils.convertHalCellIdentity(regResult.cellIdentity);
-            final String rplmn = regResult.registeredPlmn;
-            final int reasonForDenial = regResult.reasonForDenial;
-
-            int networkType = ServiceState.rilRadioTechnologyToNetworkType(regResult.rat);
-            if (networkType == TelephonyManager.NETWORK_TYPE_LTE_CA) {
-                networkType = TelephonyManager.NETWORK_TYPE_LTE;
-            }
-
-            // Conditional parameters for specific RANs
-            boolean cssSupported = false;
-            int roamingIndicator = 0;
-            int systemIsInPrl = 0;
-            int defaultRoamingIndicator = 0;
-            boolean isEndcAvailable = false;
-            boolean isNrAvailable = false;
-            boolean isDcNrRestricted = false;
-            VopsSupportInfo vopsInfo = null;
-
-            android.hardware.radio.network.AccessTechnologySpecificInfo info =
-                    regResult.accessTechnologySpecificInfo;
-
-            switch (info.getTag()) {
-                case android.hardware.radio.network.AccessTechnologySpecificInfo.cdmaInfo:
-                    cssSupported = info.getCdmaInfo().cssSupported;
-                    roamingIndicator = info.getCdmaInfo().roamingIndicator;
-                    systemIsInPrl = info.getCdmaInfo().systemIsInPrl;
-                    defaultRoamingIndicator = info.getCdmaInfo().defaultRoamingIndicator;
-                    break;
-                case android.hardware.radio.network.AccessTechnologySpecificInfo.eutranInfo:
-                    isDcNrRestricted = info.getEutranInfo().nrIndicators.isDcNrRestricted;
-                    isNrAvailable = info.getEutranInfo().nrIndicators.isNrAvailable;
-                    isEndcAvailable = info.getEutranInfo().nrIndicators.isEndcAvailable;
-                    vopsInfo = convertHalLteVopsSupportInfo(
-                            info.getEutranInfo().lteVopsInfo.isVopsSupported,
-                            info.getEutranInfo().lteVopsInfo.isEmcBearerSupported);
-                    break;
-                case android.hardware.radio.network.AccessTechnologySpecificInfo.ngranNrVopsInfo:
-                    vopsInfo = new NrVopsSupportInfo(info.getNgranNrVopsInfo().vopsSupported,
-                            info.getNgranNrVopsInfo().emcSupported,
-                            info.getNgranNrVopsInfo().emfSupported);
-                    break;
-                case android.hardware.radio.network.AccessTechnologySpecificInfo.geranDtmSupported:
-                    cssSupported = info.getGeranDtmSupported();
-                    break;
-                default:
-                    log("No access tech specific info passes for RegStateResult");
-                    break;
-            }
-
-            // build the result based on the domain for the request
-            switch (domain) {
-                case NetworkRegistrationInfo.DOMAIN_CS:
-                    return new NetworkRegistrationInfo(domain, transportType, regState,
-                            networkType, reasonForDenial, isEmergencyOnly, availableServices,
-                            cellIdentity, rplmn, cssSupported, roamingIndicator, systemIsInPrl,
-                            defaultRoamingIndicator);
-                default:
-                    loge("Unknown domain passed to CellularNetworkService= " + domain);
-                    // fall through
-                case NetworkRegistrationInfo.DOMAIN_PS:
-                    return new NetworkRegistrationInfo(domain, transportType, regState, networkType,
-                            reasonForDenial, isEmergencyOnly, availableServices, cellIdentity,
-                            rplmn, MAX_DATA_CALLS, isDcNrRestricted, isNrAvailable, isEndcAvailable,
-                            vopsInfo);
-            }
-        }
-
         private @NonNull NetworkRegistrationInfo getNetworkRegistrationInfo1_6(
                 int domain, int transportType,
                 android.hardware.radio.V1_6.RegStateResult regResult) {
@@ -573,14 +458,17 @@
             final boolean isEmergencyOnly = isEmergencyOnly(regResult.regState);
             final List<Integer> availableServices = getAvailableServices(
                     regState, domain, isEmergencyOnly);
-            final CellIdentity cellIdentity =
-                    RILUtils.convertHalCellIdentity(regResult.cellIdentity);
+            final int rejectCause = regResult.reasonForDenial;
+            final CellIdentity cellIdentity = CellIdentity.create(regResult.cellIdentity);
             final String rplmn = regResult.registeredPlmn;
             final int reasonForDenial = regResult.reasonForDenial;
 
             int networkType = ServiceState.rilRadioTechnologyToNetworkType(regResult.rat);
-            networkType =
-                    getNetworkTypeForCellIdentity(networkType, cellIdentity, mPhone.getCarrierId());
+            if (networkType == TelephonyManager.NETWORK_TYPE_LTE_CA) {
+                // In Radio HAL v1.5, NETWORK_TYPE_LTE_CA is ignored. Callers should use
+                // PhysicalChannelConfig.
+                networkType = TelephonyManager.NETWORK_TYPE_LTE;
+            }
 
             // Conditional parameters for specific RANs
             boolean cssSupported = false;
@@ -682,79 +570,6 @@
         }
     }
 
-    /** Cross-check the network type against the CellIdentity type */
-    @VisibleForTesting
-    public static int getNetworkTypeForCellIdentity(
-            int networkType, CellIdentity ci, int carrierId) {
-        if (ci == null) {
-            if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
-                // Network type is non-null but CellIdentity is null
-                AnomalyReporter.reportAnomaly(
-                        UUID.fromString("e67ea4ef-7251-4a69-a063-22c47fc58743"),
-                            "RIL Unexpected NetworkType", carrierId);
-                if (android.os.Build.isDebuggable()) {
-                    logw("Updating incorrect network type from "
-                            + TelephonyManager.getNetworkTypeName(networkType) + " to UNKNOWN");
-                    return TelephonyManager.NETWORK_TYPE_UNKNOWN;
-                } else {
-                    // If the build isn't debuggable and CellIdentity is null, there's no way to
-                    // guess the approximately correct type so if it's valid it gets a pass.
-                    for (List<Integer> values : sNetworkTypes.values()) {
-                        if (values.contains(networkType)) return networkType;
-                    }
-                }
-            }
-
-            // No valid network type, so return UNKNOWN for safety.
-            return TelephonyManager.NETWORK_TYPE_UNKNOWN;
-        }
-
-
-        // If the type is reported as IWLAN but the CellIdentity is a cellular type,
-        // report that; Devices post HAL 1.4 should be operating in AP-assisted mode
-        if (networkType == TelephonyManager.NETWORK_TYPE_IWLAN) {
-            AnomalyReporter.reportAnomaly(
-                    UUID.fromString("07dfa183-b2e7-42b7-98a1-dd5ae2abdd4f"),
-                            "RIL Reported IWLAN", carrierId);
-            if (!android.os.Build.isDebuggable()) return networkType;
-
-            if (sNetworkTypes.containsKey(ci.getClass())) {
-                final int updatedType = sNetworkTypes.get(ci.getClass()).get(0);
-                logw("Updating incorrect network type from IWLAN to " + updatedType);
-                return updatedType;
-            } else {
-                logw("Updating incorrect network type from IWLAN to UNKNOWN");
-                return TelephonyManager.NETWORK_TYPE_UNKNOWN;
-            }
-        }
-
-        if (!sNetworkTypes.containsKey(ci.getClass())) {
-            AnomalyReporter.reportAnomaly(
-                    UUID.fromString("469858cf-46e5-416e-bc11-5e7970917857"),
-                        "RIL Unknown CellIdentity", carrierId);
-            return networkType;
-        }
-
-        // If the network type isn't valid for the CellIdentity type,
-        final List<Integer> typesForCi = sNetworkTypes.get(ci.getClass());
-        if (!typesForCi.contains(networkType)) {
-            AnomalyReporter.reportAnomaly(
-                    UUID.fromString("2fb634fa-cab3-44d2-bbe8-c7689b0f3e31"),
-                        "RIL Mismatched NetworkType", carrierId);
-            // Since this is a plain-and-simple mismatch between two conflicting pieces of
-            // data, and theres no way to know which one to trust, pick the one that's harder
-            // to coerce / fake / set incorrectly and make them roughly match.
-            // Note, this also does the fixup for LTE_CA -> LTE that was formerly done as a
-            // special case.
-            logw("Updating incorrect network type from "
-                    + TelephonyManager.getNetworkTypeName(networkType)
-                    + " to " + TelephonyManager.getNetworkTypeName(typesForCi.get(0)));
-            return typesForCi.get(0);
-        }
-
-        return networkType;
-    }
-
     @Override
     public NetworkServiceProvider onCreateNetworkServiceProvider(int slotIndex) {
         if (DBG) log("Cellular network service created for slot " + slotIndex);
@@ -765,15 +580,11 @@
         return new CellularNetworkServiceProvider(slotIndex);
     }
 
-    private static void log(String s) {
+    private void log(String s) {
         Rlog.d(TAG, s);
     }
 
-    private static void logw(String s) {
-        Rlog.w(TAG, s);
-    }
-
-    private static void loge(String s) {
+    private void loge(String s) {
         Rlog.e(TAG, s);
     }
 }
diff --git a/src/java/com/android/internal/telephony/data/CellularNetworkValidator.java b/src/java/com/android/internal/telephony/CellularNetworkValidator.java
similarity index 98%
rename from src/java/com/android/internal/telephony/data/CellularNetworkValidator.java
rename to src/java/com/android/internal/telephony/CellularNetworkValidator.java
index c63676f..7124703 100644
--- a/src/java/com/android/internal/telephony/data/CellularNetworkValidator.java
+++ b/src/java/com/android/internal/telephony/CellularNetworkValidator.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony;
 
 import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
 import static android.telephony.CarrierConfigManager.KEY_DATA_SWITCH_VALIDATION_MIN_GAP_LONG;
@@ -37,10 +37,6 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConfigurationManager;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyEvent;
 
diff --git a/src/java/com/android/internal/telephony/CommandsInterface.java b/src/java/com/android/internal/telephony/CommandsInterface.java
index 27cedfe..a6ff3fa 100644
--- a/src/java/com/android/internal/telephony/CommandsInterface.java
+++ b/src/java/com/android/internal/telephony/CommandsInterface.java
@@ -17,7 +17,6 @@
 package com.android.internal.telephony;
 
 import android.annotation.NonNull;
-import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.net.KeepalivePacketData;
 import android.net.LinkProperties;
@@ -229,10 +228,6 @@
     void registerForApnUnthrottled(Handler h, int what, Object obj);
     /** Unregister for apn unthrottled event */
     void unregisterForApnUnthrottled(Handler h);
-    /** Register for the slicing config changed event */
-    void registerForSlicingConfigChanged(Handler h, int what, Object obj);
-    /** Unregister for slicing config changed event */
-    void unregisterForSlicingConfigChanged(Handler h);
 
     /** InCall voice privacy notifications */
     void registerForInCallVoicePrivacyOn(Handler h, int what, Object obj);
@@ -1604,17 +1599,6 @@
     default void isNrDualConnectivityEnabled(Message message, WorkSource workSource) {}
 
     /**
-     * Enable or disable Voice over NR (VoNR)
-     * @param enabled enable or disable VoNR.
-     */
-    default void setVoNrEnabled(boolean enabled, Message message, WorkSource workSource) {}
-
-    /**
-     * Is voice over NR enabled
-     */
-    default void isVoNrEnabled(Message message, WorkSource workSource) {}
-
-    /**
      * Request to enable/disable network state change notifications when
      * location information (lac and/or cid) has changed.
      *
@@ -2211,15 +2195,6 @@
             Message result);
 
     /**
-     * Whether the device modem supports reporting the EID in either the slot or card status or
-     * through ATR.
-     * @return true if the modem supports EID.
-     */
-    default boolean supportsEid() {
-        return false;
-    }
-
-    /**
      * Tells the modem if data is allowed or not.
      *
      * @param allowed
@@ -2394,20 +2369,30 @@
     void setUnsolResponseFilter(int filter, Message result);
 
     /**
-     * Sets or clears the signal strength reporting criteria for multiple RANs in one request.
+     * Sets the signal strength reporting criteria.
      *
-     * The reporting criteria are set individually for each combination of RAN and measurement type.
-     * For each RAN type, if no reporting criteria are set, then the reporting of SignalStrength for
-     * that RAN is implementation-defined. If any criteria are supplied for a RAN type, then
-     * SignalStrength is only reported as specified by those criteria. For any RAN types not defined
-     * by this HAL, reporting is implementation-defined.
+     * The resulting reporting rules are the AND of all the supplied criteria. For each RAN
+     * The hysteresisDb and thresholds apply to only the following measured quantities:
+     * -GERAN    - RSSI
+     * -CDMA2000 - RSSI
+     * -UTRAN    - RSCP
+     * -EUTRAN   - RSRP/RSRQ/RSSNR
+     * -NGRAN    - SSRSRP/SSRSRQ/SSSINR
      *
-     * @param signalThresholdInfos Collection of SignalThresholdInfo specifying the reporting
-     *        criteria. See SignalThresholdInfo for details.
+     * Note: Reporting criteria must be individually set for each RAN. For any unset reporting
+     * criteria, the value is implementation-defined.
+     *
+     * Response callback is
+     * IRadioResponse.setSignalStrengthReportingCriteriaResponse_1_5()
+     *
+     * @param signalThresholdInfo Signal threshold info including the threshold values,
+     *                            hysteresisDb, and hysteresisMs. See @1.5::SignalThresholdInfo
+     *                            for details.
+     * @param ran The type of network for which to apply these thresholds.
      * @param result callback message contains the information of SUCCESS/FAILURE
      */
-    void setSignalStrengthReportingCriteria(@NonNull List<SignalThresholdInfo> signalThresholdInfos,
-            @Nullable Message result);
+    void setSignalStrengthReportingCriteria(SignalThresholdInfo signalThresholdInfo, int ran,
+            Message result);
 
     /**
      * Send the link capacity reporting criteria to the modem
@@ -2674,25 +2659,6 @@
      */
     default void getSlicingConfig(Message result) {};
 
-    /**
-     * Request to enable/disable the mock modem service.
-     * This is used in shell commands during CTS testing only.
-     *
-     * @param serviceName the service name which telephony wants to bind to
-     */
-    default boolean setModemService(String serviceName) {
-        return true;
-    };
-
-   /**
-     * Return the class name of the currently bound modem service.
-     *
-     * @return the class name of the modem service.
-     */
-    default String getModemService() {
-        return "default";
-    };
-
    /**
      * Request the SIM phonebook records of all activated UICC applications
      *
@@ -2745,20 +2711,4 @@
      * @param h Handler to be removed from the registrant list.
      */
      public void unregisterForSimPhonebookRecordsReceived(Handler h);
-
-    /**
-     * Set the UE's usage setting.
-     *
-     * @param result Callback message containing the success or failure status.
-     * @param usageSetting the UE's usage setting, either VOICE_CENTRIC or DATA_CENTRIC.
-     */
-    default void setUsageSetting(Message result,
-            /* @TelephonyManager.UsageSetting */ int usageSetting) {}
-
-    /**
-     * Get the UE's usage setting.
-     *
-     * @param result Callback message containing the usage setting (or a failure status).
-     */
-    default void getUsageSetting(Message result) {}
 }
diff --git a/src/java/com/android/internal/telephony/Connection.java b/src/java/com/android/internal/telephony/Connection.java
index c60e5df..59a5195 100644
--- a/src/java/com/android/internal/telephony/Connection.java
+++ b/src/java/com/android/internal/telephony/Connection.java
@@ -92,11 +92,6 @@
          * local device.
          */
         public static final int IS_PULLABLE = 0x00000020;
-
-        /**
-         * For an IMS call, indicates that the peer supports RTT.
-         */
-        public static final int SUPPORTS_RTT_REMOTE = 0x00000040;
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/DataIndication.java b/src/java/com/android/internal/telephony/DataIndication.java
deleted file mode 100644
index c16cbaa..0000000
--- a/src/java/com/android/internal/telephony/DataIndication.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_DATA_CALL_LIST_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_KEEPALIVE_STATUS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_PCO_DATA;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SLICING_CONFIG_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UNTHROTTLE_APN;
-
-import android.hardware.radio.data.IRadioDataIndication;
-import android.os.AsyncResult;
-import android.os.RemoteException;
-import android.telephony.PcoData;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataProfile;
-import android.telephony.data.NetworkSlicingConfig;
-
-import com.android.internal.telephony.data.KeepaliveStatus;
-
-import java.util.ArrayList;
-
-/**
- * Interface declaring unsolicited radio indications for data APIs.
- */
-public class DataIndication extends IRadioDataIndication.Stub {
-    private final RIL mRil;
-
-    public DataIndication(RIL ril) {
-        mRil = ril;
-    }
-
-    /**
-     * Indicates data call contexts have changed.
-     * @param indicationType Type of radio indication
-     * @param dcList List of SetupDataCallResult identical to that returned by getDataCallList.
-     *        It is the complete list of current data contexts including new contexts that have
-     *        been activated.
-     */
-    public void dataCallListChanged(int indicationType,
-            android.hardware.radio.data.SetupDataCallResult[] dcList) {
-        mRil.processIndication(RIL.DATA_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_DATA_CALL_LIST_CHANGED, dcList);
-        ArrayList<DataCallResponse> response = RILUtils.convertHalDataCallResultList(dcList);
-        mRil.mDataCallListChangedRegistrants.notifyRegistrants(
-                new AsyncResult(null, response, null));
-    }
-
-    /**
-     * Indicates a status update for an ongoing Keepalive session.
-     * @param indicationType Type of radio indication
-     * @param halStatus Status of the ongoing Keepalive session
-     */
-    public void keepaliveStatus(int indicationType,
-            android.hardware.radio.data.KeepaliveStatus halStatus) {
-        mRil.processIndication(RIL.DATA_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) {
-            mRil.unsljLogRet(RIL_UNSOL_KEEPALIVE_STATUS, "handle=" + halStatus.sessionHandle
-                    + " code=" +  halStatus.code);
-        }
-
-        KeepaliveStatus ks = new KeepaliveStatus(
-                halStatus.sessionHandle, halStatus.code);
-        mRil.mNattKeepaliveStatusRegistrants.notifyRegistrants(new AsyncResult(null, ks, null));
-    }
-
-    /**
-     * Indicates when there is new Carrier PCO data received for a data call.
-     * @param indicationType Type of radio indication
-     * @param pco New PcoData
-     */
-    public void pcoData(int indicationType, android.hardware.radio.data.PcoDataInfo pco) {
-        mRil.processIndication(RIL.DATA_SERVICE, indicationType);
-
-        PcoData response = new PcoData(pco.cid, pco.bearerProto, pco.pcoId, pco.contents);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_PCO_DATA, response);
-
-        mRil.mPcoDataRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
-    }
-
-    /**
-     * Stop throttling calls to setupDataCall for the given APN.
-     * @param indicationType Type of radio indication
-     * @param dpi DataProfileInfo associated with the APN to unthrottle
-     * @throws RemoteException
-     */
-    public void unthrottleApn(int indicationType, android.hardware.radio.data.DataProfileInfo dpi)
-            throws RemoteException {
-        mRil.processIndication(RIL.DATA_SERVICE, indicationType);
-        DataProfile response = RILUtils.convertToDataProfile(dpi);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_UNTHROTTLE_APN, response);
-
-        mRil.mApnUnthrottledRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
-    }
-
-    /**
-     * Current slicing configuration including URSP rules and NSSAIs
-     * (configured, allowed and rejected).
-     * @param indicationType Type of radio indication
-     * @param slicingConfig Current slicing configuration
-     */
-    public void slicingConfigChanged(int indicationType,
-            android.hardware.radio.data.SlicingConfig slicingConfig) throws RemoteException {
-        mRil.processIndication(RIL.DATA_SERVICE, indicationType);
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_SLICING_CONFIG_CHANGED, slicingConfig);
-        NetworkSlicingConfig ret = RILUtils.convertHalSlicingConfig(slicingConfig);
-        mRil.mSlicingConfigChangedRegistrants.notifyRegistrants(
-                new AsyncResult(null, ret, null));
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return IRadioDataIndication.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return IRadioDataIndication.VERSION;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/DataResponse.java b/src/java/com/android/internal/telephony/DataResponse.java
deleted file mode 100644
index 7cfe13b..0000000
--- a/src/java/com/android/internal/telephony/DataResponse.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.hardware.radio.RadioError;
-import android.hardware.radio.RadioResponseInfo;
-import android.hardware.radio.data.IRadioDataResponse;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.NetworkSlicingConfig;
-
-import com.android.internal.telephony.data.KeepaliveStatus;
-
-import java.util.ArrayList;
-
-/**
- * Interface declaring response functions to solicited radio requests for data APIs.
- */
-public class DataResponse extends IRadioDataResponse.Stub {
-    private final RIL mRil;
-
-    public DataResponse(RIL ril) {
-        mRil = ril;
-    }
-
-    /**
-     * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for
-     * radio request which take long time to respond.
-     * For more details, refer https://source.android.com/devices/tech/connect/ril.html
-     * @param serial Serial no. of the request whose acknowledgement is sent.
-     */
-    public void acknowledgeRequest(int serial) {
-        mRil.processRequestAck(serial);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param id The pdu session id allocated
-     */
-    public void allocatePduSessionIdResponse(RadioResponseInfo responseInfo, int id) {
-        RILRequest rr = mRil.processResponse(RIL.DATA_SERVICE, responseInfo);
-        if (rr != null) {
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, id);
-            }
-            mRil.processResponseDone(rr, responseInfo, id);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void cancelHandoverResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.DATA_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void deactivateDataCallResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.DATA_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param dataCallResultList Response to get data call list as defined by SetupDataCallResult
-     */
-    public void getDataCallListResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.data.SetupDataCallResult[] dataCallResultList) {
-        RILRequest rr = mRil.processResponse(RIL.DATA_SERVICE, responseInfo);
-
-        if (rr != null) {
-            ArrayList<DataCallResponse> response =
-                    RILUtils.convertHalDataCallResultList(dataCallResultList);
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, response);
-            }
-            mRil.processResponseDone(rr, responseInfo, response);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param slicingConfig Current slicing configuration
-     */
-    public void getSlicingConfigResponse(RadioResponseInfo responseInfo,
-                android.hardware.radio.data.SlicingConfig slicingConfig) {
-        RILRequest rr = mRil.processResponse(RIL.DATA_SERVICE, responseInfo);
-
-        if (rr != null) {
-            NetworkSlicingConfig ret = RILUtils.convertHalSlicingConfig(slicingConfig);
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void releasePduSessionIdResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.DATA_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setDataAllowedResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.DATA_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setDataProfileResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.DATA_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setDataThrottlingResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.DATA_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setInitialAttachApnResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.DATA_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param setupDataCallResult Response to data call setup as defined by SetupDataCallResult
-     */
-    public void setupDataCallResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.data.SetupDataCallResult setupDataCallResult) {
-        RILRequest rr = mRil.processResponse(RIL.DATA_SERVICE, responseInfo);
-
-        if (rr != null) {
-            DataCallResponse response = RILUtils.convertHalDataCallResult(setupDataCallResult);
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, response);
-            }
-            mRil.processResponseDone(rr, responseInfo, response);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void startHandoverResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.DATA_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param keepaliveStatus status of the keepalive with a handle for the session
-     */
-    public void startKeepaliveResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.data.KeepaliveStatus keepaliveStatus) {
-
-        RILRequest rr = mRil.processResponse(RIL.DATA_SERVICE, responseInfo);
-        if (rr == null) return;
-
-        KeepaliveStatus ret = null;
-        try {
-            switch(responseInfo.error) {
-                case RadioError.NONE:
-                    int convertedStatus = RILUtils.convertHalKeepaliveStatusCode(
-                            keepaliveStatus.code);
-                    if (convertedStatus < 0) {
-                        ret = new KeepaliveStatus(KeepaliveStatus.ERROR_UNSUPPORTED);
-                    } else {
-                        ret = new KeepaliveStatus(
-                                keepaliveStatus.sessionHandle, convertedStatus);
-                    }
-                    // If responseInfo.error is NONE, response function sends the response message
-                    // even if result is actually an error.
-                    RadioResponse.sendMessageResponse(rr.mResult, ret);
-                    break;
-                case RadioError.REQUEST_NOT_SUPPORTED:
-                    ret = new KeepaliveStatus(KeepaliveStatus.ERROR_UNSUPPORTED);
-                    break;
-                case RadioError.NO_RESOURCES:
-                    ret = new KeepaliveStatus(KeepaliveStatus.ERROR_NO_RESOURCES);
-                    break;
-                default:
-                    ret = new KeepaliveStatus(KeepaliveStatus.ERROR_UNKNOWN);
-                    break;
-            }
-        } finally {
-            // If responseInfo.error != NONE, the processResponseDone sends the response message.
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void stopKeepaliveResponse(RadioResponseInfo responseInfo) {
-        RILRequest rr = mRil.processResponse(RIL.DATA_SERVICE, responseInfo);
-        if (rr == null) return;
-
-        try {
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, null);
-            } else {
-                //TODO: Error code translation
-            }
-        } finally {
-            mRil.processResponseDone(rr, responseInfo, null);
-        }
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return IRadioDataResponse.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return IRadioDataResponse.VERSION;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/DebugService.java b/src/java/com/android/internal/telephony/DebugService.java
index 0b759b5..3a08243 100644
--- a/src/java/com/android/internal/telephony/DebugService.java
+++ b/src/java/com/android/internal/telephony/DebugService.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import android.text.TextUtils;
+
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.telephony.Rlog;
 
@@ -42,17 +44,13 @@
      */
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         if (args != null && args.length > 0) {
-            switch (args[0]) {
-                case "--metrics":
-                case "--metricsproto":
-                case "--metricsprototext":
-                    log("Collecting telephony metrics..");
-                    TelephonyMetrics.getInstance().dump(fd, pw, args);
-                    return;
-                case "--saveatoms":
-                    log("Saving atoms..");
-                    PhoneFactory.getMetricsCollector().getAtomsStorage().flushAtoms();
-                    return;
+            if (TextUtils.equals(args[0], "--metrics")
+                    || TextUtils.equals(args[0], "--metricsproto")
+                    || TextUtils.equals(args[0], "--metricsprototext"))
+            {
+                log("Collecting telephony metrics..");
+                TelephonyMetrics.getInstance().dump(fd, pw, args);
+                return;
             }
         }
         log("Dump telephony.");
diff --git a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
index e4aff4c..333e994 100644
--- a/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
+++ b/src/java/com/android/internal/telephony/DefaultPhoneNotifier.java
@@ -31,11 +31,13 @@
 import android.telephony.PreciseDataConnectionState;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyDisplayInfo;
+import android.telephony.TelephonyManager;
 import android.telephony.TelephonyManager.DataEnabledReason;
 import android.telephony.TelephonyRegistryManager;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.ims.ImsReasonInfo;
 
+import com.android.internal.telephony.PhoneInternalInterface.DataActivityState;
 import com.android.telephony.Rlog;
 
 import java.util.List;
@@ -121,7 +123,8 @@
     @Override
     public void notifyDataActivity(Phone sender) {
         int subId = sender.getSubId();
-        mTelephonyRegistryMgr.notifyDataActivityChanged(subId, sender.getDataActivityState());
+        mTelephonyRegistryMgr.notifyDataActivityChanged(subId,
+                convertDataActivityState(sender.getDataActivityState()));
     }
 
     @Override
@@ -263,6 +266,25 @@
     }
 
     /**
+     * Convert the {@link DataActivityState} enum into the TelephonyManager.DATA_* constants for the
+     * public API.
+     */
+    public static int convertDataActivityState(DataActivityState state) {
+        switch (state) {
+            case DATAIN:
+                return TelephonyManager.DATA_ACTIVITY_IN;
+            case DATAOUT:
+                return TelephonyManager.DATA_ACTIVITY_OUT;
+            case DATAINANDOUT:
+                return TelephonyManager.DATA_ACTIVITY_INOUT;
+            case DORMANT:
+                return TelephonyManager.DATA_ACTIVITY_DORMANT;
+            default:
+                return TelephonyManager.DATA_ACTIVITY_NONE;
+        }
+    }
+
+    /**
      * Convert the {@link Call.State} enum into the PreciseCallState.PRECISE_CALL_STATE_* constants
      * for the public API.
      */
diff --git a/src/java/com/android/internal/telephony/DeviceStateMonitor.java b/src/java/com/android/internal/telephony/DeviceStateMonitor.java
index 3d63a29..1650b6f 100644
--- a/src/java/com/android/internal/telephony/DeviceStateMonitor.java
+++ b/src/java/com/android/internal/telephony/DeviceStateMonitor.java
@@ -41,7 +41,9 @@
 import android.os.RegistrantList;
 import android.provider.Settings;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.CarrierConfigManager;
 import android.telephony.NetworkRegistrationInfo;
+import android.telephony.SignalThresholdInfo;
 import android.util.LocalLog;
 import android.view.Display;
 
@@ -80,8 +82,6 @@
     @VisibleForTesting
     static final int EVENT_WIFI_CONNECTION_CHANGED      = 7;
     static final int EVENT_UPDATE_ALWAYS_REPORT_SIGNAL_STRENGTH = 8;
-    static final int EVENT_RADIO_ON                     = 9;
-    static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE   = 10;
 
     private static final int WIFI_UNAVAILABLE = 0;
     private static final int WIFI_AVAILABLE = 1;
@@ -92,7 +92,7 @@
 
     private final Phone mPhone;
 
-    private final LocalLog mLocalLog = new LocalLog(64);
+    private final LocalLog mLocalLog = new LocalLog(100);
 
     private final RegistrantList mPhysicalChannelConfigRegistrants = new RegistrantList();
 
@@ -180,12 +180,6 @@
     private boolean mIsAutomotiveProjectionActive;
 
     /**
-     * Radio is on. False means that radio is either off or not available and it is ok to reduce
-     * commands to the radio to avoid unnecessary power consumption.
-     */
-    private boolean mIsRadioOn;
-
-    /**
      * True indicates we should always enable the signal strength reporting from radio.
      */
     private boolean mIsAlwaysSignalStrengthReportingEnabled;
@@ -277,7 +271,6 @@
         mIsPowerSaveOn = isPowerSaveModeOn();
         mIsCharging = isDeviceCharging();
         mIsScreenOn = isScreenOn();
-        mIsRadioOn = isRadioOn();
         mIsAutomotiveProjectionActive = isAutomotiveProjectionActive();
         // Assuming tethering is always off after boot up.
         mIsTetheringOn = false;
@@ -291,8 +284,7 @@
                 + ", mIsAutomotiveProjectionActive=" + mIsAutomotiveProjectionActive
                 + ", mIsWifiConnected=" + mIsWifiConnected
                 + ", mIsAlwaysSignalStrengthReportingEnabled="
-                + mIsAlwaysSignalStrengthReportingEnabled
-                + ", mIsRadioOn=" + mIsRadioOn, false);
+                + mIsAlwaysSignalStrengthReportingEnabled, false);
 
         final IntentFilter filter = new IntentFilter();
         filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
@@ -303,8 +295,6 @@
 
         mPhone.mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null);
         mPhone.mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
-        mPhone.mCi.registerForOn(this, EVENT_RADIO_ON, null);
-        mPhone.mCi.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
 
         ConnectivityManager cm = (ConnectivityManager) phone.getContext().getSystemService(
                 Context.CONNECTIVITY_SERVICE);
@@ -325,7 +315,7 @@
      * @return True if low data is expected
      */
     private boolean isLowDataExpected() {
-        return (!mIsCharging && !mIsTetheringOn && !mIsScreenOn) || !mIsRadioOn;
+        return !mIsCharging && !mIsTetheringOn && !mIsScreenOn;
     }
 
     /**
@@ -355,13 +345,10 @@
      */
     private boolean shouldEnableSignalStrengthReports() {
         // We should enable signal strength update if one of the following condition is true.
-        // 1. Whenever the conditions for high power usage are met.
-        // 2. Any of system services is registrating to always listen to signal strength changes
-        //    and the radio is on (if radio is off no indications should be sent regardless, but
-        //    in the rare case that something registers/unregisters for always-on indications
-        //    and the radio is off, we might as well ignore it).
-        return shouldEnableHighPowerConsumptionIndications()
-                || (mIsAlwaysSignalStrengthReportingEnabled && mIsRadioOn);
+        // 1. The device is charging.
+        // 2. When the screen is on.
+        // 3. Any of system services is registrating to always listen to signal strength changes
+        return mIsAlwaysSignalStrengthReportingEnabled || mIsCharging || mIsScreenOn;
     }
 
     /**
@@ -412,14 +399,12 @@
      * @return True if the response update should be enabled.
      */
     public boolean shouldEnableHighPowerConsumptionIndications() {
-        // We should enable indications reports if radio is on and one of the following conditions
-        // is true:
+        // We should enable indications reports if one of the following condition is true.
         // 1. The device is charging.
         // 2. When the screen is on.
         // 3. When the tethering is on.
         // 4. When automotive projection (Android Auto) is on.
-        return (mIsCharging || mIsScreenOn || mIsTetheringOn || mIsAutomotiveProjectionActive)
-                && mIsRadioOn;
+        return mIsCharging || mIsScreenOn || mIsTetheringOn || mIsAutomotiveProjectionActive;
     }
 
     /**
@@ -470,12 +455,6 @@
             case EVENT_RADIO_AVAILABLE:
                 onReset();
                 break;
-            case EVENT_RADIO_ON:
-                onUpdateDeviceState(msg.what, /* state= */ true);
-                break;
-            case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
-                onUpdateDeviceState(msg.what, /* state= */ false);
-                break;
             case EVENT_SCREEN_STATE_CHANGED:
             case EVENT_POWER_SAVE_MODE_CHANGED:
             case EVENT_CHARGING_STATE_CHANGED:
@@ -511,11 +490,6 @@
                 mIsCharging = state;
                 sendDeviceState(CHARGING_STATE, mIsCharging);
                 break;
-            case EVENT_RADIO_ON:
-            case EVENT_RADIO_OFF_OR_NOT_AVAILABLE:
-                if (mIsRadioOn == state) return;
-                mIsRadioOn = state;
-                break;
             case EVENT_TETHERING_STATE_CHANGED:
                 if (mIsTetheringOn == state) return;
                 mIsTetheringOn = state;
@@ -616,6 +590,7 @@
         sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected);
         sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn);
         setUnsolResponseFilter(mUnsolicitedResponseFilter, true);
+        setSignalStrengthReportingCriteria();
         setLinkCapacityReportingCriteria();
         setCellInfoMinInterval(mCellInfoMinInterval);
     }
@@ -660,6 +635,36 @@
         }
     }
 
+    private void setSignalStrengthReportingCriteria() {
+        mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
+                AccessNetworkThresholds.GERAN, AccessNetworkType.GERAN, true);
+        mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP,
+                AccessNetworkThresholds.UTRAN, AccessNetworkType.UTRAN, true);
+        mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
+                AccessNetworkThresholds.EUTRAN_RSRP, AccessNetworkType.EUTRAN, true);
+        mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
+                AccessNetworkThresholds.CDMA2000, AccessNetworkType.CDMA2000, true);
+        if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
+            mPhone.setSignalStrengthReportingCriteria(
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
+                    AccessNetworkThresholds.EUTRAN_RSRQ, AccessNetworkType.EUTRAN, false);
+            mPhone.setSignalStrengthReportingCriteria(
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR,
+                    AccessNetworkThresholds.EUTRAN_RSSNR, AccessNetworkType.EUTRAN, true);
+
+            // Defaultly we only need SSRSRP for NGRAN signal criteria reporting
+            mPhone.setSignalStrengthReportingCriteria(
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
+                    AccessNetworkThresholds.NGRAN_RSRSRP, AccessNetworkType.NGRAN, true);
+            mPhone.setSignalStrengthReportingCriteria(
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
+                    AccessNetworkThresholds.NGRAN_RSRSRQ, AccessNetworkType.NGRAN, false);
+            mPhone.setSignalStrengthReportingCriteria(
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR,
+                    AccessNetworkThresholds.NGRAN_SSSINR, AccessNetworkType.NGRAN, false);
+        }
+    }
+
     private void setLinkCapacityReportingCriteria() {
         mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS,
                 LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.GERAN);
@@ -735,13 +740,6 @@
     }
 
     /**
-     * @return True if the radio is on.
-     */
-    private boolean isRadioOn() {
-        return mPhone.isRadioOn();
-    }
-
-    /**
      * @return True if automotive projection (Android Auto) is active.
      */
     private boolean isAutomotiveProjectionActive() {
@@ -807,7 +805,6 @@
         ipw.println("mIsWifiConnected=" + mIsWifiConnected);
         ipw.println("mIsAlwaysSignalStrengthReportingEnabled="
                 + mIsAlwaysSignalStrengthReportingEnabled);
-        ipw.println("mIsRadioOn=" + mIsRadioOn);
         ipw.println("Local logs:");
         ipw.increaseIndent();
         mLocalLog.dump(fd, ipw, args);
@@ -817,6 +814,115 @@
     }
 
     /**
+     * dBm thresholds that correspond to changes in signal strength indications.
+     */
+    private static final class AccessNetworkThresholds {
+
+        /**
+         * List of dBm thresholds for GERAN {@link AccessNetworkType}.
+         *
+         * Calculated from GSM asu level thresholds - TS 27.007 Sec 8.5
+         */
+        public static final int[] GERAN = new int[] {
+            -109,
+            -103,
+            -97,
+            -89,
+        };
+
+        /**
+         * List of default dBm thresholds for UTRAN {@link AccessNetworkType}.
+         *
+         * These thresholds are taken from the WCDMA RSCP defaults in {@link CarrierConfigManager}.
+         * See TS 27.007 Sec 8.69.
+         */
+        public static final int[] UTRAN = new int[] {
+            -114, /* SIGNAL_STRENGTH_POOR */
+            -104, /* SIGNAL_STRENGTH_MODERATE */
+            -94,  /* SIGNAL_STRENGTH_GOOD */
+            -84   /* SIGNAL_STRENGTH_GREAT */
+        };
+
+        /**
+         * List of default dBm RSRP thresholds for EUTRAN {@link AccessNetworkType}.
+         *
+         * These thresholds are taken from the LTE RSRP defaults in {@link CarrierConfigManager}.
+         */
+        public static final int[] EUTRAN_RSRP = new int[] {
+            -128, /* SIGNAL_STRENGTH_POOR */
+            -118, /* SIGNAL_STRENGTH_MODERATE */
+            -108, /* SIGNAL_STRENGTH_GOOD */
+            -98,  /* SIGNAL_STRENGTH_GREAT */
+        };
+
+        /**
+         * List of default dB RSRQ thresholds for EUTRAN {@link AccessNetworkType}.
+         *
+         * These thresholds are taken from the LTE RSRQ defaults in {@link CarrierConfigManager}.
+         */
+        public static final int[] EUTRAN_RSRQ = new int[] {
+            -20,  /* SIGNAL_STRENGTH_POOR */
+            -17,  /* SIGNAL_STRENGTH_MODERATE */
+            -14,  /* SIGNAL_STRENGTH_GOOD */
+            -11   /* SIGNAL_STRENGTH_GREAT */
+        };
+
+        /**
+         * List of default dB RSSNR thresholds for EUTRAN {@link AccessNetworkType}.
+         *
+         * These thresholds are taken from the LTE RSSNR defaults in {@link CarrierConfigManager}.
+         */
+        public static final int[] EUTRAN_RSSNR = new int[] {
+            -3,  /* SIGNAL_STRENGTH_POOR */
+            1,   /* SIGNAL_STRENGTH_MODERATE */
+            5,   /* SIGNAL_STRENGTH_GOOD */
+            13   /* SIGNAL_STRENGTH_GREAT */
+        };
+
+        /**
+         * List of dBm thresholds for CDMA2000 {@link AccessNetworkType}.
+         *
+         * These correspond to EVDO level thresholds.
+         */
+        public static final int[] CDMA2000 = new int[] {
+            -105,
+            -90,
+            -75,
+            -65
+        };
+
+        /**
+         * List of dB thresholds for NGRAN {@link AccessNetworkType} RSRSRP
+         */
+        public static final int[] NGRAN_RSRSRP = new int[] {
+            -110, /* SIGNAL_STRENGTH_POOR */
+            -90, /* SIGNAL_STRENGTH_MODERATE */
+            -80, /* SIGNAL_STRENGTH_GOOD */
+            -65,  /* SIGNAL_STRENGTH_GREAT */
+        };
+
+        /**
+         * List of dB thresholds for NGRAN {@link AccessNetworkType} RSRSRP
+         */
+        public static final int[] NGRAN_RSRSRQ = new int[] {
+            -31, /* SIGNAL_STRENGTH_POOR */
+            -19, /* SIGNAL_STRENGTH_MODERATE */
+            -7, /* SIGNAL_STRENGTH_GOOD */
+            6  /* SIGNAL_STRENGTH_GREAT */
+        };
+
+        /**
+         * List of dB thresholds for NGRAN {@link AccessNetworkType} SSSINR
+         */
+        public static final int[] NGRAN_SSSINR = new int[] {
+            -5, /* SIGNAL_STRENGTH_POOR */
+            5, /* SIGNAL_STRENGTH_MODERATE */
+            15, /* SIGNAL_STRENGTH_GOOD */
+            30  /* SIGNAL_STRENGTH_GREAT */
+        };
+    }
+
+    /**
      * Downlink reporting thresholds in kbps
      *
      * <p>Threshold values taken from FCC Speed Guide when available
diff --git a/src/java/com/android/internal/telephony/DisplayInfoController.java b/src/java/com/android/internal/telephony/DisplayInfoController.java
index 886a899..eb18693 100644
--- a/src/java/com/android/internal/telephony/DisplayInfoController.java
+++ b/src/java/com/android/internal/telephony/DisplayInfoController.java
@@ -16,27 +16,15 @@
 
 package com.android.internal.telephony;
 
-import android.annotation.NonNull;
 import android.os.Handler;
 import android.os.Registrant;
 import android.os.RegistrantList;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AnomalyReporter;
-import android.telephony.NetworkRegistrationInfo;
 import android.telephony.TelephonyDisplayInfo;
-import android.telephony.TelephonyManager;
-import android.util.IndentingPrintWriter;
-import android.util.LocalLog;
-import android.util.Pair;
 
 import com.android.telephony.Rlog;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.Set;
-import java.util.UUID;
-
-import javax.sip.InvalidArgumentException;
 
 /**
  * The DisplayInfoController updates and broadcasts all changes to {@link TelephonyDisplayInfo}.
@@ -46,26 +34,6 @@
  */
 public class DisplayInfoController extends Handler {
     private static final String TAG = "DisplayInfoController";
-
-    private final String mLogTag;
-    private final LocalLog mLocalLog = new LocalLog(128);
-
-    private static final Set<Pair<Integer, Integer>> VALID_DISPLAY_INFO_SET = Set.of(
-            // LTE
-            Pair.create(TelephonyManager.NETWORK_TYPE_LTE,
-                    TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA),
-            Pair.create(TelephonyManager.NETWORK_TYPE_LTE,
-                    TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO),
-            Pair.create(TelephonyManager.NETWORK_TYPE_LTE,
-                    TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA),
-            Pair.create(TelephonyManager.NETWORK_TYPE_LTE,
-                    TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED),
-
-            // NR
-            Pair.create(TelephonyManager.NETWORK_TYPE_NR,
-                    TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED)
-            );
-
     private final Phone mPhone;
     private final NetworkTypeController mNetworkTypeController;
     private final RegistrantList mTelephonyDisplayInfoChangedRegistrants = new RegistrantList();
@@ -73,7 +41,6 @@
 
     public DisplayInfoController(Phone phone) {
         mPhone = phone;
-        mLogTag = "DIC-" + mPhone.getPhoneId();
         mNetworkTypeController = new NetworkTypeController(phone, this);
         mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
     }
@@ -90,16 +57,12 @@
      * NetworkTypeController.
      */
     public void updateTelephonyDisplayInfo() {
-        NetworkRegistrationInfo nri =  mPhone.getServiceState().getNetworkRegistrationInfo(
-                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        int dataNetworkType = nri == null ? TelephonyManager.NETWORK_TYPE_UNKNOWN
-                : nri.getAccessNetworkTechnology();
-        TelephonyDisplayInfo newDisplayInfo = new TelephonyDisplayInfo(dataNetworkType,
+        TelephonyDisplayInfo newDisplayInfo = new TelephonyDisplayInfo(
+                mPhone.getServiceState().getDataNetworkType(),
                 mNetworkTypeController.getOverrideNetworkType());
         if (!newDisplayInfo.equals(mTelephonyDisplayInfo)) {
-            logl("TelephonyDisplayInfo changed from " + mTelephonyDisplayInfo + " to "
-                    + newDisplayInfo);
-            validateDisplayInfo(newDisplayInfo);
+            Rlog.d(TAG, "TelephonyDisplayInfo[" + mPhone.getPhoneId() + "] changed from "
+                    + mTelephonyDisplayInfo + " to " + newDisplayInfo);
             mTelephonyDisplayInfo = newDisplayInfo;
             mTelephonyDisplayInfoChangedRegistrants.notifyRegistrants();
             mPhone.notifyDisplayInfoChanged(mTelephonyDisplayInfo);
@@ -107,35 +70,11 @@
     }
 
     /**
-     * Validate the display info and trigger anomaly report if needed.
-     *
-     * @param displayInfo The display info to validate.
+     * @return True if either the primary or secondary 5G hysteresis timer is active,
+     * and false if neither are.
      */
-    private void validateDisplayInfo(@NonNull TelephonyDisplayInfo displayInfo) {
-        try {
-            if (displayInfo.getNetworkType() == TelephonyManager.NETWORK_TYPE_LTE_CA) {
-                throw new InvalidArgumentException("LTE_CA is not a valid network type.");
-            }
-            if (displayInfo.getNetworkType() < TelephonyManager.NETWORK_TYPE_UNKNOWN
-                    && displayInfo.getNetworkType() > TelephonyManager.NETWORK_TYPE_NR) {
-                throw new InvalidArgumentException("Invalid network type "
-                        + displayInfo.getNetworkType());
-            }
-            if (displayInfo.getOverrideNetworkType()
-                    != TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE
-                    && !VALID_DISPLAY_INFO_SET.contains(Pair.create(displayInfo.getNetworkType(),
-                    displayInfo.getOverrideNetworkType()))) {
-                throw new InvalidArgumentException("Invalid network type override "
-                        + TelephonyDisplayInfo.overrideNetworkTypeToString(
-                                displayInfo.getOverrideNetworkType())
-                        + " for " + TelephonyManager.getNetworkTypeName(
-                                displayInfo.getNetworkType()));
-            }
-        } catch (InvalidArgumentException e) {
-            logel(e.getMessage());
-            AnomalyReporter.reportAnomaly(UUID.fromString("3aa92a2c-94ed-46a0-a744-d6b1dfec2a55"),
-                    e.getMessage(), mPhone.getCarrierId());
-        }
+    public boolean is5GHysteresisActive() {
+        return mNetworkTypeController.is5GHysteresisActive();
     }
 
     /**
@@ -158,52 +97,13 @@
     }
 
     /**
-     * Log debug messages.
-     * @param s debug messages
-     */
-    private void log(@NonNull String s) {
-        Rlog.d(mLogTag, s);
-    }
-
-    /**
-     * Log error messages.
-     * @param s error messages
-     */
-    private void loge(@NonNull String s) {
-        Rlog.e(mLogTag, s);
-    }
-
-    /**
-     * Log debug messages and also log into the local log.
-     * @param s debug messages
-     */
-    private void logl(@NonNull String s) {
-        log(s);
-        mLocalLog.log(s);
-    }
-
-    /**
-     * Log error messages and also log into the local log.
-     * @param s debug messages
-     */
-    private void logel(@NonNull String s) {
-        loge(s);
-        mLocalLog.log(s);
-    }
-
-    /**
      * Dump the current state.
      */
-    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
-        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
+    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("DisplayInfoController:");
         pw.println(" mPhone=" + mPhone.getPhoneName());
         pw.println(" mTelephonyDisplayInfo=" + mTelephonyDisplayInfo.toString());
         pw.flush();
-        pw.println("Local logs:");
-        pw.increaseIndent();
-        mLocalLog.dump(fd, pw, args);
-        pw.decreaseIndent();
         pw.println(" ***************************************");
         mNetworkTypeController.dump(fd, pw, args);
         pw.flush();
diff --git a/src/java/com/android/internal/telephony/GbaManager.java b/src/java/com/android/internal/telephony/GbaManager.java
index b1db1ac..d6c59ea 100644
--- a/src/java/com/android/internal/telephony/GbaManager.java
+++ b/src/java/com/android/internal/telephony/GbaManager.java
@@ -37,7 +37,6 @@
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.metrics.RcsStats;
 import com.android.telephony.Rlog;
 
 import java.util.concurrent.ConcurrentLinkedQueue;
@@ -61,7 +60,6 @@
     public static final int MAX_RETRY = 5;
     @VisibleForTesting
     public static final int REQUEST_TIMEOUT_MS = 5000;
-    private final RcsStats mRcsStats;
 
     private final String mLogTag;
     private final Context mContext;
@@ -193,8 +191,7 @@
     }
 
     @VisibleForTesting
-    public GbaManager(Context context, int subId, String servicePackageName, int releaseTime,
-            RcsStats rcsStats) {
+    public GbaManager(Context context, int subId, String servicePackageName, int releaseTime) {
         mContext = context;
         mSubId = subId;
         mLogTag = "GbaManager[" + subId + "]";
@@ -209,7 +206,6 @@
         if (mReleaseTime < 0) {
             mHandler.sendEmptyMessage(EVENT_BIND_SERVICE);
         }
-        mRcsStats = rcsStats;
     }
 
     /**
@@ -217,8 +213,7 @@
      */
     public static GbaManager make(Context context, int subId,
             String servicePackageName, int releaseTime) {
-        GbaManager gm = new GbaManager(context, subId, servicePackageName, releaseTime,
-                RcsStats.getInstance());
+        GbaManager gm = new GbaManager(context, subId, servicePackageName, releaseTime);
         synchronized (sGbaManagers) {
             sGbaManagers.put(subId, gm);
         }
@@ -272,7 +267,6 @@
                     if (cb != null) {
                         try {
                             cb.onKeysAvailable(token, gbaKey, btId);
-                            mRcsStats.onGbaSuccessEvent(mSubId);
                         } catch (RemoteException exception) {
                             logd("RemoteException " + exception);
                         }
@@ -297,7 +291,6 @@
                     if (cb != null) {
                         try {
                             cb.onAuthenticationFailure(token, reason);
-                            mRcsStats.onGbaFailureEvent(mSubId, reason);
                         } catch (RemoteException exception) {
                             logd("RemoteException " + exception);
                         }
diff --git a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
index 3293558..4d9d8d7 100755
--- a/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
@@ -183,9 +183,7 @@
             // Prior to phone switch to GSM, if CDMA has any emergency call
             // data will be in disabled state, after switching to GSM enable data.
             if (mIsInEmergencyCall) {
-                if (!mPhone.isUsingNewDataStack()) {
-                    mPhone.getDataEnabledSettings().setInternalDataEnabled(true);
-                }
+                mPhone.getDataEnabledSettings().setInternalDataEnabled(true);
             }
         } else {
             mConnections = new GsmCdmaConnection[MAX_CONNECTIONS_CDMA];
@@ -400,9 +398,7 @@
     //CDMA
     public void setIsInEmergencyCall() {
         mIsInEmergencyCall = true;
-        if (!mPhone.isUsingNewDataStack()) {
-            mPhone.getDataEnabledSettings().setInternalDataEnabled(false);
-        }
+        mPhone.getDataEnabledSettings().setInternalDataEnabled(false);
         mPhone.notifyEmergencyCallRegistrants(true);
         mPhone.sendEmergencyCallStateChange(true);
     }
@@ -1754,9 +1750,7 @@
             }
             if (!inEcm) {
                 // Re-initiate data connection
-                if (!mPhone.isUsingNewDataStack()) {
-                    mPhone.getDataEnabledSettings().setInternalDataEnabled(true);
-                }
+                mPhone.getDataEnabledSettings().setInternalDataEnabled(true);
                 mPhone.notifyEmergencyCallRegistrants(false);
             }
             mPhone.sendEmergencyCallStateChange(false);
diff --git a/src/java/com/android/internal/telephony/GsmCdmaPhone.java b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
index ff8412f..a034392 100644
--- a/src/java/com/android/internal/telephony/GsmCdmaPhone.java
+++ b/src/java/com/android/internal/telephony/GsmCdmaPhone.java
@@ -15,7 +15,6 @@
  */
 
 package com.android.internal.telephony;
-
 import static com.android.internal.telephony.CommandException.Error.GENERIC_FAILURE;
 import static com.android.internal.telephony.CommandException.Error.SIM_BUSY;
 import static com.android.internal.telephony.CommandsInterface.CF_ACTION_DISABLE;
@@ -45,8 +44,6 @@
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.HandlerExecutor;
-import android.os.Looper;
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.PowerManager;
@@ -65,7 +62,6 @@
 import android.telecom.TelecomManager;
 import android.telecom.VideoProfile;
 import android.telephony.AccessNetworkConstants;
-import android.telephony.Annotation.DataActivityType;
 import android.telephony.Annotation.RadioPowerState;
 import android.telephony.BarringInfo;
 import android.telephony.CarrierConfigManager;
@@ -77,6 +73,7 @@
 import android.telephony.RadioAccessFamily;
 import android.telephony.ServiceState;
 import android.telephony.ServiceState.RilRadioTechnology;
+import android.telephony.SignalThresholdInfo;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -91,11 +88,9 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.cdma.CdmaMmiCode;
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
-import com.android.internal.telephony.data.AccessNetworksManager;
-import com.android.internal.telephony.data.DataNetworkController;
-import com.android.internal.telephony.data.LinkBandwidthEstimator;
 import com.android.internal.telephony.dataconnection.DataEnabledSettings;
 import com.android.internal.telephony.dataconnection.DcTracker;
+import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator;
 import com.android.internal.telephony.dataconnection.TransportManager;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.gsm.GsmMmiCode;
@@ -116,9 +111,9 @@
 import com.android.internal.telephony.uicc.IsimUiccRecords;
 import com.android.internal.telephony.uicc.RuimRecords;
 import com.android.internal.telephony.uicc.SIMRecords;
+import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccCardApplication;
 import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UiccProfile;
 import com.android.internal.telephony.uicc.UiccSlot;
 import com.android.internal.telephony.util.ArrayUtils;
@@ -146,9 +141,11 @@
     private static final boolean DBG = true;
     private static final boolean VDBG = false; /* STOPSHIP if true */
 
+    /** Required magnitude change between unsolicited SignalStrength reports. */
+    private static final int REPORTING_HYSTERESIS_DB = 2;
     /** Required throughput change between unsolicited LinkCapacityEstimate reports. */
     private static final int REPORTING_HYSTERESIS_KBPS = 50;
-    /** Minimum time between unsolicited LinkCapacityEstimate reports. */
+    /** Minimum time between unsolicited SignalStrength and LinkCapacityEstimate reports. */
     private static final int REPORTING_HYSTERESIS_MILLIS = 3000;
 
     //GSM
@@ -265,18 +262,12 @@
 
     private int mRilVersion;
     private boolean mBroadcastEmergencyCallStateChanges = false;
-    private @ServiceState.RegState int mTelecomVoiceServiceStateOverride =
-            ServiceState.STATE_OUT_OF_SERVICE;
-
     private CarrierKeyDownloadManager mCDM;
     private CarrierInfoManager mCIM;
 
     private final SettingsObserver mSettingsObserver;
 
     private final ImsManagerFactory mImsManagerFactory;
-    private final CarrierPrivilegesTracker mCarrierPrivilegesTracker;
-
-    private final SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionsChangedListener;
 
     // Constructors
 
@@ -313,25 +304,15 @@
                 .makeCarrierActionAgent(this);
         mCarrierSignalAgent = mTelephonyComponentFactory.inject(CarrierSignalAgent.class.getName())
                 .makeCarrierSignalAgent(this);
-        mAccessNetworksManager = mTelephonyComponentFactory
-                .inject(AccessNetworksManager.class.getName())
-                .makeAccessNetworksManager(this, getLooper());
-        if (!isUsingNewDataStack()) {
-            mTransportManager = mTelephonyComponentFactory.inject(TransportManager.class.getName())
-                    .makeTransportManager(this);
-        }
-        // SST/DSM depends on SSC, so SSC is instanced before SST/DSM
-        mSignalStrengthController = mTelephonyComponentFactory.inject(
-                SignalStrengthController.class.getName()).makeSignalStrengthController(this);
+        mTransportManager = mTelephonyComponentFactory.inject(TransportManager.class.getName())
+                .makeTransportManager(this);
         mSST = mTelephonyComponentFactory.inject(ServiceStateTracker.class.getName())
                 .makeServiceStateTracker(this, this.mCi);
         mEmergencyNumberTracker = mTelephonyComponentFactory
                 .inject(EmergencyNumberTracker.class.getName()).makeEmergencyNumberTracker(
                         this, this.mCi);
-        if (!isUsingNewDataStack()) {
-            mDataEnabledSettings = mTelephonyComponentFactory
-                    .inject(DataEnabledSettings.class.getName()).makeDataEnabledSettings(this);
-        }
+        mDataEnabledSettings = mTelephonyComponentFactory
+                .inject(DataEnabledSettings.class.getName()).makeDataEnabledSettings(this);
         mDeviceStateMonitor = mTelephonyComponentFactory.inject(DeviceStateMonitor.class.getName())
                 .makeDeviceStateMonitor(this);
 
@@ -340,24 +321,17 @@
         mDisplayInfoController = mTelephonyComponentFactory.inject(
                 DisplayInfoController.class.getName()).makeDisplayInfoController(this);
 
-        if (isUsingNewDataStack()) {
-            mDataNetworkController = mTelephonyComponentFactory.inject(
-                    DataNetworkController.class.getName())
-                    .makeDataNetworkController(this, getLooper());
-        } else {
-            // DcTracker uses ServiceStateTracker and DisplayInfoController so needs to be created
-            // after they are instantiated
-            for (int transport : mAccessNetworksManager.getAvailableTransports()) {
-                DcTracker dcTracker = mTelephonyComponentFactory.inject(DcTracker.class.getName())
-                        .makeDcTracker(this, transport);
-                mDcTrackers.put(transport, dcTracker);
-                mAccessNetworksManager.registerDataThrottler(dcTracker.getDataThrottler());
-            }
+        // DcTracker uses ServiceStateTracker and DisplayInfoController so needs to be created
+        // after they are instantiated
+        for (int transport : mTransportManager.getAvailableTransports()) {
+            DcTracker dcTracker = mTelephonyComponentFactory.inject(DcTracker.class.getName())
+                    .makeDcTracker(this, transport);
+            mDcTrackers.put(transport, dcTracker);
+            mTransportManager.registerDataThrottler(dcTracker.getDataThrottler());
         }
 
         mCarrierResolver = mTelephonyComponentFactory.inject(CarrierResolver.class.getName())
                 .makeCarrierResolver(this);
-        mCarrierPrivilegesTracker = new CarrierPrivilegesTracker(Looper.myLooper(), this, context);
 
         getCarrierActionAgent().registerForCarrierAction(
                 CarrierActionAgent.CARRIER_ACTION_SET_METERED_APNS_ENABLED, this,
@@ -366,7 +340,6 @@
         mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null);
         mSST.registerForVoiceRegStateOrRatChanged(this, EVENT_VRS_OR_RAT_CHANGED, null);
 
-        // TODO: Remove SettingsObserver and provisioning events when DataEnabledSettings is removed
         mSettingsObserver = new SettingsObserver(context, this);
         mSettingsObserver.observe(
                 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
@@ -385,19 +358,6 @@
         loadTtyMode();
 
         CallManager.getInstance().registerPhone(this);
-
-        mSubscriptionsChangedListener =
-                new SubscriptionManager.OnSubscriptionsChangedListener() {
-            @Override
-            public void onSubscriptionsChanged() {
-                sendEmptyMessage(EVENT_SUBSCRIPTIONS_CHANGED);
-            }
-        };
-
-        SubscriptionManager subMan = context.getSystemService(SubscriptionManager.class);
-        subMan.addOnSubscriptionsChangedListener(
-                new HandlerExecutor(this), mSubscriptionsChangedListener);
-
         logd("GsmCdmaPhone: constructor: sub = " + mPhoneId);
     }
 
@@ -479,8 +439,7 @@
                 CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED);
         filter.addAction(TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
-        mContext.registerReceiver(mBroadcastReceiver, filter,
-                android.Manifest.permission.MODIFY_PHONE_STATE, null, Context.RECEIVER_EXPORTED);
+        mContext.registerReceiver(mBroadcastReceiver, filter);
 
         mCDM = new CarrierKeyDownloadManager(this);
         mCIM = new CarrierInfoManager();
@@ -619,19 +578,18 @@
     @Override
     @NonNull
     public ServiceState getServiceState() {
-        ServiceState baseSs = mSST != null ? mSST.getServiceState() : new ServiceState();
-        ServiceState imsSs = mImsPhone != null ? mImsPhone.getServiceState() : new ServiceState();
-        return mergeVoiceServiceStates(baseSs, imsSs, mTelecomVoiceServiceStateOverride);
-    }
+        if (mSST == null || mSST.mSS.getState() != ServiceState.STATE_IN_SERVICE) {
+            if (mImsPhone != null) {
+                return mergeServiceStates((mSST == null) ? new ServiceState() : mSST.mSS,
+                        mImsPhone.getServiceState());
+            }
+        }
 
-    @Override
-    public void setVoiceServiceStateOverride(boolean hasService) {
-        int newOverride =
-                hasService ? ServiceState.STATE_IN_SERVICE : ServiceState.STATE_OUT_OF_SERVICE;
-        boolean changed = newOverride != mTelecomVoiceServiceStateOverride;
-        mTelecomVoiceServiceStateOverride = newOverride;
-        if (changed && mSST != null) {
-            mSST.onTelecomVoiceServiceStateOverrideChanged();
+        if (mSST != null) {
+            return mSST.mSS;
+        } else {
+            // avoid potential NPE in EmergencyCallHelper during Phone switch
+            return new ServiceState();
         }
     }
 
@@ -685,11 +643,6 @@
     }
 
     @Override
-    public AccessNetworksManager getAccessNetworksManager() {
-        return mAccessNetworksManager;
-    }
-
-    @Override
     public DeviceStateMonitor getDeviceStateMonitor() {
         return mDeviceStateMonitor;
     }
@@ -700,11 +653,6 @@
     }
 
     @Override
-    public SignalStrengthController getSignalStrengthController() {
-        return mSignalStrengthController;
-    }
-
-    @Override
     public void updateVoiceMail() {
         if (isPhoneTypeGsm()) {
             int countVoiceMessages = 0;
@@ -730,6 +678,12 @@
         return mPendingMMIs;
     }
 
+    private @NonNull DcTracker getActiveDcTrackerForApn(@NonNull String apnType) {
+        int currentTransport = mTransportManager.getCurrentTransport(
+                ApnSetting.getApnTypesBitmaskFromString(apnType));
+        return getDcTracker(currentTransport);
+    }
+
     @Override
     public boolean isDataSuspended() {
         return mCT.mState != PhoneConstants.State.IDLE && !mSST.isConcurrentVoiceAndDataAllowed();
@@ -755,7 +709,7 @@
 
             ret = PhoneConstants.DataState.DISCONNECTED;
         } else { /* mSST.gprsState == ServiceState.STATE_IN_SERVICE */
-            int currentTransport = mAccessNetworksManager.getCurrentTransport(
+            int currentTransport = mTransportManager.getCurrentTransport(
                     ApnSetting.getApnTypesBitmaskFromString(apnType));
             if (getDcTracker(currentTransport) != null) {
                 switch (getDcTracker(currentTransport).getState(apnType)) {
@@ -781,33 +735,30 @@
     }
 
     @Override
-    public @DataActivityType int getDataActivityState() {
-        if (isUsingNewDataStack()) {
-            return getDataNetworkController().getDataActivity();
-        }
-        int ret = TelephonyManager.DATA_ACTIVITY_NONE;
+    public DataActivityState getDataActivityState() {
+        DataActivityState ret = DataActivityState.NONE;
 
         if (mSST.getCurrentDataConnectionState() == ServiceState.STATE_IN_SERVICE
                 && getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
             switch (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).getActivity()) {
                 case DATAIN:
-                    ret = TelephonyManager.DATA_ACTIVITY_IN;
+                    ret = DataActivityState.DATAIN;
                 break;
 
                 case DATAOUT:
-                    ret = TelephonyManager.DATA_ACTIVITY_OUT;
+                    ret = DataActivityState.DATAOUT;
                 break;
 
                 case DATAINANDOUT:
-                    ret = TelephonyManager.DATA_ACTIVITY_INOUT;
+                    ret = DataActivityState.DATAINANDOUT;
                 break;
 
                 case DORMANT:
-                    ret = TelephonyManager.DATA_ACTIVITY_DORMANT;
+                    ret = DataActivityState.DORMANT;
                 break;
 
                 default:
-                    ret = TelephonyManager.DATA_ACTIVITY_NONE;
+                    ret = DataActivityState.NONE;
                 break;
             }
         }
@@ -1105,55 +1056,29 @@
         return mCT.mRingingCall;
     }
 
-    @Override
-    @NonNull
-    public CarrierPrivilegesTracker getCarrierPrivilegesTracker() {
-        return mCarrierPrivilegesTracker;
-    }
-
     /**
-     * Amends {@code baseSs} if its voice registration state is {@code OUT_OF_SERVICE}.
-     *
-     * <p>Even if the device has lost the CS link to the tower, there are two potential additional
-     * sources of voice capability not directly saved inside ServiceStateTracker:
-     *
-     * <ul>
-     *   <li>IMS voice registration state ({@code imsSs}) - if this is {@code IN_SERVICE} for voice,
-     *       we substite {@code baseSs#getDataRegState} as the final voice service state (ImsService
-     *       reports {@code IN_SERVICE} for its voice registration state even if the device has lost
-     *       the physical link to the tower)
-     *   <li>OTT voice capability provided through telecom ({@code telecomSs}) - if this is {@code
-     *       IN_SERVICE}, we directly substitute it as the final voice service state
-     * </ul>
+     * ImsService reports "IN_SERVICE" for its voice registration state even if the device
+     * has lost the physical link to the tower. This helper method merges the IMS and modem
+     * ServiceState, only overriding the voice registration state when we are registered to IMS. In
+     * this case the voice registration state may be "OUT_OF_SERVICE", so override the voice
+     * registration state with the data registration state.
      */
-    private static ServiceState mergeVoiceServiceStates(
-            ServiceState baseSs, ServiceState imsSs, @ServiceState.RegState int telecomSs) {
+    private ServiceState mergeServiceStates(ServiceState baseSs, ServiceState imsSs) {
+        // No need to merge states if the baseSs is IN_SERVICE.
         if (baseSs.getState() == ServiceState.STATE_IN_SERVICE) {
-            // No need to merge states if the baseSs is IN_SERVICE.
             return baseSs;
         }
-        // If any of the following additional sources are IN_SERVICE, we use that since voice calls
-        // can be routed through something other than the CS link.
-        @ServiceState.RegState int finalVoiceSs = ServiceState.STATE_OUT_OF_SERVICE;
-        if (telecomSs == ServiceState.STATE_IN_SERVICE) {
-            // If telecom reports there's a PhoneAccount that can provide voice service
-            // (CAPABILITY_VOICE_CALLING_AVAILABLE), then we trust that info as it may account for
-            // external possibilities like wi-fi calling provided by the SIM call manager app. Note
-            // that CAPABILITY_PLACE_EMERGENCY_CALLS is handled separately.
-            finalVoiceSs = telecomSs;
-        } else if (imsSs.getState() == ServiceState.STATE_IN_SERVICE) {
-            // Voice override for IMS case. In this case, voice registration is OUT_OF_SERVICE, but
-            // IMS is available, so use data registration state as a basis for determining
-            // whether or not the physical link is available.
-            finalVoiceSs = baseSs.getDataRegistrationState();
-        }
-        if (finalVoiceSs != ServiceState.STATE_IN_SERVICE) {
-            // None of the additional sources provide a usable route, and they only use IN/OUT.
+        // "IN_SERVICE" in this case means IMS is registered.
+        if (imsSs.getState() != ServiceState.STATE_IN_SERVICE) {
             return baseSs;
         }
+
         ServiceState newSs = new ServiceState(baseSs);
-        newSs.setVoiceRegState(finalVoiceSs);
-        newSs.setEmergencyOnly(false); // Must be IN_SERVICE if we're here
+        // Voice override for IMS case. In this case, voice registration is OUT_OF_SERVICE, but
+        // IMS is available, so use data registration state as a basis for determining
+        // whether or not the physical link is available.
+        newSs.setVoiceRegState(baseSs.getDataRegistrationState());
+        newSs.setEmergencyOnly(false); // only get here if voice is IN_SERVICE
         return newSs;
     }
 
@@ -1415,35 +1340,8 @@
                     + possibleEmergencyNumber);
             dialString = possibleEmergencyNumber;
         }
-
-        CarrierConfigManager configManager =
-                (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        PersistableBundle carrierConfig = configManager.getConfigForSubId(getSubId());
-        boolean allowWpsOverIms = carrierConfig.getBoolean(
-                CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL);
-        boolean useOnlyDialedSimEccList = carrierConfig.getBoolean(
-                CarrierConfigManager.KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL);
-
-
         TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
-        boolean isEmergency;
-        // Check if the carrier wants to treat a call as an emergency call based on its own list of
-        // known emergency numbers.
-        // useOnlyDialedSimEccList is false for the vast majority of carriers.  There are, however,
-        // some carriers which do not want to handle dial requests for numbers which are in the
-        // emergency number list on another SIM, but is not on theirs.  In this case we will use the
-        // emergency number list for this carrier's SIM only.
-        if (useOnlyDialedSimEccList) {
-            isEmergency = getEmergencyNumberTracker().isEmergencyNumber(dialString,
-                    true /* exactMatch */);
-            logi("dial; isEmergency=" + isEmergency
-                    + " (based on this phone only); globalIsEmergency="
-                    + tm.isEmergencyNumber(dialString));
-        } else {
-            isEmergency = tm.isEmergencyNumber(dialString);
-            logi("dial; isEmergency=" + isEmergency + " (based on all phones)");
-        }
-
+        boolean isEmergency = tm.isEmergencyNumber(dialString);
         /** Check if the call is Wireless Priority Service call */
         boolean isWpsCall = dialString != null ? (dialString.startsWith(PREFIX_WPS)
                 || dialString.startsWith(PREFIX_WPS_CLIR_ACTIVATE)
@@ -1457,6 +1355,12 @@
 
         Phone imsPhone = mImsPhone;
 
+        CarrierConfigManager configManager =
+                (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+
+        boolean allowWpsOverIms = configManager.getConfigForSubId(getSubId())
+                .getBoolean(CarrierConfigManager.KEY_SUPPORT_WPS_OVER_IMS_BOOL);
+
         boolean useImsForEmergency = isEmergency && useImsForEmergency();
 
         String dialPart = PhoneNumberUtils.extractNetworkPortionAlt(PhoneNumberUtils.
@@ -1470,8 +1374,7 @@
                 && (isWpsCall ? allowWpsOverIms : true);
 
         if (DBG) {
-            logi("useImsForCall=" + useImsForCall
-                    + ", useOnlyDialedSimEccList=" + useOnlyDialedSimEccList
+            logd("useImsForCall=" + useImsForCall
                     + ", isEmergency=" + isEmergency
                     + ", useImsForEmergency=" + useImsForEmergency
                     + ", useImsForUt=" + useImsForUt
@@ -1990,12 +1893,10 @@
 
     @Override
     public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int keyType, boolean fallback) {
-        final TelephonyManager telephonyManager = mContext.getSystemService(TelephonyManager.class)
-                .createForSubscriptionId(getSubId());
-        String operatorNumeric = telephonyManager.getSimOperator();
-        int carrierId = telephonyManager.getSimCarrierId();
+        String operatorNumeric = TelephonyManager.from(mContext)
+                .getSimOperatorNumericForPhone(mPhoneId);
         return CarrierInfoManager.getCarrierInfoForImsiEncryption(keyType,
-                mContext, operatorNumeric, carrierId, fallback, getSubId());
+                mContext, operatorNumeric, fallback, getSubId());
     }
 
     @Override
@@ -2005,9 +1906,8 @@
     }
 
     @Override
-    public void deleteCarrierInfoForImsiEncryption(int carrierId) {
-        CarrierInfoManager.deleteCarrierInfoForImsiEncryption(mContext, getSubId(),
-                carrierId);
+    public void deleteCarrierInfoForImsiEncryption() {
+        CarrierInfoManager.deleteCarrierInfoForImsiEncryption(mContext, getSubId());
     }
 
     @Override
@@ -2672,9 +2572,6 @@
 
     @Override
     public boolean getDataRoamingEnabled() {
-        if (isUsingNewDataStack()) {
-            return getDataSettingsManager().isDataRoamingEnabled();
-        }
         if (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
             return getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).getDataRoamingEnabled();
         }
@@ -2683,10 +2580,6 @@
 
     @Override
     public void setDataRoamingEnabled(boolean enable) {
-        if (isUsingNewDataStack()) {
-            getDataSettingsManager().setDataRoamingEnabled(enable);
-            return;
-        }
         if (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
             getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                     .setDataRoamingEnabledByUser(enable);
@@ -2741,10 +2634,6 @@
      */
     @Override
     public boolean isUserDataEnabled() {
-        if (isUsingNewDataStack()) {
-            return getDataSettingsManager().isDataEnabledForReason(
-                    TelephonyManager.DATA_ENABLED_REASON_USER);
-        }
         if (mDataEnabledSettings.isProvisioning()) {
             return mDataEnabledSettings.isProvisioningDataEnabled();
         } else {
@@ -2916,6 +2805,10 @@
         if (!isPhoneTypeGsm()) {
             mCdmaSubscriptionSource = mCdmaSSM.getCdmaSubscriptionSource();
         }
+
+        // If this is on APM off, SIM may already be loaded. Send setPreferredNetworkType
+        // request to RIL to preserve user setting across APM toggling
+        setPreferredNetworkTypeIfSimLoaded();
     }
 
     private void handleRadioOffOrNotAvailable() {
@@ -3065,7 +2958,6 @@
                 updateCdmaRoamingSettingsAfterCarrierConfigChanged(b);
 
                 updateNrSettingsAfterCarrierConfigChanged(b);
-                updateVoNrSettings(b);
                 updateSsOverCdmaSupported(b);
                 loadAllowedNetworksFromSubscriptionDatabase();
                 // Obtain new radio capabilities from the modem, since some are SIM-dependent
@@ -3131,6 +3023,26 @@
                 }
             break;
 
+            case EVENT_GET_IMEI_DONE:
+                ar = (AsyncResult)msg.obj;
+
+                if (ar.exception != null) {
+                    break;
+                }
+
+                mImei = (String)ar.result;
+            break;
+
+            case EVENT_GET_IMEISV_DONE:
+                ar = (AsyncResult)msg.obj;
+
+                if (ar.exception != null) {
+                    break;
+                }
+
+                mImeiSv = (String)ar.result;
+            break;
+
             case EVENT_USSD:
                 ar = (AsyncResult)msg.obj;
 
@@ -3283,24 +3195,14 @@
             case EVENT_SET_CARRIER_DATA_ENABLED:
                 ar = (AsyncResult) msg.obj;
                 boolean enabled = (boolean) ar.result;
-                if (isUsingNewDataStack()) {
-                    getDataSettingsManager().setDataEnabled(
-                            TelephonyManager.DATA_ENABLED_REASON_CARRIER, enabled,
-                            mContext.getOpPackageName());
-                    return;
-                }
                 mDataEnabledSettings.setDataEnabled(TelephonyManager.DATA_ENABLED_REASON_CARRIER,
                         enabled);
                 break;
             case EVENT_DEVICE_PROVISIONED_CHANGE:
-                if (!isUsingNewDataStack()) {
-                    mDataEnabledSettings.updateProvisionedChanged();
-                }
+                mDataEnabledSettings.updateProvisionedChanged();
                 break;
             case EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE:
-                if (!isUsingNewDataStack()) {
-                    mDataEnabledSettings.updateProvisioningDataEnabled();
-                }
+                mDataEnabledSettings.updateProvisioningDataEnabled();
                 break;
             case EVENT_GET_AVAILABLE_NETWORKS_DONE:
                 ar = (AsyncResult) msg.obj;
@@ -3368,14 +3270,6 @@
                 resetCarrierKeysForImsiEncryption();
                 break;
             }
-            case EVENT_SET_VONR_ENABLED_DONE:
-                logd("EVENT_SET_VONR_ENABLED_DONE is done");
-                break;
-            case EVENT_SUBSCRIPTIONS_CHANGED:
-                logd("EVENT_SUBSCRIPTIONS_CHANGED");
-                updateUsageSetting();
-                break;
-
             default:
                 super.handleMessage(msg);
         }
@@ -3796,9 +3690,7 @@
             // send an Intent
             sendEmergencyCallbackModeChange();
             // Re-initiate data connection
-            if (!isUsingNewDataStack()) {
-                mDataEnabledSettings.setInternalDataEnabled(true);
-            }
+            mDataEnabledSettings.setInternalDataEnabled(true);
             notifyEmergencyCallRegistrants(false);
         }
         mIsTestingEmergencyCallbackMode = false;
@@ -4210,6 +4102,32 @@
     }
 
     @Override
+    public void setSignalStrengthReportingCriteria(int signalStrengthMeasure,
+            int[] systemThresholds, int ran, boolean isEnabledForSystem) {
+        int[] consolidatedThresholds = mSST.getConsolidatedSignalThresholds(
+                ran,
+                signalStrengthMeasure,
+                isEnabledForSystem && mSST.shouldHonorSystemThresholds() ? systemThresholds
+                        : new int[]{},
+                REPORTING_HYSTERESIS_DB);
+        boolean isEnabledForAppRequest = mSST.shouldEnableSignalThresholdForAppRequest(
+                ran,
+                signalStrengthMeasure,
+                getSubId(),
+                isDeviceIdle());
+        mCi.setSignalStrengthReportingCriteria(
+                new SignalThresholdInfo.Builder()
+                        .setRadioAccessNetworkType(ran)
+                        .setSignalMeasurementType(signalStrengthMeasure)
+                        .setHysteresisMs(REPORTING_HYSTERESIS_MILLIS)
+                        .setHysteresisDb(REPORTING_HYSTERESIS_DB)
+                        .setThresholds(consolidatedThresholds, true /*isSystem*/)
+                        .setIsEnabled(isEnabledForSystem || isEnabledForAppRequest)
+                        .build(),
+                ran, null);
+    }
+
+    @Override
     public void setLinkCapacityReportingCriteria(int[] dlThresholds, int[] ulThresholds, int ran) {
         mCi.setLinkCapacityReportingCriteria(REPORTING_HYSTERESIS_MILLIS, REPORTING_HYSTERESIS_KBPS,
                 REPORTING_HYSTERESIS_KBPS, dlThresholds, ulThresholds, ran, null);
@@ -4286,10 +4204,6 @@
         }
         pw.println(" isCspPlmnEnabled()=" + isCspPlmnEnabled());
         pw.println(" mManualNetworkSelectionPlmn=" + mManualNetworkSelectionPlmn);
-        pw.println(
-                " mTelecomVoiceServiceStateOverride=" + mTelecomVoiceServiceStateOverride + "("
-                        + ServiceState.rilServiceStateToString(mTelecomVoiceServiceStateOverride)
-                        + ")");
         pw.flush();
     }
 
@@ -4299,12 +4213,12 @@
             return false;
         }
 
-        UiccPort port = mUiccController.getUiccPort(getPhoneId());
-        if (port == null) {
+        UiccCard card = mUiccController.getUiccCard(getPhoneId());
+        if (card == null) {
             return false;
         }
 
-        boolean status = port.setOperatorBrandOverride(brand);
+        boolean status = card.setOperatorBrandOverride(brand);
 
         // Refresh.
         if (status) {
@@ -4678,14 +4592,8 @@
             return;
         }
 
-        // Due to timing issue, sometimes UiccPort is coming null, so don't use UiccPort object
-        // to retrieve the iccId here. Instead, depend on the UiccSlot API.
-        String iccId = slot.getIccId(slot.getPortIndexFromPhoneId(mPhoneId));
-        if (iccId == null) {
-            loge("reapplyUiccAppsEnablementIfNeeded iccId is null, phoneId: " + mPhoneId
-                    + " portIndex: " + slot.getPortIndexFromPhoneId(mPhoneId));
-            return;
-        }
+        String iccId = slot.getIccId();
+        if (iccId == null) return;
 
         SubscriptionInfo info = SubscriptionController.getInstance().getSubInfoForIccId(
                 IccUtils.stripTrailingFs(iccId));
@@ -4745,9 +4653,6 @@
      * @return Currently bound data service package names.
      */
     public @NonNull List<String> getDataServicePackages() {
-        if (isUsingNewDataStack()) {
-            return getDataNetworkController().getDataServicePackages();
-        }
         List<String> packages = new ArrayList<>();
         int[] transports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 AccessNetworkConstants.TRANSPORT_TYPE_WLAN};
@@ -4789,45 +4694,6 @@
         mIsCarrierNrSupported = !ArrayUtils.isEmpty(nrAvailabilities);
     }
 
-    private void updateVoNrSettings(PersistableBundle config) {
-        UiccSlot slot = mUiccController.getUiccSlotForPhone(mPhoneId);
-
-        // If no card is present, do nothing.
-        if (slot == null || slot.getCardState() != IccCardStatus.CardState.CARDSTATE_PRESENT) {
-            return;
-        }
-
-        if (config == null) {
-            loge("didn't get the vonr_enabled_bool from the carrier config.");
-            return;
-        }
-
-        boolean mIsVonrEnabledByCarrier =
-                config.getBoolean(CarrierConfigManager.KEY_VONR_ENABLED_BOOL);
-
-        String result = SubscriptionController.getInstance().getSubscriptionProperty(
-                getSubId(),
-                SubscriptionManager.NR_ADVANCED_CALLING_ENABLED);
-
-        int setting = -1;
-        if (result != null) {
-            setting = Integer.parseInt(result);
-        }
-
-        logd("VoNR setting from telephony.db:"
-                + setting
-                + " ,vonr_enabled_bool:"
-                + mIsVonrEnabledByCarrier);
-
-        if (!mIsVonrEnabledByCarrier) {
-            mCi.setVoNrEnabled(false, obtainMessage(EVENT_SET_VONR_ENABLED_DONE), null);
-        } else if (setting == 1 || setting == -1) {
-            mCi.setVoNrEnabled(true, obtainMessage(EVENT_SET_VONR_ENABLED_DONE), null);
-        } else if (setting == 0) {
-            mCi.setVoNrEnabled(false, obtainMessage(EVENT_SET_VONR_ENABLED_DONE), null);
-        }
-    }
-
     private void updateCdmaRoamingSettingsAfterCarrierConfigChanged(PersistableBundle config) {
         if (config == null) {
             loge("didn't get the cdma_roaming_mode changes from the carrier config.");
diff --git a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
index 742cc90..c6c3d6a 100644
--- a/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccPhoneBookInterfaceManager.java
@@ -166,6 +166,10 @@
         return new AdnRecord(oldTag, oldPhoneNumber, oldEmailArray, oldAnrArray);
     }
 
+    private AdnRecord generateAdnRecordWithNewTagByContentValues(ContentValues values) {
+        return generateAdnRecordWithNewTagByContentValues(0, 0, values);
+    }
+
     private AdnRecord generateAdnRecordWithNewTagByContentValues(
             int efId, int recordNumber, ContentValues values) {
         if (values == null) {
@@ -215,14 +219,12 @@
         synchronized (updateRequest) {
             Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, updateRequest);
             AdnRecord oldAdn = generateAdnRecordWithOldTagByContentValues(values);
+            AdnRecord newAdn = generateAdnRecordWithNewTagByContentValues(values);
             if (usesPbCache(efid)) {
-                AdnRecord newAdn =
-                        generateAdnRecordWithNewTagByContentValues(IccConstants.EF_ADN, 0, values);
                 mSimPbRecordCache.updateSimPbAdnBySearch(oldAdn, newAdn, response);
                 waitForResult(updateRequest);
                 return (boolean) updateRequest.mResult;
             } else {
-                AdnRecord newAdn = generateAdnRecordWithNewTagByContentValues(efid, 0, values);
                 if (mAdnCache != null) {
                     mAdnCache.updateAdnBySearch(efid, oldAdn, newAdn, pin2, response);
                     waitForResult(updateRequest);
@@ -270,15 +272,12 @@
         Request updateRequest = new Request();
         synchronized (updateRequest) {
             Message response = mBaseHandler.obtainMessage(EVENT_UPDATE_DONE, updateRequest);
+            AdnRecord newAdn = generateAdnRecordWithNewTagByContentValues(efid, index, values);
             if (usesPbCache(efid)) {
-                AdnRecord newAdn =
-                        generateAdnRecordWithNewTagByContentValues(IccConstants.EF_ADN,
-                        index, values);
                 mSimPbRecordCache.updateSimPbAdnByRecordId(index, newAdn, response);
                 waitForResult(updateRequest);
                 return (boolean) updateRequest.mResult;
             } else {
-                AdnRecord newAdn = generateAdnRecordWithNewTagByContentValues(efid, index, values);
                 if (mAdnCache != null) {
                     mAdnCache.updateAdnByIndex(efid, newAdn, index, pin2, response);
                     waitForResult(updateRequest);
diff --git a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index a329771..982c2a2 100644
--- a/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/src/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -98,7 +98,7 @@
     public SmsDispatchersController mDispatchersController;
     private SmsPermissions mSmsPermissions;
 
-    private final LocalLog mCellBroadcastLocalLog = new LocalLog(64);
+    private final LocalLog mCellBroadcastLocalLog = new LocalLog(100);
 
     private static final class Request {
         AtomicBoolean mStatus = new AtomicBoolean(false);
@@ -597,8 +597,8 @@
             String destAddr, String scAddr, String text, PendingIntent sentIntent,
             PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp, int priority,
             boolean expectMore, int validityPeriod) {
-        if (!mSmsPermissions.checkCallingCanSendText(persistMessageForNonDefaultSmsApp,
-                    callingPackage, callingAttributionTag, "Sending SMS message")) {
+        if (!mSmsPermissions.checkCallingOrSelfCanSendSms(callingPackage, callingAttributionTag,
+                "Sending SMS message")) {
             returnUnspecifiedFailure(sentIntent);
             return;
         }
diff --git a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
index 42fe7a7..eb96af2 100644
--- a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
+++ b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.os.Binder;
-import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.provider.Telephony.Sms.Intents;
@@ -170,18 +169,10 @@
                         mTrackers.remove(token);
                         break;
                     case ImsSmsImplBase.SEND_STATUS_ERROR_RETRY:
-                        if (tracker.mRetryCount < MAX_SEND_RETRIES) {
-                            tracker.mRetryCount += 1;
-                            sendMessageDelayed(
-                                    obtainMessage(EVENT_SEND_RETRY, tracker), SEND_RETRY_DELAY);
-                        } else {
-                            tracker.onFailed(mContext, reason, networkReasonCode);
-                            mTrackers.remove(token);
-                        }
+                        tracker.mRetryCount += 1;
+                        sendSms(tracker);
                         break;
                     case ImsSmsImplBase.SEND_STATUS_ERROR_FALLBACK:
-                        // Skip MAX_SEND_RETRIES checking here. It allows CSFB after
-                        // SEND_STATUS_ERROR_RETRY up to MAX_SEND_RETRIES even.
                         tracker.mRetryCount += 1;
                         mTrackers.remove(token);
                         fallbackToPstn(tracker);
@@ -194,8 +185,7 @@
                         status == ImsSmsImplBase.SEND_STATUS_ERROR_FALLBACK,
                         reason,
                         tracker.mMessageId,
-                        tracker.isFromDefaultSmsApplication(mContext),
-                        tracker.getInterval());
+                        tracker.isFromDefaultSmsApplication(mContext));
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -270,18 +260,6 @@
         }
     };
 
-    @Override
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-            case EVENT_SEND_RETRY:
-                logd("SMS retry..");
-                sendSms((SmsTracker) msg.obj);
-                break;
-            default:
-                super.handleMessage(msg);
-        }
-    }
-
     public ImsSmsDispatcher(Phone phone, SmsDispatchersController smsDispatchersController,
             FeatureConnectorFactory factory) {
         super(phone, smsDispatchersController);
@@ -289,7 +267,7 @@
 
         mImsManagerConnector = mConnectorFactory.create(mContext, mPhone.getPhoneId(), TAG,
                 new FeatureConnector.Listener<ImsManager>() {
-                    public void connectionReady(ImsManager manager, int subId) throws ImsException {
+                    public void connectionReady(ImsManager manager) throws ImsException {
                         logd("ImsManager: connection ready.");
                         synchronized (mLock) {
                             mImsManager = manager;
@@ -438,7 +416,7 @@
         boolean isRetry = tracker.mRetryCount > 0;
         String format = getFormat();
 
-        if (SmsConstants.FORMAT_3GPP.equals(format) && isRetry) {
+        if (SmsConstants.FORMAT_3GPP.equals(format) && tracker.mRetryCount > 0) {
             // per TS 23.040 Section 9.2.3.6:  If TP-MTI SMS-SUBMIT (0x01) type
             //   TP-RD (bit 2) is 1 for retry
             //   and TP-MR is set to previously failed sms TP-MR
@@ -472,8 +450,7 @@
                     true /* fallbackToCs */,
                     SmsManager.RESULT_SYSTEM_ERROR,
                     tracker.mMessageId,
-                    tracker.isFromDefaultSmsApplication(mContext),
-                    tracker.getInterval());
+                    tracker.isFromDefaultSmsApplication(mContext));
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/InboundSmsHandler.java b/src/java/com/android/internal/telephony/InboundSmsHandler.java
index eeda1f9..c937ee1 100644
--- a/src/java/com/android/internal/telephony/InboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/InboundSmsHandler.java
@@ -28,7 +28,6 @@
 import static android.telephony.TelephonyManager.PHONE_TYPE_CDMA;
 
 import android.annotation.IntDef;
-import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.Activity;
 import android.app.AppOpsManager;
@@ -268,7 +267,7 @@
     protected TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();
 
     private LocalLog mLocalLog = new LocalLog(64);
-    private LocalLog mCarrierServiceLocalLog = new LocalLog(8);
+    private LocalLog mCarrierServiceLocalLog = new LocalLog(10);
 
     PowerWhitelistManager mPowerWhitelistManager;
 
@@ -1705,15 +1704,10 @@
 
         @Override
         public void onReceive(Context context, Intent intent) {
-            if (intent == null) {
-                logeWithLocalLog("onReceive: received null intent, faking " + mWaitingForIntent,
-                        mInboundSmsTracker.getMessageId());
-                return;
-            }
             handleAction(intent, true);
         }
 
-        private synchronized void handleAction(@NonNull Intent intent, boolean onReceive) {
+        private synchronized void handleAction(Intent intent, boolean onReceive) {
             String action = intent.getAction();
             if (mWaitingForIntent == null || !mWaitingForIntent.getAction().equals(action)) {
                 logeWithLocalLog("handleAction: Received " + action + " when expecting "
@@ -2115,8 +2109,7 @@
     static void registerNewMessageNotificationActionHandler(Context context) {
         IntentFilter userFilter = new IntentFilter();
         userFilter.addAction(ACTION_OPEN_SMS_APP);
-        context.registerReceiver(new NewMessageNotificationActionReceiver(), userFilter,
-                Context.RECEIVER_NOT_EXPORTED);
+        context.registerReceiver(new NewMessageNotificationActionReceiver(), userFilter);
     }
 
     protected abstract class CbTestBroadcastReceiver extends BroadcastReceiver {
diff --git a/src/java/com/android/internal/telephony/LocaleTracker.java b/src/java/com/android/internal/telephony/LocaleTracker.java
index 4e0f452..3797288 100755
--- a/src/java/com/android/internal/telephony/LocaleTracker.java
+++ b/src/java/com/android/internal/telephony/LocaleTracker.java
@@ -162,7 +162,7 @@
 
     private boolean mIsTracking = false;
 
-    private final LocalLog mLocalLog = new LocalLog(32, false /* useLocalTimestamps */);
+    private final LocalLog mLocalLog = new LocalLog(50);
 
     /** Broadcast receiver to get SIM card state changed event */
     private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@@ -176,7 +176,6 @@
                                     TelephonyManager.SIM_STATE_UNKNOWN), 0).sendToTarget();
                 }
             } else if (ACTION_COUNTRY_OVERRIDE.equals(intent.getAction())) {
-                // note: need to set ServiceStateTracker#PROP_FORCE_ROAMING to force roaming.
                 String countryOverride = intent.getStringExtra(EXTRA_COUNTRY);
                 boolean reset = intent.getBooleanExtra(EXTRA_RESET, false);
                 if (reset) countryOverride = null;
@@ -655,14 +654,4 @@
         ipw.decreaseIndent();
         ipw.flush();
     }
-
-    /**
-     *  This getter should only be used for testing purposes in classes that wish to spoof the
-     *  country ISO. An example of how this can be done is in ServiceStateTracker#InSameCountry
-     * @return spoofed country iso.
-     */
-    @VisibleForTesting
-    public String getCountryOverride() {
-        return mCountryOverride;
-    }
 }
diff --git a/src/java/com/android/internal/telephony/MessagingIndication.java b/src/java/com/android/internal/telephony/MessagingIndication.java
deleted file mode 100644
index 86e30b0..0000000
--- a/src/java/com/android/internal/telephony/MessagingIndication.java
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_CDMA_NEW_SMS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NEW_SMS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_SMS_STORAGE_FULL;
-
-import android.hardware.radio.messaging.IRadioMessagingIndication;
-import android.os.AsyncResult;
-import android.telephony.SmsMessage;
-
-import com.android.internal.telephony.uicc.IccUtils;
-
-/**
- * Interface declaring unsolicited radio indications for messaging APIs.
- */
-public class MessagingIndication extends IRadioMessagingIndication.Stub {
-    private final RIL mRil;
-
-    public MessagingIndication(RIL ril) {
-        mRil = ril;
-    }
-
-    /**
-     * Indicates when new CDMA SMS is received.
-     * @param indicationType Type of radio indication
-     * @param msg CdmaSmsMessage
-     */
-    public void cdmaNewSms(int indicationType,
-            android.hardware.radio.messaging.CdmaSmsMessage msg) {
-        mRil.processIndication(RIL.MESSAGING_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_CDMA_NEW_SMS);
-
-        SmsMessage sms = new SmsMessage(RILUtils.convertHalCdmaSmsMessage(msg));
-        if (mRil.mCdmaSmsRegistrant != null) {
-            mRil.mCdmaSmsRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
-        }
-    }
-
-    /**
-     * Indicates that SMS storage on the RUIM is full. Messages cannot be saved on the RUIM until
-     * space is freed.
-     * @param indicationType Type of radio indication
-     */
-    public void cdmaRuimSmsStorageFull(int indicationType) {
-        mRil.processIndication(RIL.MESSAGING_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL);
-
-        if (mRil.mIccSmsFullRegistrant != null) {
-            mRil.mIccSmsFullRegistrant.notifyRegistrant();
-        }
-    }
-
-    /**
-     * Indicates when new Broadcast SMS is received
-     * @param indicationType Type of radio indication
-     * @param data If received from GSM network, "data" is byte array of 88 bytes which indicates
-     *        each page of a CBS Message sent to the MS by the BTS as coded in 3GPP 23.041 Section
-     *        9.4.1.2. If received from UMTS network, "data" is byte array of 90 up to 1252 bytes
-     *        which contain between 1 and 15 CBS Message pages sent as one packet to the MS by the
-     *        BTS as coded in 3GPP 23.041 Section 9.4.2.2
-     */
-    public void newBroadcastSms(int indicationType, byte[] data) {
-        mRil.processIndication(RIL.MESSAGING_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) {
-            mRil.unsljLogvRet(RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS,
-                    IccUtils.bytesToHexString(data));
-        }
-
-        if (mRil.mGsmBroadcastSmsRegistrant != null) {
-            mRil.mGsmBroadcastSmsRegistrant.notifyRegistrant(new AsyncResult(null, data, null));
-        }
-    }
-
-    /**
-     * Indicates when new SMS is received.
-     * @param indicationType Type of radio indication
-     * @param pdu PDU of SMS-DELIVER represented as byte array.
-     *        The PDU starts with the SMSC address per TS 27.005 (+CMT:)
-     */
-    public void newSms(int indicationType, byte[] pdu) {
-        mRil.processIndication(RIL.MESSAGING_SERVICE, indicationType);
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS);
-
-        SmsMessageBase smsb = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pdu);
-        if (mRil.mGsmSmsRegistrant != null) {
-            mRil.mGsmSmsRegistrant.notifyRegistrant(
-                    new AsyncResult(null, smsb == null ? null : new SmsMessage(smsb), null));
-        }
-    }
-
-    /**
-     * Indicates when new SMS has been stored on SIM card.
-     * @param indicationType Type of radio indication
-     * @param recordNumber Record number on the SIM
-     */
-    public void newSmsOnSim(int indicationType, int recordNumber) {
-        mRil.processIndication(RIL.MESSAGING_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM);
-
-        if (mRil.mSmsOnSimRegistrant != null) {
-            mRil.mSmsOnSimRegistrant.notifyRegistrant(new AsyncResult(null, recordNumber, null));
-        }
-    }
-
-    /**
-     * Indicates when new SMS Status Report is received.
-     * @param indicationType Type of radio indication
-     * @param pdu PDU of SMS-STATUS-REPORT represented as byte array.
-     *        The PDU starts with the SMSC address per TS 27.005 (+CMT:)
-     */
-    public void newSmsStatusReport(int indicationType, byte[] pdu) {
-        mRil.processIndication(RIL.MESSAGING_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT);
-
-        if (mRil.mSmsStatusRegistrant != null) {
-            mRil.mSmsStatusRegistrant.notifyRegistrant(new AsyncResult(null, pdu, null));
-        }
-    }
-
-    /**
-     * Indicates that SMS storage on the SIM is full. Sent when the network attempts to deliver a
-     * new SMS message. Messages cannot be saved on the SIM until space is freed. In particular,
-     * incoming Class 2 messages must not be stored.
-     * @param indicationType Type of radio indication
-     */
-    public void simSmsStorageFull(int indicationType) {
-        mRil.processIndication(RIL.MESSAGING_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_SIM_SMS_STORAGE_FULL);
-
-        if (mRil.mIccSmsFullRegistrant != null) {
-            mRil.mIccSmsFullRegistrant.notifyRegistrant();
-        }
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return IRadioMessagingIndication.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return IRadioMessagingIndication.VERSION;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/MessagingResponse.java b/src/java/com/android/internal/telephony/MessagingResponse.java
deleted file mode 100644
index 3dc1d1a..0000000
--- a/src/java/com/android/internal/telephony/MessagingResponse.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.hardware.radio.RadioError;
-import android.hardware.radio.RadioResponseInfo;
-import android.hardware.radio.messaging.IRadioMessagingResponse;
-
-import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-
-import java.util.ArrayList;
-
-/**
- * Interface declaring response functions to solicited radio requests for messaging APIs.
- */
-public class MessagingResponse extends IRadioMessagingResponse.Stub {
-    private final RIL mRil;
-
-    public MessagingResponse(RIL ril) {
-        mRil = ril;
-    }
-
-    private void responseSms(RadioResponseInfo responseInfo,
-            android.hardware.radio.messaging.SendSmsResult sms) {
-        RILRequest rr = mRil.processResponse(RIL.MESSAGING_SERVICE, responseInfo);
-
-        if (rr != null) {
-            long messageId = RIL.getOutgoingSmsMessageId(rr.mResult);
-            SmsResponse ret = new SmsResponse(sms.messageRef, sms.ackPDU, sms.errorCode, messageId);
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for
-     * radio request which take long time to respond.
-     * For more details, refer https://source.android.com/devices/tech/connect/ril.html
-     * @param serial Serial no. of the request whose acknowledgement is sent.
-     */
-    public void acknowledgeRequest(int serial) {
-        mRil.processRequestAck(serial);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void acknowledgeIncomingGsmSmsWithPduResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MESSAGING_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void acknowledgeLastIncomingCdmaSmsResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MESSAGING_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void acknowledgeLastIncomingGsmSmsResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MESSAGING_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void deleteSmsOnRuimResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MESSAGING_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void deleteSmsOnSimResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MESSAGING_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param configs Vector of CDMA broadcast SMS configs
-     */
-    public void getCdmaBroadcastConfigResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[] configs) {
-        RILRequest rr = mRil.processResponse(RIL.MESSAGING_SERVICE, responseInfo);
-
-        if (rr != null) {
-            int[] ret;
-            int numServiceCategories = configs.length;
-            if (numServiceCategories == 0) {
-                // TODO: The logic of providing default values should not be done by this transport
-                // layer; it needs to be done by the vendor ril or application logic.
-                int numInts;
-                numInts = RILUtils.CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES
-                        * RILUtils.CDMA_BSI_NO_OF_INTS_STRUCT + 1;
-                ret = new int[numInts];
-
-                // Faking a default record for all possible records.
-                ret[0] = RILUtils.CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES;
-
-                // Loop over CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES set 'english' as
-                // default language and selection status to false for all.
-                for (int i = 1; i < numInts; i += RILUtils.CDMA_BSI_NO_OF_INTS_STRUCT) {
-                    ret[i] = i / RILUtils.CDMA_BSI_NO_OF_INTS_STRUCT;
-                    ret[i + 1] = 1;
-                    ret[i + 2] = 0;
-                }
-            } else {
-                int numInts;
-                numInts = (numServiceCategories * RILUtils.CDMA_BSI_NO_OF_INTS_STRUCT) + 1;
-                ret = new int[numInts];
-
-                ret[0] = numServiceCategories;
-                for (int i = 1, j = 0; j < configs.length;
-                        j++, i = i + RILUtils.CDMA_BSI_NO_OF_INTS_STRUCT) {
-                    ret[i] = configs[i].serviceCategory;
-                    ret[i + 1] = configs[i].language;
-                    ret[i + 2] = configs[i].selected ? 1 : 0;
-                }
-            }
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param configs Vector of GSM/WCDMA Cell broadcast SMS configs
-     */
-    public void getGsmBroadcastConfigResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[] configs) {
-        RILRequest rr = mRil.processResponse(RIL.MESSAGING_SERVICE, responseInfo);
-
-        if (rr != null) {
-            ArrayList<SmsBroadcastConfigInfo> ret = new ArrayList<>();
-            for (android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo info : configs) {
-                ret.add(new SmsBroadcastConfigInfo(info.fromServiceId, info.toServiceId,
-                        info.fromCodeScheme, info.toCodeScheme, info.selected));
-            }
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param smsc Short Message Service Center address on the device
-     */
-    public void getSmscAddressResponse(RadioResponseInfo responseInfo, String smsc) {
-        RadioResponse.responseString(RIL.MESSAGING_SERVICE, mRil, responseInfo, smsc);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void reportSmsMemoryStatusResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MESSAGING_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param sms Response to SMS sent as defined by SendSmsResult
-     */
-    public void sendCdmaSmsExpectMoreResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.messaging.SendSmsResult sms) {
-        responseSms(responseInfo, sms);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param sms Response to SMS sent as defined by SendSmsResult
-     */
-    public void sendCdmaSmsResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.messaging.SendSmsResult sms) {
-        responseSms(responseInfo, sms);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param sms Response to SMS sent as defined by SendSmsResult
-     */
-    public void sendImsSmsResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.messaging.SendSmsResult sms) {
-        responseSms(responseInfo, sms);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param sms Response to SMS sent as defined by SendSmsResult
-     */
-    public void sendSmsExpectMoreResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.messaging.SendSmsResult sms) {
-        responseSms(responseInfo, sms);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param sms Response to sms sent as defined by SendSmsResult
-     */
-    public void sendSmsResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.messaging.SendSmsResult sms) {
-        responseSms(responseInfo, sms);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setCdmaBroadcastActivationResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MESSAGING_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setCdmaBroadcastConfigResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MESSAGING_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setGsmBroadcastActivationResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MESSAGING_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setGsmBroadcastConfigResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MESSAGING_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setSmscAddressResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MESSAGING_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param index record index where the CDMA SMS message is stored
-     */
-    public void writeSmsToRuimResponse(RadioResponseInfo responseInfo, int index) {
-        RadioResponse.responseInts(RIL.MESSAGING_SERVICE, mRil, responseInfo, index);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param index record index where the message is stored
-     */
-    public void writeSmsToSimResponse(RadioResponseInfo responseInfo, int index) {
-        RadioResponse.responseInts(RIL.MESSAGING_SERVICE, mRil, responseInfo, index);
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return IRadioMessagingResponse.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return IRadioMessagingResponse.VERSION;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/MockModem.java b/src/java/com/android/internal/telephony/MockModem.java
deleted file mode 100644
index 4266a75..0000000
--- a/src/java/com/android/internal/telephony/MockModem.java
+++ /dev/null
@@ -1,358 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.ServiceConnection;
-import android.os.IBinder;
-
-import com.android.telephony.Rlog;
-
-/** This class provides wrapper APIs for binding interfaces to mock service. */
-public class MockModem {
-    private static final String TAG = "MockModem";
-    private static final String BIND_IRADIOMODEM = "android.telephony.mockmodem.iradiomodem";
-    private static final String BIND_IRADIOSIM = "android.telephony.mockmodem.iradiosim";
-    private static final String BIND_IRADIOMESSAGING =
-            "android.telephony.mockmodem.iradiomessaging";
-    private static final String BIND_IRADIODATA = "android.telephony.mockmodem.iradiodata";
-    private static final String BIND_IRADIONETWORK = "android.telephony.mockmodem.iradionetwork";
-    private static final String BIND_IRADIOVOICE = "android.telephony.mockmodem.iradiovoice";
-    private static final String BIND_IRADIOCONFIG = "android.telephony.mockmodem.iradioconfig";
-    private static final String PHONE_ID = "phone_id";
-
-    private static final byte DEFAULT_PHONE_ID = 0x00;
-
-    static final int RADIOCONFIG_SERVICE = RIL.MAX_SERVICE_IDX + 1;
-
-    static final int BINDER_RETRY_MILLIS = 3 * 100;
-    static final int BINDER_MAX_RETRY = 3;
-
-    private Context mContext;
-    private String mServiceName;
-    private String mPackageName;
-
-    private IBinder mModemBinder;
-    private IBinder mSimBinder;
-    private IBinder mMessagingBinder;
-    private IBinder mDataBinder;
-    private IBinder mNetworkBinder;
-    private IBinder mVoiceBinder;
-    private IBinder mConfigBinder;
-    private ServiceConnection mModemServiceConnection;
-    private ServiceConnection mSimServiceConnection;
-    private ServiceConnection mMessagingServiceConnection;
-    private ServiceConnection mDataServiceConnection;
-    private ServiceConnection mNetworkServiceConnection;
-    private ServiceConnection mVoiceServiceConnection;
-    private ServiceConnection mConfigServiceConnection;
-
-    private byte mPhoneId;
-
-    MockModem(Context context, String serviceName) {
-        this(context, serviceName, 0);
-    }
-
-    MockModem(Context context, String serviceName, int phoneId) {
-        mPhoneId = (byte) phoneId;
-        mContext = context;
-        String[] componentInfo = serviceName.split("/", 2);
-        mPackageName = componentInfo[0];
-        mServiceName = componentInfo[1];
-    }
-
-    private class MockModemConnection implements ServiceConnection {
-        private int mService;
-
-        MockModemConnection(int module) {
-            mService = module;
-        }
-
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder binder) {
-            Rlog.d(TAG, "IRadio " + getModuleName(mService) + "  - onServiceConnected");
-
-            if (mService == RIL.MODEM_SERVICE) {
-                mModemBinder = binder;
-            } else if (mService == RIL.SIM_SERVICE) {
-                mSimBinder = binder;
-            } else if (mService == RIL.MESSAGING_SERVICE) {
-                mMessagingBinder = binder;
-            } else if (mService == RIL.DATA_SERVICE) {
-                mDataBinder = binder;
-            } else if (mService == RIL.NETWORK_SERVICE) {
-                mNetworkBinder = binder;
-            } else if (mService == RIL.VOICE_SERVICE) {
-                mVoiceBinder = binder;
-            } else if (mService == RADIOCONFIG_SERVICE) {
-                mConfigBinder = binder;
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            Rlog.d(TAG, "IRadio " + getModuleName(mService) + "  - onServiceDisconnected");
-
-            if (mService == RIL.MODEM_SERVICE) {
-                mModemBinder = null;
-            } else if (mService == RIL.SIM_SERVICE) {
-                mSimBinder = null;
-            } else if (mService == RIL.MESSAGING_SERVICE) {
-                mMessagingBinder = null;
-            } else if (mService == RIL.DATA_SERVICE) {
-                mDataBinder = null;
-            } else if (mService == RIL.NETWORK_SERVICE) {
-                mNetworkBinder = null;
-            } else if (mService == RIL.VOICE_SERVICE) {
-                mVoiceBinder = null;
-            } else if (mService == RADIOCONFIG_SERVICE) {
-                mConfigBinder = null;
-            }
-        }
-    }
-
-    private boolean bindModuleToMockModemService(
-            String actionName, ServiceConnection serviceConnection) {
-        return bindModuleToMockModemService(DEFAULT_PHONE_ID, actionName, serviceConnection);
-    }
-
-    private boolean bindModuleToMockModemService(
-            byte phoneId, String actionName, ServiceConnection serviceConnection) {
-        boolean status = false;
-
-        Intent intent = new Intent();
-        intent.setComponent(new ComponentName(mPackageName, mServiceName));
-        intent.setAction(actionName);
-        intent.putExtra(PHONE_ID, phoneId);
-
-        status = mContext.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);
-        return status;
-    }
-
-    /** waitForBinder */
-    public IBinder getServiceBinder(int service) {
-        switch (service) {
-            case RIL.MODEM_SERVICE:
-                return mModemBinder;
-            case RIL.SIM_SERVICE:
-                return mSimBinder;
-            case RIL.MESSAGING_SERVICE:
-                return mMessagingBinder;
-            case RIL.DATA_SERVICE:
-                return mDataBinder;
-            case RIL.NETWORK_SERVICE:
-                return mNetworkBinder;
-            case RIL.VOICE_SERVICE:
-                return mVoiceBinder;
-            case RADIOCONFIG_SERVICE:
-                return mConfigBinder;
-            default:
-                return null;
-        }
-    }
-
-    /** Binding interfaces with mock modem service */
-    public void bindAllMockModemService() {
-        for (int service = RIL.MIN_SERVICE_IDX; service <= RIL.MAX_SERVICE_IDX; service++) {
-            bindToMockModemService(service);
-        }
-    }
-
-    /** bindToMockModemService */
-    public void bindToMockModemService(int service) {
-        if (service == RADIOCONFIG_SERVICE) {
-            if (mConfigBinder == null) {
-                mConfigServiceConnection = new MockModemConnection(RADIOCONFIG_SERVICE);
-
-                boolean status =
-                        bindModuleToMockModemService(BIND_IRADIOCONFIG, mConfigServiceConnection);
-                if (!status) {
-                    Rlog.d(TAG, "IRadio Config bind fail");
-                    mConfigServiceConnection = null;
-                }
-            } else {
-                Rlog.d(TAG, "IRadio Config is bound");
-            }
-        } else if (service == RIL.MODEM_SERVICE) {
-            if (mModemBinder == null) {
-                mModemServiceConnection = new MockModemConnection(RIL.MODEM_SERVICE);
-
-                boolean status =
-                        bindModuleToMockModemService(
-                                mPhoneId, BIND_IRADIOMODEM, mModemServiceConnection);
-                if (!status) {
-                    Rlog.d(TAG, "IRadio Modem bind fail");
-                    mModemServiceConnection = null;
-                }
-            } else {
-                Rlog.d(TAG, "IRadio Modem is bound");
-            }
-        } else if (service == RIL.SIM_SERVICE) {
-            if (mSimBinder == null) {
-                mSimServiceConnection = new MockModemConnection(RIL.SIM_SERVICE);
-
-                boolean status =
-                        bindModuleToMockModemService(
-                                mPhoneId, BIND_IRADIOSIM, mSimServiceConnection);
-                if (!status) {
-                    Rlog.d(TAG, "IRadio Sim bind fail");
-                    mSimServiceConnection = null;
-                }
-            } else {
-                Rlog.d(TAG, "IRadio Sim is bound");
-            }
-        } else if (service == RIL.MESSAGING_SERVICE) {
-            if (mMessagingBinder == null) {
-                mMessagingServiceConnection = new MockModemConnection(RIL.MESSAGING_SERVICE);
-
-                boolean status =
-                        bindModuleToMockModemService(
-                                mPhoneId, BIND_IRADIOMESSAGING, mMessagingServiceConnection);
-                if (!status) {
-                    Rlog.d(TAG, "IRadio Messaging bind fail");
-                    mMessagingServiceConnection = null;
-                }
-            } else {
-                Rlog.d(TAG, "IRadio Messaging is bound");
-            }
-        } else if (service == RIL.DATA_SERVICE) {
-            if (mDataBinder == null) {
-                mDataServiceConnection = new MockModemConnection(RIL.DATA_SERVICE);
-
-                boolean status =
-                        bindModuleToMockModemService(
-                                mPhoneId, BIND_IRADIODATA, mDataServiceConnection);
-                if (!status) {
-                    Rlog.d(TAG, "IRadio Data bind fail");
-                    mDataServiceConnection = null;
-                }
-            } else {
-                Rlog.d(TAG, "IRadio Data is bound");
-            }
-        } else if (service == RIL.NETWORK_SERVICE) {
-            if (mNetworkBinder == null) {
-                mNetworkServiceConnection = new MockModemConnection(RIL.NETWORK_SERVICE);
-
-                boolean status =
-                        bindModuleToMockModemService(
-                                mPhoneId, BIND_IRADIONETWORK, mNetworkServiceConnection);
-                if (!status) {
-                    Rlog.d(TAG, "IRadio Network bind fail");
-                    mNetworkServiceConnection = null;
-                }
-            } else {
-                Rlog.d(TAG, "IRadio Network is bound");
-            }
-        } else if (service == RIL.VOICE_SERVICE) {
-            if (mVoiceBinder == null) {
-                mVoiceServiceConnection = new MockModemConnection(RIL.VOICE_SERVICE);
-
-                boolean status =
-                        bindModuleToMockModemService(
-                                mPhoneId, BIND_IRADIOVOICE, mVoiceServiceConnection);
-                if (!status) {
-                    Rlog.d(TAG, "IRadio Voice bind fail");
-                    mVoiceServiceConnection = null;
-                }
-            } else {
-                Rlog.d(TAG, "IRadio Voice is bound");
-            }
-        }
-    }
-
-    /** unbindMockModemService */
-    public void unbindMockModemService(int service) {
-
-        if (service == RADIOCONFIG_SERVICE) {
-            if (mConfigServiceConnection != null) {
-                mContext.unbindService(mConfigServiceConnection);
-                mConfigServiceConnection = null;
-                mConfigBinder = null;
-                Rlog.d(TAG, "unbind IRadio Config");
-            }
-        } else if (service == RIL.MODEM_SERVICE) {
-            if (mModemServiceConnection != null) {
-                mContext.unbindService(mModemServiceConnection);
-                mModemServiceConnection = null;
-                mModemBinder = null;
-                Rlog.d(TAG, "unbind IRadio Modem");
-            }
-        } else if (service == RIL.SIM_SERVICE) {
-            if (mSimServiceConnection != null) {
-                mContext.unbindService(mSimServiceConnection);
-                mSimServiceConnection = null;
-                mSimBinder = null;
-                Rlog.d(TAG, "unbind IRadio Sim");
-            }
-        } else if (service == RIL.MESSAGING_SERVICE) {
-            if (mMessagingServiceConnection != null) {
-                mContext.unbindService(mMessagingServiceConnection);
-                mMessagingServiceConnection = null;
-                mMessagingBinder = null;
-                Rlog.d(TAG, "unbind IRadio Messaging");
-            }
-        } else if (service == RIL.DATA_SERVICE) {
-            if (mDataServiceConnection != null) {
-                mContext.unbindService(mDataServiceConnection);
-                mDataServiceConnection = null;
-                mDataBinder = null;
-                Rlog.d(TAG, "unbind IRadio Data");
-            }
-        } else if (service == RIL.NETWORK_SERVICE) {
-            if (mNetworkServiceConnection != null) {
-                mContext.unbindService(mNetworkServiceConnection);
-                mNetworkServiceConnection = null;
-                mNetworkBinder = null;
-                Rlog.d(TAG, "unbind IRadio Network");
-            }
-        } else if (service == RIL.VOICE_SERVICE) {
-            if (mVoiceServiceConnection != null) {
-                mContext.unbindService(mVoiceServiceConnection);
-                mVoiceServiceConnection = null;
-                mVoiceBinder = null;
-                Rlog.d(TAG, "unbind IRadio Voice");
-            }
-        }
-    }
-
-    public String getServiceName() {
-        return mServiceName;
-    }
-
-    private String getModuleName(int service) {
-        switch (service) {
-            case RIL.MODEM_SERVICE:
-                return "modem";
-            case RIL.SIM_SERVICE:
-                return "sim";
-            case RIL.MESSAGING_SERVICE:
-                return "messaging";
-            case RIL.DATA_SERVICE:
-                return "data";
-            case RIL.NETWORK_SERVICE:
-                return "network";
-            case RIL.VOICE_SERVICE:
-                return "voice";
-            case RADIOCONFIG_SERVICE:
-                return "config";
-            default:
-                return "none";
-        }
-    }
-}
diff --git a/src/java/com/android/internal/telephony/ModemIndication.java b/src/java/com/android/internal/telephony/ModemIndication.java
deleted file mode 100644
index 8baa5fd..0000000
--- a/src/java/com/android/internal/telephony/ModemIndication.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_HARDWARE_CONFIG_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_MODEM_RESTART;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RADIO_CAPABILITY;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RIL_CONNECTED;
-
-import android.hardware.radio.modem.IRadioModemIndication;
-import android.os.AsyncResult;
-
-import java.util.ArrayList;
-
-/**
- * Interface declaring unsolicited radio indications for modem APIs.
- */
-public class ModemIndication extends IRadioModemIndication.Stub {
-    private final RIL mRil;
-
-    public ModemIndication(RIL ril) {
-        mRil = ril;
-    }
-
-    /**
-     * Indicates when the hardware configuration associated with the RILd changes.
-     * @param indicationType Type of radio indication
-     * @param configs Array of hardware configs
-     */
-    public void hardwareConfigChanged(int indicationType,
-            android.hardware.radio.modem.HardwareConfig[] configs) {
-        mRil.processIndication(RIL.MODEM_SERVICE, indicationType);
-
-        ArrayList<HardwareConfig> response = RILUtils.convertHalHardwareConfigList(configs);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_HARDWARE_CONFIG_CHANGED, response);
-
-        mRil.mHardwareConfigChangeRegistrants.notifyRegistrants(
-                new AsyncResult(null, response, null));
-    }
-
-    /**
-     * Indicates when there is a modem reset.
-     * @param indicationType Type of radio indication
-     * @param reason The reason for the reset. It may be a crash signature if the restart was due to
-     *        a crash or some string such as "user-initiated restart" or "AT command initiated
-     *        restart" that explains the cause of the modem restart
-     */
-    public void modemReset(int indicationType, String reason) {
-        mRil.processIndication(RIL.MODEM_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_MODEM_RESTART, reason);
-
-        mRil.writeMetricsModemRestartEvent(reason);
-        mRil.mModemResetRegistrants.notifyRegistrants(new AsyncResult(null, reason, null));
-    }
-
-    /**
-     * Sent when setRadioCapability() completes. Returns the same RadioCapability as
-     * getRadioCapability() and is the same as the one sent by setRadioCapability().
-     * @param indicationType Type of radio indication
-     * @param radioCapability Current radio capability
-     */
-    public void radioCapabilityIndication(int indicationType,
-            android.hardware.radio.modem.RadioCapability radioCapability) {
-        mRil.processIndication(RIL.MODEM_SERVICE, indicationType);
-
-        RadioCapability response = RILUtils.convertHalRadioCapability(radioCapability, mRil);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_RADIO_CAPABILITY, response);
-
-        mRil.mPhoneRadioCapabilityChangedRegistrants.notifyRegistrants(
-                new AsyncResult(null, response, null));
-    }
-
-    /**
-     * Indicates when radio state changes.
-     * @param indicationType Type of radio indication
-     * @param radioState Current radio state
-     */
-    public void radioStateChanged(int indicationType, int radioState) {
-        mRil.processIndication(RIL.MODEM_SERVICE, indicationType);
-
-        int state = RILUtils.convertHalRadioState(radioState);
-        if (RIL.RILJ_LOGD) {
-            mRil.unsljLogMore(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, "radioStateChanged: "
-                    + state);
-        }
-
-        mRil.setRadioState(state, false /* forceNotifyRegistrants */);
-    }
-
-    /**
-     * Indicates the ril connects and returns the version.
-     * @param indicationType Type of radio indication
-     */
-    public void rilConnected(int indicationType) {
-        mRil.processIndication(RIL.MODEM_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RIL_CONNECTED);
-
-        // Initial conditions
-        mRil.setRadioPower(false, null);
-        mRil.setCdmaSubscriptionSource(mRil.mCdmaSubscription, null);
-        // TODO: This should not require a version number. Setting it to latest RIL version for now.
-        mRil.notifyRegistrantsRilConnectionChanged(15);
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return IRadioModemIndication.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return IRadioModemIndication.VERSION;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/ModemResponse.java b/src/java/com/android/internal/telephony/ModemResponse.java
deleted file mode 100644
index 6e44ddc..0000000
--- a/src/java/com/android/internal/telephony/ModemResponse.java
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.hardware.radio.RadioError;
-import android.hardware.radio.RadioResponseInfo;
-import android.hardware.radio.modem.IRadioModemResponse;
-import android.os.SystemClock;
-import android.telephony.ActivityStatsTechSpecificInfo;
-import android.telephony.AnomalyReporter;
-import android.telephony.ModemActivityInfo;
-
-import java.util.ArrayList;
-import java.util.UUID;
-
-/**
- * Interface declaring response functions to solicited radio requests for modem APIs.
- */
-public class ModemResponse extends IRadioModemResponse.Stub {
-    private final RIL mRil;
-
-    public ModemResponse(RIL ril) {
-        mRil = ril;
-    }
-
-    /**
-     * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for
-     * radio request which take long time to respond.
-     * For more details, refer https://source.android.com/devices/tech/connect/ril.html
-     * @param serial Serial no. of the request whose acknowledgement is sent.
-     */
-    public void acknowledgeRequest(int serial) {
-        mRil.processRequestAck(serial);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial number and error.
-     */
-    public void enableModemResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MODEM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param version String containing version string for log reporting
-     */
-    public void getBasebandVersionResponse(RadioResponseInfo responseInfo, String version) {
-        RadioResponse.responseString(RIL.MODEM_SERVICE, mRil, responseInfo, version);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param imei IMEI if GSM subscription is available
-     * @param imeisv IMEISV if GSM subscription is available
-     * @param esn ESN if CDMA subscription is available
-     * @param meid MEID if CDMA subscription is available
-     */
-    public void getDeviceIdentityResponse(RadioResponseInfo responseInfo, String imei,
-            String imeisv, String esn, String meid) {
-        RadioResponse.responseStrings(
-                RIL.MODEM_SERVICE, mRil, responseInfo, imei, imeisv, esn, meid);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param config Array of HardwareConfig of the radio
-     */
-    public void getHardwareConfigResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.modem.HardwareConfig[] config) {
-        RILRequest rr = mRil.processResponse(RIL.MODEM_SERVICE, responseInfo);
-
-        if (rr != null) {
-            ArrayList<HardwareConfig> ret = RILUtils.convertHalHardwareConfigList(config);
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param activityInfo modem activity information
-     */
-    public void getModemActivityInfoResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.modem.ActivityStatsInfo activityInfo) {
-        RILRequest rr = mRil.processResponse(RIL.MODEM_SERVICE, responseInfo);
-
-        if (rr != null) {
-            ModemActivityInfo ret = null;
-            ActivityStatsTechSpecificInfo[] astsi = null;
-            if (responseInfo.error == RadioError.NONE) {
-                final int sleepModeTimeMs = activityInfo.sleepModeTimeMs;
-                final int idleModeTimeMs = activityInfo.idleModeTimeMs;
-                int size = activityInfo.techSpecificInfo.length;
-                astsi = new ActivityStatsTechSpecificInfo[size];
-                for (int s = 0; s < size; s++) {
-                    int rat = activityInfo.techSpecificInfo[s].rat;
-                    int frequencyRange = activityInfo.techSpecificInfo[s].frequencyRange;
-                    int [] txModeTimeMs = new int[ModemActivityInfo.getNumTxPowerLevels()];
-                    int rxModeTimeMs = activityInfo.techSpecificInfo[s].rxModeTimeMs;
-                    for (int i = 0; i < ModemActivityInfo.getNumTxPowerLevels(); i++) {
-                        txModeTimeMs[i] = activityInfo.techSpecificInfo[s].txmModetimeMs[i];
-                    }
-                    astsi[s] = new ActivityStatsTechSpecificInfo(
-                                    rat,
-                                    frequencyRange,
-                                    txModeTimeMs,
-                                    rxModeTimeMs);
-                }
-                ret = new ModemActivityInfo(SystemClock.elapsedRealtime(), sleepModeTimeMs,
-                        idleModeTimeMs, astsi);
-            } else {
-                astsi = new ActivityStatsTechSpecificInfo[1];
-                astsi[0] = new ActivityStatsTechSpecificInfo(0, 0,
-                        new int[ModemActivityInfo.getNumTxPowerLevels()], 0);
-                ret = new ModemActivityInfo(SystemClock.elapsedRealtime(), 0, 0, astsi);
-                responseInfo.error = RadioError.NONE;
-            }
-            RadioResponse.sendMessageResponse(rr.mResult, ret);
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param isEnabled whether the modem stack is enabled.
-     */
-    public void getModemStackStatusResponse(RadioResponseInfo responseInfo, boolean isEnabled) {
-        RILRequest rr = mRil.processResponse(RIL.MODEM_SERVICE, responseInfo);
-
-        if (rr != null) {
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, isEnabled);
-            }
-            mRil.processResponseDone(rr, responseInfo, isEnabled);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param radioCapability RadioCapability from the modem
-     */
-    public void getRadioCapabilityResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.modem.RadioCapability radioCapability) {
-        RILRequest rr = mRil.processResponse(RIL.MODEM_SERVICE, responseInfo);
-
-        if (rr != null) {
-            RadioCapability ret = RILUtils.convertHalRadioCapability(radioCapability, mRil);
-            if (responseInfo.error == RadioError.REQUEST_NOT_SUPPORTED
-                    || responseInfo.error == RadioError.GENERIC_FAILURE) {
-                // TODO: Construct the supported RAF bitmask based on preferred network bitmasks
-                ret = mRil.makeStaticRadioCapability();
-                responseInfo.error = RadioError.NONE;
-            }
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param result String containing the contents of the NV item
-     */
-    public void nvReadItemResponse(RadioResponseInfo responseInfo, String result) {
-        RadioResponse.responseString(RIL.MODEM_SERVICE, mRil, responseInfo, result);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void nvResetConfigResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MODEM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void nvWriteCdmaPrlResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MODEM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void nvWriteItemResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MODEM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void requestShutdownResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MODEM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void sendDeviceStateResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MODEM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param radioCapability RadioCapability to set
-     */
-    public void setRadioCapabilityResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.modem.RadioCapability radioCapability) {
-        RILRequest rr = mRil.processResponse(RIL.MODEM_SERVICE, responseInfo);
-
-        if (rr != null) {
-            RadioCapability ret = RILUtils.convertHalRadioCapability(radioCapability, mRil);
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error.
-     */
-    public void setRadioPowerResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.MODEM_SERVICE, mRil, responseInfo);
-        mRil.mLastRadioPowerResult = responseInfo.error;
-        if (responseInfo.error == RadioError.RF_HARDWARE_ISSUE) {
-            AnomalyReporter.reportAnomaly(
-                    UUID.fromString(RILUtils.RADIO_POWER_FAILURE_RF_HARDWARE_ISSUE_UUID),
-                    "RF HW damaged");
-        } else if (responseInfo.error == RadioError.NO_RF_CALIBRATION_INFO) {
-            AnomalyReporter.reportAnomaly(
-                    UUID.fromString(RILUtils.RADIO_POWER_FAILURE_NO_RF_CALIBRATION_UUID),
-                    "No RF calibration data");
-        } else if (responseInfo.error != RadioError.RADIO_NOT_AVAILABLE
-                && responseInfo.error != RadioError.NONE) {
-            AnomalyReporter.reportAnomaly(
-                    UUID.fromString(RILUtils.RADIO_POWER_FAILURE_BUGREPORT_UUID),
-                    "Radio power failure");
-        }
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return IRadioModemResponse.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return IRadioModemResponse.VERSION;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/MultiSimSettingController.java b/src/java/com/android/internal/telephony/MultiSimSettingController.java
index 3f5c23c..ca5d962 100644
--- a/src/java/com/android/internal/telephony/MultiSimSettingController.java
+++ b/src/java/com/android/internal/telephony/MultiSimSettingController.java
@@ -29,7 +29,6 @@
 import static android.telephony.TelephonyManager.EXTRA_SIM_COMBINATION_WARNING_TYPE_NONE;
 import static android.telephony.TelephonyManager.EXTRA_SUBSCRIPTION_ID;
 
-import android.annotation.CallbackExecutor;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.app.PendingIntent;
@@ -53,7 +52,6 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
 import com.android.internal.telephony.util.ArrayUtils;
 
 import java.lang.annotation.Retention;
@@ -61,7 +59,6 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
-import java.util.concurrent.Executor;
 import java.util.stream.Collectors;
 
 /**
@@ -153,9 +150,6 @@
     // device.
     private final boolean mIsAskEverytimeSupportedForSms;
 
-    // The number of existing DataSettingsControllerCallback
-    private int mCallbacksCount;
-
     private static final String SETTING_USER_PREF_DATA_SUB = "user_preferred_data_sub";
 
     private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@@ -171,37 +165,6 @@
         }
     };
 
-    private static class DataSettingsControllerCallback extends DataSettingsManagerCallback {
-        private final Phone mPhone;
-
-        DataSettingsControllerCallback(@NonNull Phone phone,
-                @NonNull @CallbackExecutor Executor executor) {
-            super(executor);
-            mPhone = phone;
-        }
-
-        @Override
-        public void onDataEnabledChanged(boolean enabled,
-                @TelephonyManager.DataEnabledChangedReason int reason, String callingPackage) {
-            int subId = mPhone.getSubId();
-            // notifyUserDataEnabled if the change is called from external and reason is
-            // DATA_ENABLED_REASON_USER
-            if (SubscriptionManager.isValidSubscriptionId(subId)
-                    && reason == TelephonyManager.DATA_ENABLED_REASON_USER
-                    && !getInstance().mContext.getOpPackageName().equals(callingPackage)) {
-                getInstance().notifyUserDataEnabled(mPhone.getSubId(), enabled);
-            }
-        }
-
-        @Override
-        public void onDataRoamingEnabledChanged(boolean enabled) {
-            int subId = mPhone.getSubId();
-            if (SubscriptionManager.isValidSubscriptionId(subId)) {
-                getInstance().notifyRoamingDataEnabled(mPhone.getSubId(), enabled);
-            }
-        }
-    }
-
     /**
      * Return the singleton or create one if not existed.
      */
@@ -390,7 +353,6 @@
             }
             reEvaluateAll();
         }
-        registerDataSettingsControllerCallbackAsNeeded();
     }
 
     /**
@@ -454,11 +416,7 @@
         reEvaluateAll();
     }
 
-    /**
-     * Check whether carrier config loaded for all subs
-     */
-    @VisibleForTesting
-    public boolean isCarrierConfigLoadedForAllSub() {
+    private boolean isCarrierConfigLoadedForAllSub() {
         int[] activeSubIds = mSubController.getActiveSubIdList(false);
         for (int activeSubId : activeSubIds) {
             boolean isLoaded = false;
@@ -486,7 +444,6 @@
         for (Phone phone : PhoneFactory.getPhones()) {
             phone.mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
         }
-        registerDataSettingsControllerCallbackAsNeeded();
     }
 
     /**
@@ -768,12 +725,8 @@
                 && (!dataSelected || !smsSelected || !voiceSelected)) {
             dialogType = EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL;
         } else if (mPrimarySubList.size() > 1 && (isUserVisibleChange(change)
-                || (change == PRIMARY_SUB_INITIALIZED && !dataSelected
-                && Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.DEVICE_PROVISIONED, 0) != 0))) {
+                || (change == PRIMARY_SUB_INITIALIZED && !dataSelected))) {
             // If change is SWAPPED_IN_GROUP or MARKED_OPPT, don't ask user again.
-            // In default DSDS devices, do not show data selection dialog during SuW as there is
-            // fullscreen activity to choose data preference.
             dialogType = EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA;
         }
 
@@ -837,14 +790,8 @@
                     && phone.isUserDataEnabled()
                     && !areSubscriptionsInSameGroup(defaultDataSub, phone.getSubId())) {
                 log("setting data to false on " + phone.getSubId());
-                if (phone.isUsingNewDataStack()) {
-                    phone.getDataSettingsManager().setDataEnabled(
-                            TelephonyManager.DATA_ENABLED_REASON_USER, false,
-                            mContext.getOpPackageName());
-                } else {
-                    phone.getDataEnabledSettings().setDataEnabled(
-                            TelephonyManager.DATA_ENABLED_REASON_USER, false);
-                }
+                phone.getDataEnabledSettings().setDataEnabled(
+                        TelephonyManager.DATA_ENABLED_REASON_USER, false);
             }
         }
     }
@@ -875,18 +822,12 @@
             int currentSubId = info.getSubscriptionId();
             // TODO: simplify when setUserDataEnabled becomes singleton
             if (mSubController.isActiveSubId(currentSubId)) {
-                // For active subscription, call setUserDataEnabled through DataSettingsManager.
+                // For active subscription, call setUserDataEnabled through DataEnabledSettings.
                 Phone phone = PhoneFactory.getPhone(mSubController.getPhoneId(currentSubId));
                 // If enable is true and it's not opportunistic subscription, we don't enable it,
-                // as there can't be two
+                // as there can't e two
                 if (phone != null) {
-                    if (phone.isUsingNewDataStack()) {
-                        phone.getDataSettingsManager().setDataEnabled(
-                                TelephonyManager.DATA_ENABLED_REASON_USER, enable,
-                                mContext.getOpPackageName());
-                    } else {
-                        phone.getDataEnabledSettings().setUserDataEnabled(enable, false);
-                    }
+                    phone.getDataEnabledSettings().setUserDataEnabled(enable, false);
                 }
             } else {
                 // For inactive subscription, directly write into global settings.
@@ -982,7 +923,7 @@
             EuiccManager euiccManager = (EuiccManager)
                     mContext.getSystemService(Context.EUICC_SERVICE);
             euiccManager.switchToSubscription(SubscriptionManager.INVALID_SUBSCRIPTION_ID,
-                    info.getPortIndex(), PendingIntent.getService(
+                    PendingIntent.getService(
                             mContext, 0, new Intent(), PendingIntent.FLAG_IMMUTABLE));
         }
     }
@@ -1056,19 +997,6 @@
         return true;
     }
 
-    private void registerDataSettingsControllerCallbackAsNeeded() {
-        // Only register callbacks for new phone instance as PhoneFactory does not remove
-        // existing phone instance.
-        Phone[] phones = PhoneFactory.getPhones();
-        for (int i = mCallbacksCount; i < phones.length; i++) {
-            if (phones[i].isUsingNewDataStack()) {
-                phones[i].getDataSettingsManager().registerCallback(
-                        new DataSettingsControllerCallback(phones[i], this::post));
-            }
-        }
-        mCallbacksCount = phones.length;
-    }
-
     private void log(String msg) {
         Log.d(LOG_TAG, msg);
     }
diff --git a/src/java/com/android/internal/telephony/NetworkIndication.java b/src/java/com/android/internal/telephony/NetworkIndication.java
deleted file mode 100644
index 17d906e..0000000
--- a/src/java/com/android/internal/telephony/NetworkIndication.java
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
-
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_PRL_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CELL_INFO_LIST;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_LCEDATA_RECV;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_NETWORK_SCAN_RESULT;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_NITZ_TIME_RECEIVED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESTRICTED_STATE_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIGNAL_STRENGTH;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SUPP_SVC_NOTIFICATION;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_VOICE_RADIO_TECH_CHANGED;
-
-import android.annotation.ElapsedRealtimeLong;
-import android.hardware.radio.network.IRadioNetworkIndication;
-import android.os.AsyncResult;
-import android.sysprop.TelephonyProperties;
-import android.telephony.AnomalyReporter;
-import android.telephony.BarringInfo;
-import android.telephony.CellIdentity;
-import android.telephony.CellInfo;
-import android.telephony.LinkCapacityEstimate;
-import android.telephony.NetworkRegistrationInfo;
-import android.telephony.PhysicalChannelConfig;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.gsm.SuppServiceNotification;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.UUID;
-
-/**
- * Interface declaring unsolicited radio indications for network APIs.
- */
-public class NetworkIndication extends IRadioNetworkIndication.Stub {
-    private final RIL mRil;
-
-    public NetworkIndication(RIL ril) {
-        mRil = ril;
-    }
-
-    /**
-     * Indicate that BarringInfo has changed for the current cell and user.
-     * @param indicationType Type of radio indication
-     * @param cellIdentity the CellIdentity of the Cell
-     * @param barringInfos the updated barring information from the current cell, filtered for the
-     *        current PLMN and access class / access category.
-     */
-    public void barringInfoChanged(int indicationType,
-            android.hardware.radio.network.CellIdentity cellIdentity,
-            android.hardware.radio.network.BarringInfo[] barringInfos) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-
-        if (cellIdentity == null || barringInfos == null) {
-            reportAnomaly(UUID.fromString("645b16bb-c930-4c1c-9c5d-568696542e05"),
-                    "Invalid barringInfoChanged indication");
-            mRil.riljLoge("Invalid barringInfoChanged indication");
-            return;
-        }
-
-        BarringInfo cbi = new BarringInfo(RILUtils.convertHalCellIdentity(cellIdentity),
-                RILUtils.convertHalBarringInfoList(barringInfos));
-
-        mRil.mBarringInfoChangedRegistrants.notifyRegistrants(new AsyncResult(null, cbi, null));
-    }
-
-    /**
-     * Indicates when PRL (preferred roaming list) changes.
-     * @param indicationType Type of radio indication
-     * @param version PRL version after PRL changes
-     */
-    public void cdmaPrlChanged(int indicationType, int version) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-
-        int[] response = new int[]{version};
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CDMA_PRL_CHANGED, response);
-
-        mRil.mCdmaPrlChangedRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
-    }
-
-    /**
-     * Report all of the current cell information known to the radio.
-     * @param indicationType Type of radio indication
-     * @param records Current cell information
-     */
-    public void cellInfoList(int indicationType,
-            android.hardware.radio.network.CellInfo[] records) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-        ArrayList<CellInfo> response = RILUtils.convertHalCellInfoList(records);
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CELL_INFO_LIST, response);
-        mRil.mRilCellInfoListRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
-    }
-
-    /**
-     * Indicates current link capacity estimate.
-     * @param indicationType Type of radio indication
-     * @param lce LinkCapacityEstimate
-     */
-    public void currentLinkCapacityEstimate(int indicationType,
-            android.hardware.radio.network.LinkCapacityEstimate lce) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-
-        List<LinkCapacityEstimate> response = RILUtils.convertHalLceData(lce);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_LCEDATA_RECV, response);
-
-        if (mRil.mLceInfoRegistrants != null) {
-            mRil.mLceInfoRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
-        }
-    }
-
-    /**
-     * Indicates current physical channel configuration.
-     * @param indicationType Type of radio indication
-     * @param configs Vector of PhysicalChannelConfigs
-     */
-    public void currentPhysicalChannelConfigs(int indicationType,
-            android.hardware.radio.network.PhysicalChannelConfig[] configs) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-        List<PhysicalChannelConfig> response = new ArrayList<>(configs.length);
-        try {
-            for (android.hardware.radio.network.PhysicalChannelConfig config : configs) {
-                PhysicalChannelConfig.Builder builder = new PhysicalChannelConfig.Builder();
-                switch (config.band.getTag()) {
-                    case android.hardware.radio.network.PhysicalChannelConfigBand.geranBand:
-                        builder.setBand(config.band.getGeranBand());
-                        break;
-                    case android.hardware.radio.network.PhysicalChannelConfigBand.utranBand:
-                        builder.setBand(config.band.getUtranBand());
-                        break;
-                    case android.hardware.radio.network.PhysicalChannelConfigBand.eutranBand:
-                        builder.setBand(config.band.getEutranBand());
-                        break;
-                    case android.hardware.radio.network.PhysicalChannelConfigBand.ngranBand:
-                        builder.setBand(config.band.getNgranBand());
-                        break;
-                    default:
-                        mRil.riljLoge("Unsupported band type " + config.band.getTag());
-                }
-                response.add(builder.setCellConnectionStatus(
-                        RILUtils.convertHalCellConnectionStatus(config.status))
-                        .setDownlinkChannelNumber(config.downlinkChannelNumber)
-                        .setUplinkChannelNumber(config.uplinkChannelNumber)
-                        .setCellBandwidthDownlinkKhz(config.cellBandwidthDownlinkKhz)
-                        .setCellBandwidthUplinkKhz(config.cellBandwidthUplinkKhz)
-                        .setNetworkType(ServiceState.rilRadioTechnologyToNetworkType(config.rat))
-                        .setPhysicalCellId(config.physicalCellId)
-                        .setContextIds(config.contextIds)
-                        .build());
-            }
-        } catch (IllegalArgumentException iae) {
-            reportAnomaly(UUID.fromString("918f0970-9aa9-4bcd-a28e-e49a83fe77d5"),
-                    "RIL reported invalid PCC (AIDL)");
-            mRil.riljLoge("Invalid PhysicalChannelConfig " + iae);
-            return;
-        }
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG, response);
-
-        mRil.mPhysicalChannelConfigurationRegistrants.notifyRegistrants(
-                new AsyncResult(null, response, null));
-    }
-
-    /**
-     * Indicates current signal strength of the radio.
-     * @param indicationType Type of radio indication
-     * @param signalStrength SignalStrength information
-     */
-    public void currentSignalStrength(int indicationType,
-            android.hardware.radio.network.SignalStrength signalStrength) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-
-        SignalStrength ssInitial = RILUtils.convertHalSignalStrength(signalStrength);
-
-        SignalStrength ss = mRil.fixupSignalStrength10(ssInitial);
-        // Note this is set to "verbose" because it happens frequently
-        if (RIL.RILJ_LOGV) mRil.unsljLogvRet(RIL_UNSOL_SIGNAL_STRENGTH, ss);
-
-        if (mRil.mSignalStrengthRegistrant != null) {
-            mRil.mSignalStrengthRegistrant.notifyRegistrant(new AsyncResult(null, ss, null));
-        }
-    }
-
-    /**
-     * Indicates when IMS registration state has changed.
-     * @param indicationType Type of radio indication
-     */
-    public void imsNetworkStateChanged(int indicationType) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED);
-
-        mRil.mImsNetworkStateChangedRegistrants.notifyRegistrants();
-    }
-
-    /**
-     * Incremental network scan results.
-     * @param indicationType Type of radio indication
-     * @param result the result of the network scan
-     */
-    public void networkScanResult(int indicationType,
-            android.hardware.radio.network.NetworkScanResult result) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-
-        ArrayList<CellInfo> cellInfos = RILUtils.convertHalCellInfoList(result.networkInfos);
-        NetworkScanResult nsr = new NetworkScanResult(result.status, result.error, cellInfos);
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_NETWORK_SCAN_RESULT, nsr);
-        mRil.mRilNetworkScanResultRegistrants.notifyRegistrants(new AsyncResult(null, nsr, null));
-    }
-
-    /**
-     * Indicates when either voice or data network state changed
-     * @param indicationType Type of radio indication
-     */
-    public void networkStateChanged(int indicationType) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED);
-
-        mRil.mNetworkStateRegistrants.notifyRegistrants();
-    }
-
-    /**
-     * Indicates when radio has received a NITZ time message.
-     * @param indicationType Type of radio indication
-     * @param nitzTime NITZ time string in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt"
-     * @param receivedTimeMs time according to {@link android.os.SystemClock#elapsedRealtime()} when
-     *        the RIL sent the NITZ time to the framework
-     * @param ageMs time in milliseconds indicating how long NITZ was cached in RIL and modem.
-     *        This must track true age and therefore must be calculated using clocks that
-     *        include the time spend in sleep / low power states. If it can not be guaranteed,
-     *        there must not be any caching done at the modem and should fill in 0 for ageMs
-     */
-    public void nitzTimeReceived(int indicationType, String nitzTime,
-        @ElapsedRealtimeLong long receivedTimeMs, long ageMs) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_NITZ_TIME_RECEIVED, nitzTime);
-
-        // Ignore the NITZ if receivedTimeMs or ageMs is not a valid time.
-        // e.g. receivedTimeMs is non-positive, ageMs is negative or greater than receivedTimeMs.
-        if ((receivedTimeMs <= 0) || (ageMs < 0) || (ageMs >= receivedTimeMs)) {
-            reportAnomaly(UUID.fromString("fc7c56d4-485d-475a-aaff-394203c6cdfc"),
-                    "NITZ indication with invalid parameter");
-
-            mRil.riljLoge("NITZ parameter is invalid, ignoring nitzTimeReceived indication. "
-                + "receivedTimeMs = " + receivedTimeMs + ", ageMs = " + ageMs);
-            return;
-        }
-
-        // TODO: Clean this up with a parcelable class for better self-documentation
-        Object[] result = new Object[3];
-        result[0] = nitzTime;
-        result[1] = receivedTimeMs;
-        result[2] = ageMs;
-
-        boolean ignoreNitz = TelephonyProperties.ignore_nitz().orElse(false);
-
-        if (ignoreNitz) {
-            if (RIL.RILJ_LOGD) mRil.riljLog("ignoring UNSOL_NITZ_TIME_RECEIVED");
-        } else {
-            if (mRil.mNITZTimeRegistrant != null) {
-                mRil.mNITZTimeRegistrant.notifyRegistrant(new AsyncResult(null, result, null));
-            }
-            // in case NITZ time registrant isn't registered yet, or a new registrant
-            // registers later
-            mRil.mLastNITZTimeInfo = result;
-        }
-    }
-
-    /**
-     * Indicate that a registration failure has occurred.
-     * @param cellIdentity a CellIdentity the CellIdentity of the Cell
-     * @param chosenPlmn a 5 or 6 digit alphanumeric string indicating the PLMN on which
-     *        registration failed
-     * @param domain the domain of the failed procedure: CS, PS, or both
-     * @param causeCode the primary failure cause code of the procedure
-     * @param additionalCauseCode an additional cause code if applicable
-     */
-    public void registrationFailed(int indicationType,
-            android.hardware.radio.network.CellIdentity cellIdentity, String chosenPlmn,
-            @NetworkRegistrationInfo.Domain int domain, int causeCode, int additionalCauseCode) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-        CellIdentity ci = RILUtils.convertHalCellIdentity(cellIdentity);
-        if (ci == null || TextUtils.isEmpty(chosenPlmn)
-                || (domain & NetworkRegistrationInfo.DOMAIN_CS_PS) == 0
-                || (domain & ~NetworkRegistrationInfo.DOMAIN_CS_PS) != 0
-                || causeCode < 0 || additionalCauseCode < 0
-                || (causeCode == Integer.MAX_VALUE && additionalCauseCode == Integer.MAX_VALUE)) {
-            reportAnomaly(UUID.fromString("f16e5703-6105-4341-9eb3-e68189156eb4"),
-                    "Invalid registrationFailed indication");
-
-            mRil.riljLoge("Invalid registrationFailed indication");
-            return;
-        }
-
-        mRil.mRegistrationFailedRegistrant.notifyRegistrant(
-                new AsyncResult(null, new RegistrationFailedEvent(
-                        ci, chosenPlmn, domain, causeCode, additionalCauseCode), null));
-    }
-
-    /**
-     * Indicates a restricted state change (eg, for Domain Specific Access Control).
-     * @param indicationType Type of radio indication
-     * @param state Bitmask of restricted state as defined by PhoneRestrictedState
-     */
-    public void restrictedStateChanged(int indicationType, int state) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogvRet(RIL_UNSOL_RESTRICTED_STATE_CHANGED, state);
-
-        if (mRil.mRestrictedStateRegistrant != null) {
-            mRil.mRestrictedStateRegistrant.notifyRegistrant(new AsyncResult(null, state, null));
-        }
-    }
-
-    /**
-     * Reports supplementary service related notification from the network.
-     * @param indicationType Type of radio indication
-     * @param suppSvcNotification SuppSvcNotification
-     */
-    public void suppSvcNotify(int indicationType,
-            android.hardware.radio.network.SuppSvcNotification suppSvcNotification) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-
-        SuppServiceNotification notification = new SuppServiceNotification();
-        notification.notificationType = suppSvcNotification.isMT ? 1 : 0;
-        notification.code = suppSvcNotification.code;
-        notification.index = suppSvcNotification.index;
-        notification.type = suppSvcNotification.type;
-        notification.number = suppSvcNotification.number;
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_SUPP_SVC_NOTIFICATION, notification);
-
-        if (mRil.mSsnRegistrant != null) {
-            mRil.mSsnRegistrant.notifyRegistrant(new AsyncResult(null, notification, null));
-        }
-    }
-
-    /**
-     * Indicates that voice technology has changed. Responds with new rat.
-     * @param indicationType Type of radio indication
-     * @param rat Current new voice rat
-     */
-    public void voiceRadioTechChanged(int indicationType, int rat) {
-        mRil.processIndication(RIL.NETWORK_SERVICE, indicationType);
-
-        int[] response = new int[] {rat};
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_VOICE_RADIO_TECH_CHANGED, response);
-
-        mRil.mVoiceRadioTechChangedRegistrants.notifyRegistrants(
-                new AsyncResult(null, response, null));
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return IRadioNetworkIndication.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return IRadioNetworkIndication.VERSION;
-    }
-
-    private void reportAnomaly(UUID uuid, String msg) {
-        Phone phone = mRil.mPhoneId == null ? null : PhoneFactory.getPhone(mRil.mPhoneId);
-        int carrierId = phone == null ? UNKNOWN_CARRIER_ID : phone.getCarrierId();
-        AnomalyReporter.reportAnomaly(uuid, msg, carrierId);
-    }
-}
diff --git a/src/java/com/android/internal/telephony/NetworkResponse.java b/src/java/com/android/internal/telephony/NetworkResponse.java
deleted file mode 100644
index d9f70fd..0000000
--- a/src/java/com/android/internal/telephony/NetworkResponse.java
+++ /dev/null
@@ -1,448 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.hardware.radio.RadioError;
-import android.hardware.radio.RadioResponseInfo;
-import android.hardware.radio.network.IRadioNetworkResponse;
-import android.os.AsyncResult;
-import android.telephony.BarringInfo;
-import android.telephony.CellInfo;
-import android.telephony.LinkCapacityEstimate;
-import android.telephony.RadioAccessSpecifier;
-import android.telephony.SignalStrength;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Interface declaring response functions to solicited radio requests for network APIs.
- */
-public class NetworkResponse extends IRadioNetworkResponse.Stub {
-    private final RIL mRil;
-
-    public NetworkResponse(RIL ril) {
-        mRil = ril;
-    }
-
-    /**
-     * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for
-     * radio request which take long time to respond.
-     * For more details, refer https://source.android.com/devices/tech/connect/ril.html
-     * @param serial Serial no. of the request whose acknowledgement is sent.
-     */
-    public void acknowledgeRequest(int serial) {
-        mRil.processRequestAck(serial);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param halRadioAccessFamilyBitmap a 32-bit bitmap of RadioAccessFamily.
-     */
-    public void getAllowedNetworkTypesBitmapResponse(RadioResponseInfo responseInfo,
-            int halRadioAccessFamilyBitmap) {
-        int networkTypeBitmask = RILUtils.convertHalNetworkTypeBitMask(halRadioAccessFamilyBitmap);
-        mRil.mAllowedNetworkTypesBitmask = networkTypeBitmask;
-        RadioResponse.responseInts(RIL.NETWORK_SERVICE, mRil, responseInfo, networkTypeBitmask);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param bandModes List of RadioBandMode listing supported modes
-     */
-    public void getAvailableBandModesResponse(RadioResponseInfo responseInfo, int[] bandModes) {
-        RadioResponse.responseIntArrayList(RIL.NETWORK_SERVICE, mRil, responseInfo,
-                RILUtils.primitiveArrayToArrayList(bandModes));
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param networkInfos List of network operator information as OperatorInfos
-     */
-    public void getAvailableNetworksResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.network.OperatorInfo[] networkInfos) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
-
-        if (rr != null) {
-            ArrayList<OperatorInfo> ret = new ArrayList<>();
-            for (android.hardware.radio.network.OperatorInfo info : networkInfos) {
-                ret.add(new OperatorInfo(info.alphaLong, info.alphaShort, info.operatorNumeric,
-                        RILUtils.convertHalOperatorStatus(info.status)));
-            }
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error.
-     * @param cellIdentity CellIdentity for the barringInfos.
-     * @param barringInfos List of BarringInfo for all the barring service types.
-     */
-    public void getBarringInfoResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.network.CellIdentity cellIdentity,
-            android.hardware.radio.network.BarringInfo[] barringInfos) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
-
-        if (rr != null) {
-            BarringInfo bi = new BarringInfo(RILUtils.convertHalCellIdentity(cellIdentity),
-                    RILUtils.convertHalBarringInfoList(barringInfos));
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, bi);
-                // notify all registrants for the possible barring info change
-                mRil.mBarringInfoChangedRegistrants.notifyRegistrants(
-                        new AsyncResult(null, bi, null));
-            }
-            mRil.processResponseDone(rr, responseInfo, bi);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param type CdmaRoamingType defined in types.hal
-     */
-    public void getCdmaRoamingPreferenceResponse(RadioResponseInfo responseInfo, int type) {
-        RadioResponse.responseInts(RIL.NETWORK_SERVICE, mRil, responseInfo, type);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param cellInfo List of current cell information known to radio
-     */
-    public void getCellInfoListResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.network.CellInfo[] cellInfo) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
-
-        if (rr != null) {
-            ArrayList<CellInfo> ret = RILUtils.convertHalCellInfoList(cellInfo);
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param dataRegResponse Current data registration response as defined by DataRegStateResult
-     */
-    public void getDataRegistrationStateResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.network.RegStateResult dataRegResponse) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
-
-        if (rr != null) {
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, dataRegResponse);
-            }
-            mRil.processResponseDone(rr, responseInfo, dataRegResponse);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param isRegistered false = not registered, true = registered
-     * @param ratFamily RadioTechnologyFamily. This value is valid only if isRegistered is true.
-     */
-    public void getImsRegistrationStateResponse(RadioResponseInfo responseInfo,
-            boolean isRegistered, int ratFamily) {
-        RadioResponse.responseInts(RIL.NETWORK_SERVICE, mRil, responseInfo, isRegistered ? 1 : 0,
-                ratFamily == android.hardware.radio.RadioTechnologyFamily.THREE_GPP
-                        ? PhoneConstants.PHONE_TYPE_GSM : PhoneConstants.PHONE_TYPE_CDMA);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param selection false for automatic selection, true for manual selection
-     */
-    public void getNetworkSelectionModeResponse(RadioResponseInfo responseInfo, boolean selection) {
-        RadioResponse.responseInts(RIL.NETWORK_SERVICE, mRil, responseInfo, selection ? 1 : 0);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param longName is long alpha ONS or EONS or empty string if unregistered
-     * @param shortName is short alpha ONS or EONS or empty string if unregistered
-     * @param numeric is 5 or 6 digit numeric code (MCC + MNC) or empty string if unregistered
-     */
-    public void getOperatorResponse(RadioResponseInfo responseInfo, String longName,
-            String shortName, String numeric) {
-        RadioResponse.responseStrings(
-                RIL.NETWORK_SERVICE, mRil, responseInfo, longName, shortName, numeric);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param signalStrength Current signal strength of camped/connected cells
-     */
-    public void getSignalStrengthResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.network.SignalStrength signalStrength) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
-
-        if (rr != null) {
-            SignalStrength ret = RILUtils.convertHalSignalStrength(signalStrength);
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error.
-     * @param halSpecifiers List of RadioAccessSpecifiers that are scanned.
-     */
-    public void getSystemSelectionChannelsResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.network.RadioAccessSpecifier[] halSpecifiers) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
-
-        if (rr != null) {
-            ArrayList<RadioAccessSpecifier> specifiers = new ArrayList<>();
-            for (android.hardware.radio.network.RadioAccessSpecifier specifier : halSpecifiers) {
-                specifiers.add(RILUtils.convertHalRadioAccessSpecifier(specifier));
-            }
-            mRil.riljLog("getSystemSelectionChannelsResponse: from AIDL: " + specifiers);
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, specifiers);
-            }
-            mRil.processResponseDone(rr, responseInfo, specifiers);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param rat Current voice RAT
-     */
-    public void getVoiceRadioTechnologyResponse(RadioResponseInfo responseInfo, int rat) {
-        RadioResponse.responseInts(RIL.NETWORK_SERVICE, mRil, responseInfo, rat);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param voiceRegResponse Current Voice registration response as defined by VoiceRegStateResult
-     */
-    public void getVoiceRegistrationStateResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.network.RegStateResult voiceRegResponse) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
-        if (rr != null) {
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, voiceRegResponse);
-            }
-            mRil.processResponseDone(rr, responseInfo, voiceRegResponse);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param isEnabled Indicates whether NR dual connectivity is enabled or not, True if enabled
-     *        else false.
-     */
-    public void isNrDualConnectivityEnabledResponse(RadioResponseInfo responseInfo,
-            boolean isEnabled) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
-
-        if (rr != null) {
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, isEnabled);
-            }
-            mRil.processResponseDone(rr, responseInfo, isEnabled);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param lceInfo LceDataInfo indicating LCE data
-     */
-    public void pullLceDataResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.network.LceDataInfo lceInfo) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
-
-        if (rr != null) {
-            List<LinkCapacityEstimate> ret = RILUtils.convertHalLceData(lceInfo);
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setAllowedNetworkTypesBitmapResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setBandModeResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setBarringPasswordResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setCdmaRoamingPreferenceResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setCellInfoListRateResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setIndicationFilterResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setLinkCapacityReportingCriteriaResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setLocationUpdatesResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setNetworkSelectionModeAutomaticResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setNetworkSelectionModeManualResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setNrDualConnectivityStateResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setSignalStrengthReportingCriteriaResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setSuppServiceNotificationsResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial number and error.
-     */
-    public void setSystemSelectionChannelsResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void startNetworkScanResponse(RadioResponseInfo responseInfo) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
-        if (rr != null) {
-            NetworkScanResult nsr = null;
-            if (responseInfo.error == RadioError.NONE) {
-                nsr = new NetworkScanResult(NetworkScanResult.SCAN_STATUS_PARTIAL,
-                        RadioError.NONE, null);
-                RadioResponse.sendMessageResponse(rr.mResult, nsr);
-            }
-            mRil.processResponseDone(rr, responseInfo, nsr);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void stopNetworkScanResponse(RadioResponseInfo responseInfo) {
-        RILRequest rr = mRil.processResponse(RIL.NETWORK_SERVICE, responseInfo);
-        if (rr != null) {
-            NetworkScanResult nsr = null;
-            if (responseInfo.error == RadioError.NONE) {
-                nsr = new NetworkScanResult(NetworkScanResult.SCAN_STATUS_PARTIAL,
-                        RadioError.NONE, null);
-                RadioResponse.sendMessageResponse(rr.mResult, nsr);
-            }
-            mRil.processResponseDone(rr, responseInfo, nsr);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param retriesRemaining Number of retries remaining, must be equal to -1 if unknown.
-     */
-    public void supplyNetworkDepersonalizationResponse(RadioResponseInfo responseInfo,
-            int retriesRemaining) {
-        RadioResponse.responseInts(RIL.NETWORK_SERVICE, mRil, responseInfo, retriesRemaining);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setUsageSettingResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.NETWORK_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param usageSetting the cellular usage setting
-     */
-    public void getUsageSettingResponse(RadioResponseInfo responseInfo,
-            /* @TelephonyManager.UsageSetting */ int usageSetting) {
-        RadioResponse.responseInts(RIL.NETWORK_SERVICE, mRil, responseInfo, usageSetting);
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return IRadioNetworkResponse.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return IRadioNetworkResponse.VERSION;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java b/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
index ea68cba..92f552a 100644
--- a/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
+++ b/src/java/com/android/internal/telephony/NetworkScanRequestTracker.java
@@ -259,13 +259,11 @@
         private final int mScanId;
         private final int mUid;
         private final int mPid;
-        private boolean mRenounceFineLocationAccess;
         private final String mCallingPackage;
         private boolean mIsBinderDead;
 
         NetworkScanRequestInfo(NetworkScanRequest r, Messenger m, IBinder b, int id, Phone phone,
-                int callingUid, int callingPid, String callingPackage,
-                boolean renounceFineLocationAccess) {
+                int callingUid, int callingPid, String callingPackage) {
             super();
             mRequest = r;
             mMessenger = m;
@@ -276,7 +274,6 @@
             mPid = callingPid;
             mCallingPackage = callingPackage;
             mIsBinderDead = false;
-            mRenounceFineLocationAccess = renounceFineLocationAccess;
 
             try {
                 mBinder.linkToDeath(this, 0);
@@ -456,8 +453,7 @@
                     .build();
             if (ar.exception == null && ar.result != null) {
                 NetworkScanResult nsr = (NetworkScanResult) ar.result;
-                boolean isLocationAccessAllowed = !nsri.mRenounceFineLocationAccess
-                        && LocationAccessPolicy.checkLocationPermission(
+                boolean isLocationAccessAllowed = LocationAccessPolicy.checkLocationPermission(
                         nsri.mPhone.getContext(), locationQuery)
                         == LocationAccessPolicy.LocationPermissionResult.ALLOWED;
                 int notifyMsg = isLocationAccessAllowed
@@ -632,13 +628,12 @@
      * returned to the user, no matter how this scan will be actually handled.
      */
     public int startNetworkScan(
-            boolean renounceFineLocationAccess, NetworkScanRequest request, Messenger messenger,
-            IBinder binder, Phone phone,
+            NetworkScanRequest request, Messenger messenger, IBinder binder, Phone phone,
             int callingUid, int callingPid, String callingPackage) {
         int scanId = mNextNetworkScanRequestId.getAndIncrement();
         NetworkScanRequestInfo nsri =
                 new NetworkScanRequestInfo(request, messenger, binder, scanId, phone,
-                        callingUid, callingPid, callingPackage, renounceFineLocationAccess);
+                        callingUid, callingPid, callingPackage);
         // nsri will be stored as Message.obj
         mHandler.obtainMessage(CMD_START_NETWORK_SCAN, nsri).sendToTarget();
         return scanId;
diff --git a/src/java/com/android/internal/telephony/NetworkTypeController.java b/src/java/com/android/internal/telephony/NetworkTypeController.java
index 2260d34..a1724a6 100644
--- a/src/java/com/android/internal/telephony/NetworkTypeController.java
+++ b/src/java/com/android/internal/telephony/NetworkTypeController.java
@@ -23,7 +23,6 @@
 import android.os.AsyncResult;
 import android.os.Message;
 import android.os.PersistableBundle;
-import android.os.PowerManager;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.Annotation;
 import android.telephony.CarrierConfigManager;
@@ -35,12 +34,11 @@
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataCallResponse.LinkStatus;
 import android.text.TextUtils;
 
-import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
 import com.android.internal.telephony.dataconnection.DataConnection;
+import com.android.internal.telephony.dataconnection.DcController;
+import com.android.internal.telephony.dataconnection.DcController.PhysicalLinkState;
 import com.android.internal.telephony.dataconnection.DcTracker;
 import com.android.internal.telephony.util.ArrayUtils;
 import com.android.internal.util.IState;
@@ -90,7 +88,7 @@
     private static final int EVENT_DATA_RAT_CHANGED = 2;
     private static final int EVENT_NR_STATE_CHANGED = 3;
     private static final int EVENT_NR_FREQUENCY_CHANGED = 4;
-    private static final int EVENT_PHYSICAL_LINK_STATUS_CHANGED = 5;
+    private static final int EVENT_PHYSICAL_LINK_STATE_CHANGED = 5;
     private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED = 6;
     private static final int EVENT_CARRIER_CONFIG_CHANGED = 7;
     private static final int EVENT_PRIMARY_TIMER_EXPIRED = 8;
@@ -100,18 +98,15 @@
     private static final int EVENT_INITIALIZE = 12;
     private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED = 13;
     private static final int EVENT_PCO_DATA_CHANGED = 14;
-    private static final int EVENT_BANDWIDTH_CHANGED = 15;
-    private static final int EVENT_UPDATE_NR_ADVANCED_STATE = 16;
-    private static final int EVENT_DEVICE_IDLE_MODE_CHANGED = 17;
 
-    private static final String[] sEvents = new String[EVENT_DEVICE_IDLE_MODE_CHANGED + 1];
+    private static final String[] sEvents = new String[EVENT_PCO_DATA_CHANGED + 1];
     static {
         sEvents[EVENT_UPDATE] = "EVENT_UPDATE";
         sEvents[EVENT_QUIT] = "EVENT_QUIT";
         sEvents[EVENT_DATA_RAT_CHANGED] = "EVENT_DATA_RAT_CHANGED";
         sEvents[EVENT_NR_STATE_CHANGED] = "EVENT_NR_STATE_CHANGED";
         sEvents[EVENT_NR_FREQUENCY_CHANGED] = "EVENT_NR_FREQUENCY_CHANGED";
-        sEvents[EVENT_PHYSICAL_LINK_STATUS_CHANGED] = "EVENT_PHYSICAL_LINK_STATUS_CHANGED";
+        sEvents[EVENT_PHYSICAL_LINK_STATE_CHANGED] = "EVENT_PHYSICAL_LINK_STATE_CHANGED";
         sEvents[EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED] =
                 "EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED";
         sEvents[EVENT_CARRIER_CONFIG_CHANGED] = "EVENT_CARRIER_CONFIG_CHANGED";
@@ -122,9 +117,6 @@
         sEvents[EVENT_INITIALIZE] = "EVENT_INITIALIZE";
         sEvents[EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED] = "EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED";
         sEvents[EVENT_PCO_DATA_CHANGED] = "EVENT_PCO_DATA_CHANGED";
-        sEvents[EVENT_BANDWIDTH_CHANGED] = "EVENT_BANDWIDTH_CHANGED";
-        sEvents[EVENT_UPDATE_NR_ADVANCED_STATE] = "EVENT_UPDATE_NR_ADVANCED_STATE";
-        sEvents[EVENT_DEVICE_IDLE_MODE_CHANGED] = "EVENT_DEVICE_IDLE_MODE_CHANGED";
     }
 
     private final Phone mPhone;
@@ -132,18 +124,12 @@
     private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            switch (intent.getAction()) {
-                case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
-                    if (intent.getIntExtra(SubscriptionManager.EXTRA_SLOT_INDEX,
-                            SubscriptionManager.INVALID_PHONE_INDEX) == mPhone.getPhoneId()
-                            && !intent.getBooleanExtra(
-                                    CarrierConfigManager.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
-                        sendMessage(EVENT_CARRIER_CONFIG_CHANGED);
-                    }
-                    break;
-                case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
-                    sendMessage(EVENT_DEVICE_IDLE_MODE_CHANGED);
-                    break;
+            if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)
+                    && intent.getIntExtra(SubscriptionManager.EXTRA_SLOT_INDEX,
+                    SubscriptionManager.INVALID_PHONE_INDEX) == mPhone.getPhoneId()
+                    && !intent.getBooleanExtra(CarrierConfigManager.EXTRA_REBROADCAST_ON_UNLOCK,
+                    false)) {
+                sendMessage(EVENT_CARRIER_CONFIG_CHANGED);
             }
         }
     };
@@ -156,18 +142,15 @@
     private boolean mIsSecondaryTimerActive;
     private boolean mIsTimerResetEnabledForLegacyStateRRCIdle;
     private int mLtePlusThresholdBandwidth;
-    private int mNrAdvancedThresholdBandwidth;
     private int[] mAdditionalNrAdvancedBandsList;
     private String mPrimaryTimerState;
     private String mSecondaryTimerState;
     private String mPreviousState;
-    private @LinkStatus int mPhysicalLinkStatus;
+    private @PhysicalLinkState int mPhysicalLinkState;
     private boolean mIsPhysicalChannelConfig16Supported;
-    private boolean mIsNrAdvancedAllowedByPco = false;
+    private Boolean mIsNrAdvancedAllowedByPco = false;
     private int mNrAdvancedCapablePcoId = 0;
     private boolean mIsUsingUserDataForRrcDetection = false;
-    private boolean mEnableNrAdvancedWhileRoaming = true;
-    private boolean mIsDeviceIdleMode = false;
 
     /**
      * NetworkTypeController constructor.
@@ -217,11 +200,14 @@
         mPhone.getServiceStateTracker().registerForDataRegStateOrRatChanged(
                 AccessNetworkConstants.TRANSPORT_TYPE_WWAN, getHandler(),
                 EVENT_DATA_RAT_CHANGED, null);
-        mPhone.getServiceStateTracker().registerForBandwidthChanged(
-                getHandler(), EVENT_BANDWIDTH_CHANGED, null);
         mIsPhysicalChannelConfig16Supported = mPhone.getContext().getSystemService(
                 TelephonyManager.class).isRadioInterfaceCapabilitySupported(
                 TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
+        if (!mIsPhysicalChannelConfig16Supported) {
+            mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                    .registerForPhysicalLinkStateChanged(getHandler(),
+                            EVENT_PHYSICAL_LINK_STATE_CHANGED);
+        }
         mPhone.getServiceStateTracker().registerForNrStateChanged(getHandler(),
                 EVENT_NR_STATE_CHANGED, null);
         mPhone.getServiceStateTracker().registerForNrFrequencyChanged(getHandler(),
@@ -230,11 +216,8 @@
                 EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED, null);
         IntentFilter filter = new IntentFilter();
         filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        filter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
         mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
-        if (!mPhone.isUsingNewDataStack()) {
-            mPhone.mCi.registerForPcoData(getHandler(), EVENT_PCO_DATA_CHANGED, null);
-        }
+        mPhone.mCi.registerForPcoData(getHandler(), EVENT_PCO_DATA_CHANGED, null);
     }
 
     private void unRegisterForAllEvents() {
@@ -246,9 +229,7 @@
         mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler());
         mPhone.getDeviceStateMonitor().unregisterForPhysicalChannelConfigNotifChanged(getHandler());
         mPhone.getContext().unregisterReceiver(mIntentReceiver);
-        if (!mPhone.isUsingNewDataStack()) {
-            mPhone.mCi.unregisterForPcoData(getHandler());
-        }
+        mPhone.mCi.unregisterForPcoData(getHandler());
     }
 
     private void parseCarrierConfigs() {
@@ -265,10 +246,6 @@
                         CarrierConfigManager.KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL);
         mLtePlusThresholdBandwidth = CarrierConfigManager.getDefaultConfig().getInt(
                 CarrierConfigManager.KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT);
-        mNrAdvancedThresholdBandwidth = CarrierConfigManager.getDefaultConfig().getInt(
-                CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT);
-        mEnableNrAdvancedWhileRoaming = CarrierConfigManager.getDefaultConfig().getBoolean(
-                CarrierConfigManager.KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL);
 
         CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
                 .getSystemService(Context.CARRIER_CONFIG_SERVICE);
@@ -299,45 +276,16 @@
                 mLtePlusThresholdBandwidth = b.getInt(
                         CarrierConfigManager.KEY_LTE_PLUS_THRESHOLD_BANDWIDTH_KHZ_INT,
                         mLtePlusThresholdBandwidth);
-                mNrAdvancedThresholdBandwidth = b.getInt(
-                        CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT,
-                        mNrAdvancedThresholdBandwidth);
                 mAdditionalNrAdvancedBandsList = b.getIntArray(
                         CarrierConfigManager.KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY);
                 mNrAdvancedCapablePcoId = b.getInt(
                         CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT);
-                if (mNrAdvancedCapablePcoId > 0 && mPhone.isUsingNewDataStack()) {
-                    mPhone.getDataNetworkController().registerDataNetworkControllerCallback(
-                            new DataNetworkControllerCallback(getHandler()::post) {
-                                @Override
-                                public void onNrAdvancedCapableByPcoChanged(
-                                        boolean nrAdvancedCapable) {
-                                    log("mIsNrAdvancedAllowedByPco=" + nrAdvancedCapable);
-                                    mIsNrAdvancedAllowedByPco = nrAdvancedCapable;
-                                    sendMessage(EVENT_UPDATE_NR_ADVANCED_STATE);
-                                }
-                            });
-                }
-                mEnableNrAdvancedWhileRoaming = b.getBoolean(
-                        CarrierConfigManager.KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL);
                 mIsUsingUserDataForRrcDetection = b.getBoolean(
                         CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL);
-                if (!mIsPhysicalChannelConfig16Supported || mIsUsingUserDataForRrcDetection) {
-                    if (mPhone.isUsingNewDataStack()) {
-                        mPhone.getDataNetworkController().registerDataNetworkControllerCallback(
-                                new DataNetworkControllerCallback(getHandler()::post) {
-                                    @Override
-                                    public void onPhysicalLinkStatusChanged(
-                                            @LinkStatus int status) {
-                                        sendMessage(obtainMessage(
-                                                EVENT_PHYSICAL_LINK_STATUS_CHANGED,
-                                                new AsyncResult(null, status, null)));
-                                    }});
-                    } else {
-                        mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                                .registerForPhysicalLinkStatusChanged(getHandler(),
-                                        EVENT_PHYSICAL_LINK_STATUS_CHANGED);
-                    }
+                if (mIsPhysicalChannelConfig16Supported && mIsUsingUserDataForRrcDetection) {
+                    mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                            .registerForPhysicalLinkStateChanged(getHandler(),
+                                    EVENT_PHYSICAL_LINK_STATE_CHANGED);
                 }
             }
         }
@@ -451,7 +399,7 @@
         if (mIsPhysicalChannelConfigOn && (nrNsa || nrSa)) {
             // Process NR display network type
             displayNetworkType = getNrDisplayType(nrSa);
-            if (displayNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE && !nrSa) {
+            if (displayNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE) {
                 // Use LTE values if 5G values aren't defined
                 displayNetworkType = getLteDisplayType();
             }
@@ -470,10 +418,8 @@
         }
         // Icon display keys in order of priority
         List<String> keys = new ArrayList<>();
-        if (isNrSa) {
-            if (isNrAdvanced()) {
-                keys.add(STATE_CONNECTED_NR_ADVANCED);
-            }
+        if (isNrSa && isNrAdvanced()) {
+            keys.add(STATE_CONNECTED_NR_ADVANCED);
         } else {
             switch (mPhone.getServiceState().getNrState()) {
                 case NetworkRegistrationInfo.NR_STATE_CONNECTED:
@@ -543,12 +489,10 @@
             switch (msg.what) {
                 case EVENT_UPDATE:
                 case EVENT_PREFERRED_NETWORK_MODE_CHANGED:
-                    if (DBG) log("Reset timers since preferred network mode changed.");
                     resetAllTimers();
                     transitionToCurrentState();
                     break;
                 case EVENT_QUIT:
-                    if (DBG) log("Reset timers on state machine quitting.");
                     resetAllTimers();
                     unRegisterForAllEvents();
                     quit();
@@ -564,21 +508,16 @@
                 case EVENT_NR_STATE_CHANGED:
                 case EVENT_NR_FREQUENCY_CHANGED:
                 case EVENT_PCO_DATA_CHANGED:
-                case EVENT_UPDATE_NR_ADVANCED_STATE:
                     // ignored
                     break;
-                case EVENT_BANDWIDTH_CHANGED:
-                    // Update in case of LTE/LTE+ switch
-                    updateOverrideNetworkType();
-                    break;
                 case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
                     if (isUsingPhysicalChannelConfigForRrcDetection()) {
-                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
+                        mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig();
                     }
                     break;
-                case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
+                case EVENT_PHYSICAL_LINK_STATE_CHANGED:
                     AsyncResult ar = (AsyncResult) msg.obj;
-                    mPhysicalLinkStatus = (int) ar.result;
+                    mPhysicalLinkState = (int) ar.result;
                     break;
                 case EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED:
                     AsyncResult result = (AsyncResult) msg.obj;
@@ -587,47 +526,28 @@
                         log("mIsPhysicalChannelConfigOn changed to: " + mIsPhysicalChannelConfigOn);
                     }
                     if (!mIsPhysicalChannelConfigOn) {
-                        if (DBG) {
-                            log("Reset timers since physical channel config indications are off.");
-                        }
                         resetAllTimers();
                     }
                     transitionToCurrentState();
                     break;
                 case EVENT_CARRIER_CONFIG_CHANGED:
                     parseCarrierConfigs();
-                    if (DBG) log("Reset timers since carrier configurations changed.");
                     resetAllTimers();
                     transitionToCurrentState();
                     break;
                 case EVENT_PRIMARY_TIMER_EXPIRED:
-                    if (DBG) log("Primary timer expired for state: " + mPrimaryTimerState);
                     transitionWithSecondaryTimerTo((IState) msg.obj);
                     break;
                 case EVENT_SECONDARY_TIMER_EXPIRED:
-                    if (DBG) log("Secondary timer expired for state: " + mSecondaryTimerState);
                     mIsSecondaryTimerActive = false;
                     mSecondaryTimerState = "";
                     updateTimers();
                     updateOverrideNetworkType();
                     break;
                 case EVENT_RADIO_OFF_OR_UNAVAILABLE:
-                    if (DBG) log("Reset timers since radio is off or unavailable.");
                     resetAllTimers();
                     transitionTo(mLegacyState);
                     break;
-                case EVENT_DEVICE_IDLE_MODE_CHANGED:
-                    PowerManager pm = mPhone.getContext().getSystemService(PowerManager.class);
-                    mIsDeviceIdleMode = pm.isDeviceIdleMode();
-                    if (DBG) {
-                        log("mIsDeviceIdleMode changed to: " + mIsDeviceIdleMode);
-                    }
-                    if (mIsDeviceIdleMode) {
-                        if (DBG) log("Reset timers since device is in idle mode.");
-                        resetAllTimers();
-                    }
-                    transitionToCurrentState();
-                    break;
                 default:
                     throw new RuntimeException("Received invalid event: " + msg.what);
             }
@@ -647,7 +567,7 @@
      * This is the initial state.
      */
     private final class LegacyState extends State {
-        private boolean mIsNrRestricted = false;
+        private Boolean mIsNrRestricted = false;
 
         @Override
         public void enter() {
@@ -674,7 +594,7 @@
                                 ? mLteConnectedState : mIdleState);
                     } else {
                         if (!isLte(rat)) {
-                            if (DBG) log("Reset timers since 2G and 3G don't need NR timers.");
+                            // Rat is 3G or 2G, and it doesn't need NR timer.
                             resetAllTimers();
                         }
                         updateOverrideNetworkType();
@@ -697,20 +617,18 @@
                     break;
                 case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
                     if (isUsingPhysicalChannelConfigForRrcDetection()) {
-                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
+                        mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig();
                         if (mIsTimerResetEnabledForLegacyStateRRCIdle && !isPhysicalLinkActive()) {
-                            if (DBG) log("Reset timers since timer reset is enabled for RRC idle.");
                             resetAllTimers();
                         }
                     }
                     // Update in case of LTE/LTE+ switch
                     updateOverrideNetworkType();
                     break;
-                case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
+                case EVENT_PHYSICAL_LINK_STATE_CHANGED:
                     AsyncResult ar = (AsyncResult) msg.obj;
-                    mPhysicalLinkStatus = (int) ar.result;
+                    mPhysicalLinkState = (int) ar.result;
                     if (mIsTimerResetEnabledForLegacyStateRRCIdle && !isPhysicalLinkActive()) {
-                        if (DBG) log("Reset timers since timer reset is enabled for RRC idle.");
                         resetAllTimers();
                         updateOverrideNetworkType();
                     }
@@ -726,7 +644,7 @@
 
         @Override
         public String getName() {
-            return mIsNrRestricted ? STATE_RESTRICTED : STATE_LEGACY;
+            return mIsNrRestricted  ? STATE_RESTRICTED : STATE_LEGACY;
         }
     }
 
@@ -771,7 +689,7 @@
                     break;
                 case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
                     if (isUsingPhysicalChannelConfigForRrcDetection()) {
-                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
+                        mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig();
                         if (isNrNotRestricted()) {
                             // NOT_RESTRICTED_RRC_IDLE -> NOT_RESTRICTED_RRC_CON
                             if (isPhysicalLinkActive()) {
@@ -786,9 +704,9 @@
                     // Update in case of LTE/LTE+ switch
                     updateOverrideNetworkType();
                     break;
-                case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
+                case EVENT_PHYSICAL_LINK_STATE_CHANGED:
                     AsyncResult ar = (AsyncResult) msg.obj;
-                    mPhysicalLinkStatus = (int) ar.result;
+                    mPhysicalLinkState = (int) ar.result;
                     if (isNrNotRestricted()) {
                         // NOT_RESTRICTED_RRC_IDLE -> NOT_RESTRICTED_RRC_CON
                         if (isPhysicalLinkActive()) {
@@ -855,7 +773,7 @@
                     break;
                 case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
                     if (isUsingPhysicalChannelConfigForRrcDetection()) {
-                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
+                        mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig();
                         if (isNrNotRestricted()) {
                             // NOT_RESTRICTED_RRC_CON -> NOT_RESTRICTED_RRC_IDLE
                             if (!isPhysicalLinkActive()) {
@@ -870,9 +788,9 @@
                     // Update in case of LTE/LTE+ switch
                     updateOverrideNetworkType();
                     break;
-                case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
+                case EVENT_PHYSICAL_LINK_STATE_CHANGED:
                     AsyncResult ar = (AsyncResult) msg.obj;
-                    mPhysicalLinkStatus = (int) ar.result;
+                    mPhysicalLinkState = (int) ar.result;
                     if (isNrNotRestricted()) {
                         // NOT_RESTRICTED_RRC_CON -> NOT_RESTRICTED_RRC_IDLE
                         if (!isPhysicalLinkActive()) {
@@ -901,14 +819,14 @@
     private final LteConnectedState mLteConnectedState = new LteConnectedState();
 
     /**
-     * Device is connected to 5G NR as the primary or secondary cell.
+     * Device is connected to 5G NR as the secondary cell.
      */
     private final class NrConnectedState extends State {
-        private boolean mIsNrAdvanced = false;
+        private Boolean mIsNrAdvanced = false;
 
         @Override
         public void enter() {
-            if (DBG) log("Entering NrConnectedState(" + getName() + ")");
+            if (DBG) log("Entering NrConnectedState");
             updateTimers();
             updateOverrideNetworkType();
             if (!mIsPrimaryTimerActive && !mIsSecondaryTimerActive) {
@@ -919,7 +837,7 @@
 
         @Override
         public boolean processMessage(Message msg) {
-            if (DBG) log("NrConnectedState(" + getName() + "): process " + getEventName(msg.what));
+            if (DBG) log("NrConnectedState: process " + getEventName(msg.what));
             updateTimers();
             int rat = getDataNetworkType();
             switch (msg.what) {
@@ -944,27 +862,21 @@
                 case EVENT_PCO_DATA_CHANGED:
                     handlePcoData((AsyncResult) msg.obj);
                     break;
-                case EVENT_UPDATE_NR_ADVANCED_STATE:
-                    updateNrAdvancedState();
-                    break;
                 case EVENT_NR_FREQUENCY_CHANGED:
                 case EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED:
                     if (isUsingPhysicalChannelConfigForRrcDetection()) {
-                        mPhysicalLinkStatus = getPhysicalLinkStatusFromPhysicalChannelConfig();
+                        mPhysicalLinkState = getPhysicalLinkStateFromPhysicalChannelConfig();
                     }
                     updateNrAdvancedState();
                     break;
-                case EVENT_PHYSICAL_LINK_STATUS_CHANGED:
+                case EVENT_PHYSICAL_LINK_STATE_CHANGED:
                     AsyncResult ar = (AsyncResult) msg.obj;
-                    mPhysicalLinkStatus = (int) ar.result;
+                    mPhysicalLinkState = (int) ar.result;
                     if (!isNrConnected()) {
                         log("NR state changed. Sending EVENT_NR_STATE_CHANGED");
                         sendMessage(EVENT_NR_STATE_CHANGED);
                     }
                     break;
-                case EVENT_BANDWIDTH_CHANGED:
-                    updateNrAdvancedState();
-                    break;
                 default:
                     return NOT_HANDLED;
             }
@@ -986,10 +898,10 @@
                 return;
             }
             if (!isNrAdvanced()) {
-                if (DBG) log("updateNrAdvancedState: CONNECTED_NR_ADVANCED -> CONNECTED");
+                // STATE_CONNECTED_NR_ADVANCED -> STATE_CONNECTED
                 transitionWithTimerTo(mNrConnectedState);
             } else {
-                if (DBG) log("updateNrAdvancedState: CONNECTED -> CONNECTED_NR_ADVANCED");
+                // STATE_CONNECTED -> STATE_CONNECTED_NR_ADVANCED
                 transitionTo(mNrConnectedState);
             }
             mIsNrAdvanced = isNrAdvanced();
@@ -1014,10 +926,8 @@
                     && mNrAdvancedCapablePcoId > 0
                     && pcodata.pcoId == mNrAdvancedCapablePcoId
             ) {
-                log("EVENT_PCO_DATA_CHANGED: NR_ADVANCED is allowed by PCO. length:"
-                        + pcodata.contents.length + ",value: " + Arrays.toString(pcodata.contents));
-                mIsNrAdvancedAllowedByPco = pcodata.contents.length > 0
-                        && pcodata.contents[pcodata.contents.length - 1] == 1;
+                log("EVENT_PCO_DATA_CHANGED: Nr Advanced is allowed by PCO.");
+                mIsNrAdvancedAllowedByPco = pcodata.contents[0] == 1;
                 updateNrAdvancedState();
             }
         }
@@ -1027,15 +937,14 @@
 
     private void transitionWithTimerTo(IState destState) {
         String destName = destState.getName();
-        if (DBG) log("Transition with primary timer from " + mPreviousState + " to " + destName);
         OverrideTimerRule rule = mOverrideTimerRules.get(mPreviousState);
-        if (!mIsDeviceIdleMode && rule != null && rule.getTimer(destName) > 0) {
-            int duration = rule.getTimer(destName);
-            if (DBG) log(duration + "s primary timer started for state: " + mPreviousState);
+        if (rule != null && rule.getTimer(destName) > 0) {
+            if (DBG) log("Primary timer started for state: " + mPreviousState);
             mPrimaryTimerState = mPreviousState;
             mPreviousState = getCurrentState().getName();
             mIsPrimaryTimerActive = true;
-            sendMessageDelayed(EVENT_PRIMARY_TIMER_EXPIRED, destState, duration * 1000L);
+            sendMessageDelayed(EVENT_PRIMARY_TIMER_EXPIRED, destState,
+                    rule.getTimer(destName) * 1000);
         }
         transitionTo(destState);
     }
@@ -1043,17 +952,13 @@
     private void transitionWithSecondaryTimerTo(IState destState) {
         String currentName = getCurrentState().getName();
         OverrideTimerRule rule = mOverrideTimerRules.get(mPrimaryTimerState);
-        if (DBG) {
-            log("Transition with secondary timer from " + currentName + " to "
-                    + destState.getName());
-        }
-        if (!mIsDeviceIdleMode && rule != null && rule.getSecondaryTimer(currentName) > 0) {
-            int duration = rule.getSecondaryTimer(currentName);
-            if (DBG) log(duration + "s secondary timer started for state: " + currentName);
+        if (rule != null && rule.getSecondaryTimer(currentName) > 0) {
+            if (DBG) log("Secondary timer started for state: " + currentName);
             mSecondaryTimerState = currentName;
             mPreviousState = currentName;
             mIsSecondaryTimerActive = true;
-            sendMessageDelayed(EVENT_SECONDARY_TIMER_EXPIRED, destState, duration * 1000L);
+            sendMessageDelayed(EVENT_SECONDARY_TIMER_EXPIRED, destState,
+                    rule.getSecondaryTimer(currentName) * 1000);
         }
         mIsPrimaryTimerActive = false;
         transitionTo(getCurrentState());
@@ -1085,13 +990,6 @@
     }
 
     private void updateTimers() {
-        if ((mPhone.getCachedAllowedNetworkTypesBitmask()
-                & TelephonyManager.NETWORK_TYPE_BITMASK_NR) == 0) {
-            if (DBG) log("Reset timers since NR is not allowed.");
-            resetAllTimers();
-            return;
-        }
-
         String currentState = getCurrentState().getName();
 
         if (mIsPrimaryTimerActive && getOverrideNetworkType() == getCurrentOverrideNetworkType()) {
@@ -1116,21 +1014,21 @@
             mSecondaryTimerState = "";
         }
 
-        if (mIsPrimaryTimerActive || mIsSecondaryTimerActive) {
-            if (currentState.equals(STATE_CONNECTED_NR_ADVANCED)) {
-                if (DBG) log("Reset timers since state is NR_ADVANCED.");
-                resetAllTimers();
-            }
+        if (currentState.equals(STATE_CONNECTED_NR_ADVANCED)) {
+            resetAllTimers();
+        }
 
-            int rat = getDataNetworkType();
-            if (!isLte(rat) && rat != TelephonyManager.NETWORK_TYPE_NR) {
-                if (DBG) log("Reset timers since 2G and 3G don't need NR timers.");
-                resetAllTimers();
-            }
+        int rat = getDataNetworkType();
+        if (!isLte(rat) && rat != TelephonyManager.NETWORK_TYPE_NR) {
+            // Rat is 3G or 2G, and it doesn't need NR timer.
+            resetAllTimers();
         }
     }
 
     private void resetAllTimers() {
+        if (DBG) {
+            log("Remove all timers");
+        }
         removeMessages(EVENT_PRIMARY_TIMER_EXPIRED);
         removeMessages(EVENT_SECONDARY_TIMER_EXPIRED);
         mIsPrimaryTimerActive = false;
@@ -1143,7 +1041,7 @@
      * Private class defining timer rules between states to prevent flickering. These rules are
      * created in {@link #parseCarrierConfigs()} based on various carrier configs.
      */
-    private static class OverrideTimerRule {
+    private class OverrideTimerRule {
         /** The 5G state this timer rule applies for. See {@link #ALL_STATES}. */
         final String mState;
 
@@ -1235,33 +1133,8 @@
                 == NetworkRegistrationInfo.NR_STATE_RESTRICTED;
     }
 
-    /**
-     * @return {@code true} if the device is in NR advanced mode (i.e. 5G+).
-     */
     private boolean isNrAdvanced() {
-        // Check PCO requirement. For carriers using PCO to indicate whether the data connection is
-        // NR advanced capable, mNrAdvancedCapablePcoId should be configured to non-zero.
-        if (mNrAdvancedCapablePcoId > 0 && !mIsNrAdvancedAllowedByPco) {
-            return false;
-        }
-
-        // Check if NR advanced is enabled when the device is roaming. Some carriers disable it
-        // while the device is roaming.
-        if (mPhone.getServiceState().getDataRoaming() && !mEnableNrAdvancedWhileRoaming) {
-            return false;
-        }
-
-        // Check if meeting minimum bandwidth requirement. For most carriers, there is no minimum
-        // bandwidth requirement and mNrAdvancedThresholdBandwidth is 0.
-        if (mNrAdvancedThresholdBandwidth > 0
-                && IntStream.of(mPhone.getServiceState().getCellBandwidths()).sum()
-                < mNrAdvancedThresholdBandwidth) {
-            return false;
-        }
-
-        // If all above tests passed, then check if the device is using millimeter wave bands or
-        // carrier designated bands.
-        return isNrMmwave() || isAdditionalNrAdvancedBand();
+        return isNrAdvancedCapable() && (isNrMmwave() || isAdditionalNrAdvancedBand());
     }
 
     private boolean isNrMmwave() {
@@ -1285,20 +1158,27 @@
         return false;
     }
 
+    private boolean isNrAdvancedCapable() {
+        if (mNrAdvancedCapablePcoId > 0) {
+            return mIsNrAdvancedAllowedByPco;
+        }
+        return true;
+    }
+
     private boolean isLte(int rat) {
         return rat == TelephonyManager.NETWORK_TYPE_LTE
                 || rat == TelephonyManager.NETWORK_TYPE_LTE_CA;
     }
 
     private boolean isPhysicalLinkActive() {
-        return mPhysicalLinkStatus == DataCallResponse.LINK_STATUS_ACTIVE;
+        return mPhysicalLinkState == DcController.PHYSICAL_LINK_ACTIVE;
     }
 
-    private int getPhysicalLinkStatusFromPhysicalChannelConfig() {
+    private int getPhysicalLinkStateFromPhysicalChannelConfig() {
         List<PhysicalChannelConfig> physicalChannelConfigList =
                 mPhone.getServiceStateTracker().getPhysicalChannelConfigList();
         return (physicalChannelConfigList == null || physicalChannelConfigList.isEmpty())
-                ? DataCallResponse.LINK_STATUS_DORMANT : DataCallResponse.LINK_STATUS_ACTIVE;
+                ? DcController.PHYSICAL_LINK_NOT_ACTIVE : DcController.PHYSICAL_LINK_ACTIVE;
     }
 
     private int getDataNetworkType() {
@@ -1338,7 +1218,7 @@
                 + ", mPrimaryTimerState=" + mPrimaryTimerState
                 + ", mSecondaryTimerState=" + mSecondaryTimerState
                 + ", mPreviousState=" + mPreviousState
-                + ", mIsNrAdvanced=" + isNrAdvanced();
+                + ", misNrAdvanced=" + isNrAdvanced();
     }
 
     @Override
@@ -1357,19 +1237,13 @@
         pw.println("mIsTimerRestEnabledForLegacyStateRRCIdle="
                 + mIsTimerResetEnabledForLegacyStateRRCIdle);
         pw.println("mLtePlusThresholdBandwidth=" + mLtePlusThresholdBandwidth);
-        pw.println("mNrAdvancedThresholdBandwidth=" + mNrAdvancedThresholdBandwidth);
         pw.println("mPrimaryTimerState=" + mPrimaryTimerState);
         pw.println("mSecondaryTimerState=" + mSecondaryTimerState);
         pw.println("mPreviousState=" + mPreviousState);
-        pw.println("mPhysicalLinkStatus=" + mPhysicalLinkStatus);
+        pw.println("mPhysicalLinkState=" + mPhysicalLinkState);
         pw.println("mAdditionalNrAdvancedBandsList="
                 + Arrays.toString(mAdditionalNrAdvancedBandsList));
-        pw.println("mIsPhysicalChannelConfig16Supported=" + mIsPhysicalChannelConfig16Supported);
-        pw.println("mIsNrAdvancedAllowedByPco=" + mIsNrAdvancedAllowedByPco);
         pw.println("mNrAdvancedCapablePcoId=" + mNrAdvancedCapablePcoId);
-        pw.println("mIsUsingUserDataForRrcDetection=" + mIsUsingUserDataForRrcDetection);
-        pw.println("mEnableNrAdvancedWhileRoaming=" + mEnableNrAdvancedWhileRoaming);
-        pw.println("mIsDeviceIdleMode=" + mIsDeviceIdleMode);
         pw.decreaseIndent();
         pw.flush();
     }
diff --git a/src/java/com/android/internal/telephony/NitzData.java b/src/java/com/android/internal/telephony/NitzData.java
index 6b19e08..20f9e6a 100644
--- a/src/java/com/android/internal/telephony/NitzData.java
+++ b/src/java/com/android/internal/telephony/NitzData.java
@@ -56,14 +56,14 @@
     private final TimeZone mEmulatorHostTimeZone;
 
     private NitzData(String originalString, int zoneOffsetMillis, Integer dstOffsetMillis,
-            long unixEpochTimeMillis, TimeZone emulatorHostTimeZone) {
+            long utcTimeMillis, TimeZone emulatorHostTimeZone) {
         if (originalString == null) {
             throw new NullPointerException("originalString==null");
         }
         this.mOriginalString = originalString;
         this.mZoneOffset = zoneOffsetMillis;
         this.mDstOffset = dstOffsetMillis;
-        this.mCurrentTimeMillis = unixEpochTimeMillis;
+        this.mCurrentTimeMillis = utcTimeMillis;
         this.mEmulatorHostTimeZone = emulatorHostTimeZone;
     }
 
@@ -130,8 +130,8 @@
 
     /** A method for use in tests to create NitzData instances. */
     public static NitzData createForTests(int zoneOffsetMillis, Integer dstOffsetMillis,
-            long unixEpochTimeMillis, TimeZone emulatorHostTimeZone) {
-        return new NitzData("Test data", zoneOffsetMillis, dstOffsetMillis, unixEpochTimeMillis,
+            long utcTimeMillis, TimeZone emulatorHostTimeZone) {
+        return new NitzData("Test data", zoneOffsetMillis, dstOffsetMillis, utcTimeMillis,
                 emulatorHostTimeZone);
     }
 
diff --git a/src/java/com/android/internal/telephony/NitzSignal.java b/src/java/com/android/internal/telephony/NitzSignal.java
deleted file mode 100644
index 889fe95..0000000
--- a/src/java/com/android/internal/telephony/NitzSignal.java
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.annotation.DurationMillisLong;
-import android.annotation.ElapsedRealtimeLong;
-import android.annotation.NonNull;
-import android.os.TimestampedValue;
-
-import java.time.Duration;
-import java.util.Objects;
-
-/** NITZ information and associated metadata. */
-public final class NitzSignal {
-
-    @ElapsedRealtimeLong private final long mReceiptElapsedMillis;
-    @NonNull private final NitzData mNitzData;
-    @DurationMillisLong private final long mAgeMillis;
-
-    /**
-     * @param receiptElapsedMillis the time according to {@link
-     *     android.os.SystemClock#elapsedRealtime()} when the NITZ signal was first received by
-     *     the platform code
-     * @param nitzData the NITZ data
-     * @param ageMillis the age of the NITZ when it was passed to the platform, e.g. if it was
-     *     cached by the modem for a period of time. Must not be negative.
-     */
-    public NitzSignal(
-            @ElapsedRealtimeLong long receiptElapsedMillis,
-            @NonNull NitzData nitzData,
-            long ageMillis) {
-        mReceiptElapsedMillis = receiptElapsedMillis;
-        mNitzData = Objects.requireNonNull(nitzData);
-        if (ageMillis < 0) {
-            throw new IllegalArgumentException("ageMillis < 0");
-        }
-        mAgeMillis = ageMillis;
-    }
-
-    /**
-     * Returns the time according to {@link android.os.SystemClock#elapsedRealtime()} when the NITZ
-     * signal was first received by the platform code.
-     */
-    @ElapsedRealtimeLong
-    public long getReceiptElapsedRealtimeMillis() {
-        return mReceiptElapsedMillis;
-    }
-
-    /**
-     * Returns the NITZ data.
-     */
-    @NonNull
-    public NitzData getNitzData() {
-        return mNitzData;
-    }
-
-    /**
-     * Returns the age of the NITZ when it was passed to the platform, e.g. if it was cached by the
-     * modem for a period of time. Must not be negative.
-     */
-    @DurationMillisLong
-    public long getAgeMillis() {
-        return mAgeMillis;
-    }
-
-    /**
-     * Returns a derived property of {@code receiptElapsedMillis - ageMillis}, i.e. the time
-     * according to the elapsed realtime clock when the NITZ signal was actually received by this
-     * device taking into time it was cached by layers before the RIL.
-     */
-    @ElapsedRealtimeLong
-    public long getAgeAdjustedElapsedRealtimeMillis() {
-        return mReceiptElapsedMillis - mAgeMillis;
-    }
-
-    /**
-     * Creates a {@link android.os.TimestampedValue} containing the UTC time as the number of
-     * milliseconds since the start of the Unix epoch. The reference time is the time according to
-     * the elapsed realtime clock when that would have been the time, accounting for receipt time
-     * and age.
-     */
-    public TimestampedValue<Long> createTimeSignal() {
-        return new TimestampedValue<>(
-                getAgeAdjustedElapsedRealtimeMillis(),
-                getNitzData().getCurrentTimeInMillis());
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-        NitzSignal that = (NitzSignal) o;
-        return mReceiptElapsedMillis == that.mReceiptElapsedMillis
-                && mAgeMillis == that.mAgeMillis
-                && mNitzData.equals(that.mNitzData);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mReceiptElapsedMillis, mNitzData, mAgeMillis);
-    }
-
-    @Override
-    public String toString() {
-        return "NitzSignal{"
-                + "mReceiptElapsedMillis=" + Duration.ofMillis(mReceiptElapsedMillis)
-                + ", mNitzData=" + mNitzData
-                + ", mAgeMillis=" + mAgeMillis
-                + '}';
-    }
-}
diff --git a/src/java/com/android/internal/telephony/NitzStateMachine.java b/src/java/com/android/internal/telephony/NitzStateMachine.java
index 291cd40..e1f854c 100644
--- a/src/java/com/android/internal/telephony/NitzStateMachine.java
+++ b/src/java/com/android/internal/telephony/NitzStateMachine.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.TimestampedValue;
 import android.provider.Settings;
 
 import com.android.internal.util.IndentingPrintWriter;
@@ -64,7 +65,7 @@
     /**
      * Handle a new NITZ signal being received.
      */
-    void handleNitzReceived(@NonNull NitzSignal nitzSignal);
+    void handleNitzReceived(@NonNull TimestampedValue<NitzData> nitzSignal);
 
     /**
      * Handle the user putting the device into or out of airplane mode
@@ -89,29 +90,18 @@
     interface DeviceState {
 
         /**
-         * If the elapsed realtime between two NITZ signals is greater than this value then the
-         * second signal cannot be ignored.
+         * If time between NITZ updates is less than {@link #getNitzUpdateSpacingMillis()} the
+         * update may be ignored.
          */
         int getNitzUpdateSpacingMillis();
 
         /**
-         * If Unix epoch time between two NITZ signals is greater than this value then the second
-         * signal cannot be ignored.
+         * If {@link #getNitzUpdateSpacingMillis()} hasn't been exceeded but update is >
+         * {@link #getNitzUpdateDiffMillis()} do the update
          */
         int getNitzUpdateDiffMillis();
 
         /**
-         * If the device connects to a telephony network and was disconnected from a telephony
-         * network for less than this time, a previously received NITZ signal can be restored.
-         *
-         * <p>The restored NITZ may not be from the same network as the current network. It is
-         * intended to be a relatively small value to allow for brief disconnections. Larger values
-         * increase the likelihood that the device has moved to a different network and/or time
-         * zone.
-         */
-        int getNitzNetworkDisconnectRetentionMillis();
-
-        /**
          * Returns true if the {@code gsm.ignore-nitz} system property is set to "yes".
          */
         boolean getIgnoreNitz();
@@ -119,7 +109,7 @@
         /**
          * Returns the same value as {@link SystemClock#elapsedRealtime()}.
          */
-        long elapsedRealtimeMillis();
+        long elapsedRealtime();
 
         /**
          * Returns the same value as {@link System#currentTimeMillis()}.
@@ -133,53 +123,32 @@
      * {@hide}
      */
     class DeviceStateImpl implements DeviceState {
+        private static final int NITZ_UPDATE_SPACING_DEFAULT = 1000 * 60 * 10;
+        private final int mNitzUpdateSpacing;
 
-        /** The default value to use for {@link #getNitzUpdateSpacingMillis()}. 10 minutes. */
-        private static final int NITZ_UPDATE_SPACING_MILLIS_DEFAULT = 1000 * 60 * 10;
-        private final int mNitzUpdateSpacingMillis;
-
-        /** The default value to use for {@link #getNitzUpdateDiffMillis()}. 2 seconds. */
-        private static final int NITZ_UPDATE_DIFF_MILLIS_DEFAULT = 2000;
-        private final int mNitzUpdateDiffMillis;
-
-        /**
-         * The default value to use for {@link #getNitzNetworkDisconnectRetentionMillis()}.
-         * 5 minutes.
-         */
-        private static final int NITZ_NETWORK_DISCONNECT_RETENTION_MILLIS_DEFAULT = 1000 * 60 * 5;
-        private final int mNitzNetworkDisconnectRetentionMillis;
+        private static final int NITZ_UPDATE_DIFF_DEFAULT = 2000;
+        private final int mNitzUpdateDiff;
 
         private final ContentResolver mCr;
 
         public DeviceStateImpl(Phone phone) {
             Context context = phone.getContext();
             mCr = context.getContentResolver();
-            mNitzUpdateSpacingMillis =
-                    SystemProperties.getInt("ro.nitz_update_spacing",
-                            NITZ_UPDATE_SPACING_MILLIS_DEFAULT);
-            mNitzUpdateDiffMillis =
-                    SystemProperties.getInt("ro.nitz_update_diff", NITZ_UPDATE_DIFF_MILLIS_DEFAULT);
-            mNitzNetworkDisconnectRetentionMillis =
-                    SystemProperties.getInt("ro.nitz_network_disconnect_retention",
-                            NITZ_NETWORK_DISCONNECT_RETENTION_MILLIS_DEFAULT);
+            mNitzUpdateSpacing =
+                    SystemProperties.getInt("ro.nitz_update_spacing", NITZ_UPDATE_SPACING_DEFAULT);
+            mNitzUpdateDiff =
+                    SystemProperties.getInt("ro.nitz_update_diff", NITZ_UPDATE_DIFF_DEFAULT);
         }
 
         @Override
         public int getNitzUpdateSpacingMillis() {
             return Settings.Global.getInt(mCr, Settings.Global.NITZ_UPDATE_SPACING,
-                    mNitzUpdateSpacingMillis);
+                    mNitzUpdateSpacing);
         }
 
         @Override
         public int getNitzUpdateDiffMillis() {
-            return Settings.Global.getInt(mCr, Settings.Global.NITZ_UPDATE_DIFF,
-                    mNitzUpdateDiffMillis);
-        }
-
-        @Override
-        public int getNitzNetworkDisconnectRetentionMillis() {
-            return Settings.Global.getInt(mCr, Settings.Global.NITZ_NETWORK_DISCONNECT_RETENTION,
-                    mNitzNetworkDisconnectRetentionMillis);
+            return Settings.Global.getInt(mCr, Settings.Global.NITZ_UPDATE_DIFF, mNitzUpdateDiff);
         }
 
         @Override
@@ -189,7 +158,7 @@
         }
 
         @Override
-        public long elapsedRealtimeMillis() {
+        public long elapsedRealtime() {
             return SystemClock.elapsedRealtime();
         }
 
diff --git a/src/java/com/android/internal/telephony/Phone.java b/src/java/com/android/internal/telephony/Phone.java
index 4afccd1..93a2e8e 100644
--- a/src/java/com/android/internal/telephony/Phone.java
+++ b/src/java/com/android/internal/telephony/Phone.java
@@ -24,6 +24,8 @@
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.res.Configuration;
+import android.net.LinkProperties;
+import android.net.NetworkCapabilities;
 import android.net.Uri;
 import android.os.AsyncResult;
 import android.os.Build;
@@ -48,7 +50,6 @@
 import android.telephony.ClientRequestStats;
 import android.telephony.ImsiEncryptionInfo;
 import android.telephony.LinkCapacityEstimate;
-import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneStateListener;
 import android.telephony.PhysicalChannelConfig;
 import android.telephony.PreciseDataConnectionState;
@@ -56,7 +57,6 @@
 import android.telephony.RadioAccessSpecifier;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
-import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
@@ -66,7 +66,6 @@
 import android.telephony.ims.stub.ImsRegistrationImplBase;
 import android.text.TextUtils;
 import android.util.LocalLog;
-import android.util.Log;
 import android.util.SparseArray;
 import android.util.Xml;
 
@@ -76,16 +75,12 @@
 import com.android.ims.ImsManager;
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.data.AccessNetworksManager;
-import com.android.internal.telephony.data.DataNetworkController;
-import com.android.internal.telephony.data.DataSettingsManager;
-import com.android.internal.telephony.data.LinkBandwidthEstimator;
 import com.android.internal.telephony.dataconnection.DataConnectionReasons;
 import com.android.internal.telephony.dataconnection.DataEnabledSettings;
 import com.android.internal.telephony.dataconnection.DcTracker;
+import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator;
 import com.android.internal.telephony.dataconnection.TransportManager;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
-import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneCall;
 import com.android.internal.telephony.metrics.SmsStats;
 import com.android.internal.telephony.metrics.VoiceCallSessionStats;
@@ -97,7 +92,6 @@
 import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccCardApplication;
 import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UsimServiceTable;
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.internal.util.XmlUtils;
@@ -113,6 +107,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -173,6 +168,8 @@
     protected static final int EVENT_GET_BASEBAND_VERSION_DONE   = 6;
     protected static final int EVENT_USSD                        = 7;
     protected static final int EVENT_RADIO_OFF_OR_NOT_AVAILABLE  = 8;
+    protected static final int EVENT_GET_IMEI_DONE               = 9;
+    protected static final int EVENT_GET_IMEISV_DONE             = 10;
     private static final int EVENT_GET_SIM_STATUS_DONE           = 11;
     protected static final int EVENT_SET_CALL_FORWARD_DONE       = 12;
     protected static final int EVENT_GET_CALL_FORWARD_DONE       = 13;
@@ -235,12 +232,8 @@
     protected static final int EVENT_BARRING_INFO_CHANGED = 58;
     protected static final int EVENT_LINK_CAPACITY_CHANGED = 59;
     protected static final int EVENT_RESET_CARRIER_KEY_IMSI_ENCRYPTION = 60;
-    protected static final int EVENT_SET_VONR_ENABLED_DONE = 61;
-    protected static final int EVENT_SUBSCRIPTIONS_CHANGED = 62;
-    protected static final int EVENT_GET_USAGE_SETTING_DONE = 63;
-    protected static final int EVENT_SET_USAGE_SETTING_DONE = 64;
 
-    protected static final int EVENT_LAST = EVENT_SET_USAGE_SETTING_DONE;
+    protected static final int EVENT_LAST = EVENT_RESET_CARRIER_KEY_IMSI_ENCRYPTION;
 
     // For shared prefs.
     private static final String GSM_ROAMING_LIST_OVERRIDE_PREFIX = "gsm_roaming_list_";
@@ -308,7 +301,6 @@
     // WLAN DcTracker is for IWLAN data connection. For IWLAN legacy mode, only one (WWAN) DcTracker
     // will be created.
     protected final SparseArray<DcTracker> mDcTrackers = new SparseArray<>();
-    protected DataNetworkController mDataNetworkController;
     /* Used for dispatching signals to configured carrier apps */
     protected CarrierSignalAgent mCarrierSignalAgent;
     /* Used for dispatching carrier action from carrier apps */
@@ -347,11 +339,9 @@
     protected DeviceStateMonitor mDeviceStateMonitor;
     protected DisplayInfoController mDisplayInfoController;
     protected TransportManager mTransportManager;
-    protected AccessNetworksManager mAccessNetworksManager;
     protected DataEnabledSettings mDataEnabledSettings;
     // Used for identify the carrier of current subscription
     protected CarrierResolver mCarrierResolver;
-    protected SignalStrengthController mSignalStrengthController;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     protected int mPhoneId;
@@ -367,10 +357,6 @@
     private int mLceStatus = RILConstants.LCE_NOT_AVAILABLE;
     protected TelephonyComponentFactory mTelephonyComponentFactory;
 
-    private int mPreferredUsageSetting = SubscriptionManager.USAGE_SETTING_UNKNOWN;
-    private int mUsageSettingFromModem = SubscriptionManager.USAGE_SETTING_UNKNOWN;
-    private boolean mIsUsageSettingSupported = true;
-
     //IMS
     /**
      * {@link CallStateException} message text used to indicate that an IMS call has failed because
@@ -468,16 +454,13 @@
     protected boolean mIsCarrierNrSupported = false;
     protected boolean mIsAllowedNetworkTypesLoadedFromDb = false;
     private boolean mUnitTestMode;
+    private CarrierPrivilegesTracker mCarrierPrivilegesTracker = null;
 
     protected VoiceCallSessionStats mVoiceCallSessionStats;
     protected SmsStats mSmsStats;
 
     protected LinkBandwidthEstimator mLinkBandwidthEstimator;
 
-    /** The flag indicating using the new data stack or not. */
-    // This flag and the old data stack code will be deleted in Android 14.
-    private final boolean mNewDataStackEnabled;
-
     public IccRecords getIccRecords() {
         return mIccRecords.get();
     }
@@ -619,9 +602,6 @@
         // Initialize SMS stats
         mSmsStats = new SmsStats(this);
 
-        mNewDataStackEnabled = !mContext.getResources().getBoolean(
-                com.android.internal.R.bool.config_force_disable_telephony_new_data_stack);
-
         if (getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
             return;
         }
@@ -637,6 +617,7 @@
         mSimActivationTracker = mTelephonyComponentFactory
                 .inject(SimActivationTracker.class.getName())
                 .makeSimActivationTracker(this);
+        mCarrierPrivilegesTracker = new CarrierPrivilegesTracker(mLooper, this, mContext);
         if (getPhoneType() != PhoneConstants.PHONE_TYPE_SIP) {
             mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null);
         }
@@ -819,49 +800,6 @@
                     mAllDataDisconnectedRegistrants.notifyRegistrants();
                 }
                 break;
-            case EVENT_GET_USAGE_SETTING_DONE:
-                ar = (AsyncResult) msg.obj;
-                if (ar.exception == null) {
-                    try {
-                        mUsageSettingFromModem = ((int[]) ar.result)[0];
-                    } catch (NullPointerException | ClassCastException e) {
-                        Rlog.e(LOG_TAG, "Invalid response for usage setting " + ar.result);
-                        break;
-                    }
-
-                    logd("Received mUsageSettingFromModem=" + mUsageSettingFromModem);
-                    if (mUsageSettingFromModem != mPreferredUsageSetting) {
-                        mCi.setUsageSetting(obtainMessage(EVENT_SET_USAGE_SETTING_DONE),
-                                mPreferredUsageSetting);
-                    }
-                } else {
-                    try {
-                        CommandException ce = (CommandException) ar.exception;
-                        if (ce.getCommandError() == CommandException.Error.REQUEST_NOT_SUPPORTED) {
-                            mIsUsageSettingSupported = false;
-                        }
-                        Rlog.w(LOG_TAG, "Unexpected failure to retrieve usage setting " + ce);
-                    } catch (ClassCastException unused) {
-                        Rlog.e(LOG_TAG, "Invalid Exception for usage setting " + ar.exception);
-                        break; // technically extraneous, but good hygiene
-                    }
-                }
-                break;
-            case EVENT_SET_USAGE_SETTING_DONE:
-                ar = (AsyncResult) msg.obj;
-                if (ar.exception != null) {
-                    try {
-                        CommandException ce = (CommandException) ar.exception;
-                        if (ce.getCommandError() == CommandException.Error.REQUEST_NOT_SUPPORTED) {
-                            mIsUsageSettingSupported = false;
-                        }
-                        Rlog.w(LOG_TAG, "Unexpected failure to set usage setting " + ce);
-                    } catch (ClassCastException unused) {
-                        Rlog.e(LOG_TAG, "Invalid Exception for usage setting " + ar.exception);
-                        break; // technically extraneous, but good hygiene
-                    }
-                }
-                break;
             default:
                 throw new RuntimeException("unexpected event not handled");
         }
@@ -1795,7 +1733,7 @@
      * version scoped to their packages
      */
     protected void notifyServiceStateChangedP(ServiceState ss) {
-        AsyncResult ar = new AsyncResult(null, new ServiceState(ss), null);
+        AsyncResult ar = new AsyncResult(null, ss, null);
         mServiceStateRegistrants.notifyRegistrants(ar);
 
         mNotifier.notifyServiceState(this);
@@ -1916,15 +1854,6 @@
     }
 
     /**
-     * Override to merge into {@link #getServiceState} when telecom has registered a SIM call
-     * manager that supports over-the-top SIM-based calling (e.g. carrier-provided wi-fi calling
-     * implementation).
-     *
-     * @param hasService Whether or not the SIM call manager currently provides over-the-top voice
-     */
-    public void setVoiceServiceStateOverride(boolean hasService) {}
-
-    /**
      * Check whether the radio is off for thermal reason.
      *
      * @return {@code true} only if thermal mitigation is one of the reason for which radio is off.
@@ -1951,20 +1880,13 @@
     }
 
     /**
-     * @return The instance of transport manager.
+     * @return The instance of transport manager
      */
     public TransportManager getTransportManager() {
         return null;
     }
 
     /**
-     * @return The instance of access networks manager.
-     */
-    public AccessNetworksManager getAccessNetworksManager() {
-        return null;
-    }
-
-    /**
      * Retrieves the DeviceStateMonitor of the phone instance.
      */
     public DeviceStateMonitor getDeviceStateMonitor() {
@@ -1979,14 +1901,6 @@
     }
 
     /**
-     * Retrieves the SignalStrengthController of the phone instance.
-     */
-    public SignalStrengthController getSignalStrengthController() {
-        Log.wtf(LOG_TAG, "getSignalStrengthController return null.");
-        return null;
-    }
-
-    /**
      * Update voice activation state
      */
     public void setVoiceActivationState(int state) {
@@ -2276,11 +2190,11 @@
      * @return Current signal strength as SignalStrength
      */
     public SignalStrength getSignalStrength() {
-        SignalStrengthController ssc = getSignalStrengthController();
-        if (ssc == null) {
+        ServiceStateTracker sst = getServiceStateTracker();
+        if (sst == null) {
             return new SignalStrength();
         } else {
-            return ssc.getSignalStrength();
+            return sst.getSignalStrength();
         }
     }
 
@@ -2506,29 +2420,24 @@
      *
      * @param reason reason to configure allowed network type
      * @param networkTypes one of the network types
-     * @param response callback Message
      */
     public void setAllowedNetworkTypes(@TelephonyManager.AllowedNetworkTypesReason int reason,
-            @TelephonyManager.NetworkTypeBitMask long networkTypes, @Nullable Message response) {
+            @TelephonyManager.NetworkTypeBitMask long networkTypes, Message response) {
         int subId = getSubId();
         if (!TelephonyManager.isValidAllowedNetworkTypesReason(reason)) {
             loge("setAllowedNetworkTypes: Invalid allowed network type reason: " + reason);
-            if (response != null) {
-                AsyncResult.forMessage(response, null,
-                        new CommandException(CommandException.Error.INVALID_ARGUMENTS));
-                response.sendToTarget();
-            }
+            AsyncResult.forMessage(response, null,
+                    new CommandException(CommandException.Error.INVALID_ARGUMENTS));
+            response.sendToTarget();
             return;
         }
         if (!SubscriptionManager.isUsableSubscriptionId(subId)
                 || !mIsAllowedNetworkTypesLoadedFromDb) {
             loge("setAllowedNetworkTypes: no sim or network type is not loaded. SubscriptionId: "
                     + subId + ", isNetworkTypeLoaded" + mIsAllowedNetworkTypesLoadedFromDb);
-            if (response != null) {
-                AsyncResult.forMessage(response, null,
-                        new CommandException(CommandException.Error.MISSING_RESOURCE));
-                response.sendToTarget();
-            }
+            AsyncResult.forMessage(response, null,
+                    new CommandException(CommandException.Error.MISSING_RESOURCE));
+            response.sendToTarget();
             return;
         }
         String mapAsString = "";
@@ -2993,11 +2902,6 @@
         return false;
     }
 
-    public boolean isInCdmaEcm() {
-        return getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA && isInEcm()
-                && (mImsPhone == null || !mImsPhone.isInImsEcm());
-    }
-
     public void setIsInEcm(boolean isInEcm) {
         if (!getUnitTestMode()) {
             TelephonyProperties.in_ecm_mode(isInEcm);
@@ -3635,6 +3539,31 @@
     }
 
     /**
+     * Returns an array of string identifiers for the APN types serviced by the
+     * currently active subscription.
+     *
+     * @return The string array of APN types. Return null if no active APN types.
+     */
+    @UnsupportedAppUsage
+    @NonNull
+    public String[] getActiveApnTypes() {
+        if (mTransportManager == null || mDcTrackers == null)  {
+            Rlog.e(LOG_TAG, "Invalid state for Transport/DcTrackers");
+            return new String[0];
+        }
+
+        Set<String> activeApnTypes = new HashSet<String>();
+        for (int transportType : mTransportManager.getAvailableTransports()) {
+            DcTracker dct = getDcTracker(transportType);
+            if (dct == null) continue; // TODO: should this ever happen?
+            activeApnTypes.addAll(Arrays.asList(dct.getActiveApnTypes()));
+        }
+
+        return activeApnTypes.toArray(new String[activeApnTypes.size()]);
+    }
+
+
+    /**
      *  Location to an updatable file listing carrier provisioning urls.
      *  An example:
      *
@@ -3730,15 +3659,6 @@
      * @return true if there is a matching DUN APN.
      */
     public boolean hasMatchedTetherApnSetting() {
-        if (isUsingNewDataStack()) {
-            NetworkRegistrationInfo nrs = getServiceState().getNetworkRegistrationInfo(
-                    NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-            if (nrs != null) {
-                return getDataNetworkController().getDataProfileManager()
-                        .isTetheringDataProfileExisting(nrs.getAccessNetworkTechnology());
-            }
-            return false;
-        }
         if (getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) != null) {
             return getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                     .hasMatchedTetherApnSetting();
@@ -3747,15 +3667,58 @@
     }
 
     /**
-     * Report on whether data connectivity is allowed for internet.
-     *
-     * @return {@code true} if internet data is allowed to be established.
+     * Returns string for the active APN host.
+     *  @return type as a string or null if none.
      */
-    public boolean isDataAllowed() {
-        if (isUsingNewDataStack()) {
-            return getDataNetworkController().isInternetDataAllowed();
+    public String getActiveApnHost(String apnType) {
+        if (mTransportManager != null) {
+            int transportType = mTransportManager.getCurrentTransport(
+                    ApnSetting.getApnTypesBitmaskFromString(apnType));
+            if (getDcTracker(transportType) != null) {
+                return getDcTracker(transportType).getActiveApnString(apnType);
+            }
         }
-        return isDataAllowed(ApnSetting.TYPE_DEFAULT, null);
+
+        return null;
+    }
+
+    /**
+     * Return the LinkProperties for the named apn or null if not available
+     */
+    public LinkProperties getLinkProperties(String apnType) {
+        if (mTransportManager != null) {
+            int transport = mTransportManager.getCurrentTransport(
+                    ApnSetting.getApnTypesBitmaskFromString(apnType));
+            if (getDcTracker(transport) != null) {
+                return getDcTracker(transport).getLinkProperties(apnType);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Return the NetworkCapabilities
+     */
+    public NetworkCapabilities getNetworkCapabilities(String apnType) {
+        if (mTransportManager != null) {
+            int transportType = mTransportManager.getCurrentTransport(
+                    ApnSetting.getApnTypesBitmaskFromString(apnType));
+            if (getDcTracker(transportType) != null) {
+                return getDcTracker(transportType).getNetworkCapabilities(apnType);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Report on whether data connectivity is allowed for given APN type.
+     *
+     * @param apnType APN type
+     *
+     * @return True if data is allowed to be established.
+     */
+    public boolean isDataAllowed(@ApnType int apnType) {
+        return isDataAllowed(apnType, null);
     }
 
     /**
@@ -3766,8 +3729,8 @@
      * @return True if data is allowed to be established
      */
     public boolean isDataAllowed(@ApnType int apnType, DataConnectionReasons reasons) {
-        if (mAccessNetworksManager != null) {
-            int transport = mAccessNetworksManager.getCurrentTransport(apnType);
+        if (mTransportManager != null) {
+            int transport = mTransportManager.getCurrentTransport(apnType);
             if (getDcTracker(transport) != null) {
                 return getDcTracker(transport).isDataAllowed(reasons);
             }
@@ -3810,9 +3773,6 @@
      * version scoped to their packages
      */
     public void notifyNewRingingConnectionP(Connection cn) {
-        Rlog.i(LOG_TAG, String.format(
-                "notifyNewRingingConnection: phoneId=[%d], connection=[%s], registrants=[%s]",
-                getPhoneId(), cn, getNewRingingConnectionRegistrantsAsString()));
         if (!mIsVoiceCapable)
             return;
         AsyncResult ar = new AsyncResult(null, cn, null);
@@ -3820,19 +3780,6 @@
     }
 
     /**
-     * helper for notifyNewRingingConnectionP(Connection) to create a string for a log message.
-     *
-     * @return a list of objects in mNewRingingConnectionRegistrants as a String
-     */
-    private String getNewRingingConnectionRegistrantsAsString() {
-        List<String> registrants = new ArrayList<>();
-        for (int i = 0; i < mNewRingingConnectionRegistrants.size(); i++) {
-            registrants.add(mNewRingingConnectionRegistrants.get(i).toString());
-        }
-        return String.join(", ", registrants);
-    }
-
-    /**
      * Notify registrants of a new unknown connection.
      */
     public void notifyUnknownConnectionP(Connection cn) {
@@ -3976,11 +3923,19 @@
     }
 
     /**
-     * Gets the Uicc port corresponding to this phone.
-     * @return the UiccPort object corresponding to the phone ID.
+     * Get P-CSCF address from PCO after data connection is established or modified.
+     * @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN
      */
-    public UiccPort getUiccPort() {
-        return mUiccController.getUiccPort(mPhoneId);
+    public String[] getPcscfAddress(String apnType) {
+        if (mTransportManager != null) {
+            int transportType = mTransportManager.getCurrentTransport(
+                    ApnSetting.getApnTypesBitmaskFromString(apnType));
+            if (getDcTracker(transportType) != null) {
+                return getDcTracker(transportType).getPcscfAddress(apnType);
+            }
+        }
+
+        return null;
     }
 
     /**
@@ -3997,11 +3952,6 @@
         return mImsPhone;
     }
 
-    @VisibleForTesting
-    public void setImsPhone(ImsPhone imsPhone) {
-        mImsPhone = imsPhone;
-    }
-
     /**
      * Returns Carrier specific information that will be used to encrypt the IMSI and IMPI.
      * @param keyType whether the key is being used for WLAN or ePDG.
@@ -4028,9 +3978,8 @@
 
     /**
      * Deletes all the keys for a given Carrier from the device keystore.
-     * @param carrierId : the carrier ID which needs to be matched in the delete query
      */
-    public void deleteCarrierInfoForImsiEncryption(int carrierId) {
+    public void deleteCarrierInfoForImsiEncryption() {
         return;
     }
 
@@ -4136,6 +4085,19 @@
     }
 
     /**
+     * Return the service state of mImsPhone if it is STATE_IN_SERVICE
+     * otherwise return the current voice service state
+     */
+    public int getVoicePhoneServiceState() {
+        Phone imsPhone = mImsPhone;
+        if (imsPhone != null
+                && imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE) {
+            return ServiceState.STATE_IN_SERVICE;
+        }
+        return getServiceState().getState();
+    }
+
+    /**
      * Override the service provider name and the operator name for the current ICCID.
      */
     public boolean setOperatorBrandOverride(String brand) {
@@ -4433,74 +4395,16 @@
         if (restoreNetworkSelection) {
             restoreSavedNetworkSelection(null);
         }
-
-        updateUsageSetting();
     }
 
-    private int getResolvedUsageSetting(int subId) {
-        SubscriptionInfo subInfo = SubscriptionController.getInstance().getSubscriptionInfo(subId);
-
-        if (subInfo == null
-                || subInfo.getUsageSetting() == SubscriptionManager.USAGE_SETTING_UNKNOWN) {
-            loge("Failed to get SubscriptionInfo for subId=" + subId);
-            return SubscriptionManager.USAGE_SETTING_UNKNOWN;
-        }
-
-        if (subInfo.getUsageSetting() != SubscriptionManager.USAGE_SETTING_DEFAULT) {
-            return subInfo.getUsageSetting();
-        }
-
-        if (subInfo.isOpportunistic()) {
-            return SubscriptionManager.USAGE_SETTING_DATA_CENTRIC;
-        } else {
-            return mContext.getResources().getInteger(
-                    com.android.internal.R.integer.config_default_cellular_usage_setting);
+    protected void setPreferredNetworkTypeIfSimLoaded() {
+        int subId = getSubId();
+        if (SubscriptionManager.isValidSubscriptionId(subId)) {
+            updateAllowedNetworkTypes(null);
         }
     }
 
     /**
-     * Attempt to update the usage setting.
-     *
-     * @return whether the usage setting will be updated (used for test)
-     */
-    public boolean updateUsageSetting() {
-        if (!mIsUsageSettingSupported) return false;
-
-        final int subId = getSubId();
-        if (!SubscriptionManager.isValidSubscriptionId(subId)) return false;
-
-        final int lastPreferredUsageSetting = mPreferredUsageSetting;
-
-        mPreferredUsageSetting = getResolvedUsageSetting(subId);
-        if (mPreferredUsageSetting == SubscriptionManager.USAGE_SETTING_UNKNOWN) {
-            loge("Usage Setting is Supported but Preferred Setting Unknown!");
-            return false;
-        }
-
-        // We might get a lot of requests to update, so definitely we don't want to hammer
-        // the modem with multiple duplicate requests for usage setting updates
-        if (mPreferredUsageSetting == lastPreferredUsageSetting) return false;
-
-        String logStr = "mPreferredUsageSetting=" + mPreferredUsageSetting
-                + ", lastPreferredUsageSetting=" + lastPreferredUsageSetting
-                + ", mUsageSettingFromModem=" + mUsageSettingFromModem;
-        logd(logStr);
-        mLocalLog.log(logStr);
-
-        // If the modem value hasn't been updated, request it.
-        if (mUsageSettingFromModem == SubscriptionManager.USAGE_SETTING_UNKNOWN) {
-            mCi.getUsageSetting(obtainMessage(EVENT_GET_USAGE_SETTING_DONE));
-            // If the modem value is already known, and the value has changed, proceed to update.
-        } else if (mPreferredUsageSetting != mUsageSettingFromModem) {
-            mCi.setUsageSetting(obtainMessage(EVENT_SET_USAGE_SETTING_DONE),
-                    mPreferredUsageSetting);
-        }
-        return true;
-    }
-
-
-
-    /**
      * Registers the handler when phone radio  capability is changed.
      *
      * @param h Handler for notification message.
@@ -4593,6 +4497,12 @@
     }
 
     /** Sets the SignalStrength reporting criteria. */
+    public void setSignalStrengthReportingCriteria(
+            int signalStrengthMeasure, int[] thresholds, int ran, boolean isEnabled) {
+        // no-op default implementation
+    }
+
+    /** Sets the SignalStrength reporting criteria. */
     public void setLinkCapacityReportingCriteria(int[] dlThresholds, int[] ulThresholds, int ran) {
         // no-op default implementation
     }
@@ -4625,8 +4535,8 @@
      * @return True if all data connections are disconnected.
      */
     public boolean areAllDataDisconnected() {
-        if (mAccessNetworksManager != null) {
-            for (int transport : mAccessNetworksManager.getAvailableTransports()) {
+        if (mTransportManager != null) {
+            for (int transport : mTransportManager.getAvailableTransports()) {
                 if (getDcTracker(transport) != null
                         && !getDcTracker(transport).areAllDataDisconnected()) {
                     return false;
@@ -4638,8 +4548,8 @@
 
     public void registerForAllDataDisconnected(Handler h, int what) {
         mAllDataDisconnectedRegistrants.addUnique(h, what, null);
-        if (mAccessNetworksManager != null) {
-            for (int transport : mAccessNetworksManager.getAvailableTransports()) {
+        if (mTransportManager != null) {
+            for (int transport : mTransportManager.getAvailableTransports()) {
                 if (getDcTracker(transport) != null
                         && !getDcTracker(transport).areAllDataDisconnected()) {
                     getDcTracker(transport).registerForAllDataDisconnected(
@@ -4745,21 +4655,6 @@
         mCi.setSimCardPower(state, result, workSource);
     }
 
-    /**
-     * Enable or disable Voice over NR (VoNR)
-     * @param enabled enable or disable VoNR.
-     **/
-    public void setVoNrEnabled(boolean enabled, Message result, WorkSource workSource) {
-        mCi.setVoNrEnabled(enabled, result, workSource);
-    }
-
-    /**
-     * Is voice over NR enabled
-     */
-    public void isVoNrEnabled(Message message, WorkSource workSource) {
-        mCi.isVoNrEnabled(message, workSource);
-    }
-
     public void setCarrierTestOverride(String mccmnc, String imsi, String iccid, String gid1,
             String gid2, String pnn, String spn, String carrierPrivilegeRules, String apn) {
     }
@@ -4862,7 +4757,7 @@
 
     /** @hide */
     public CarrierPrivilegesTracker getCarrierPrivilegesTracker() {
-        return null;
+        return mCarrierPrivilegesTracker;
     }
 
     public boolean useSsOverIms(Message onComplete) {
@@ -4891,12 +4786,12 @@
      * @param isIdle true if the new state is idle
      */
     public void notifyDeviceIdleStateChanged(boolean isIdle) {
-        SignalStrengthController ssc = getSignalStrengthController();
-        if (ssc == null) {
-            Rlog.e(LOG_TAG, "notifyDeviceIdleStateChanged: SignalStrengthController is null");
+        ServiceStateTracker sst = getServiceStateTracker();
+        if (sst == null) {
+            Rlog.e(LOG_TAG, "notifyDeviceIdleStateChanged: SST is null");
             return;
         }
-        ssc.onDeviceIdleStateChanged(isIdle);
+        sst.onDeviceIdleStateChanged(isIdle);
     }
 
     /**
@@ -4939,41 +4834,6 @@
         return null;
     }
 
-    /**
-     * @return The data network controller
-     */
-    public @Nullable DataNetworkController getDataNetworkController() {
-        return mDataNetworkController;
-    }
-
-    /**
-     * @return The data settings manager
-     */
-    public @Nullable DataSettingsManager getDataSettingsManager() {
-        if (mDataNetworkController == null) return null;
-        return mDataNetworkController.getDataSettingsManager();
-    }
-
-    /**
-     * Used in unit tests to set whether the AllowedNetworkTypes is loaded from Db.  Should not
-     * be used otherwise.
-     *
-     * @return {@code true} if the AllowedNetworkTypes is loaded from Db,
-     * {@code false} otherwise.
-     */
-    @VisibleForTesting
-    public boolean isAllowedNetworkTypesLoadedFromDb() {
-        return mIsAllowedNetworkTypesLoadedFromDb;
-    }
-
-    /**
-     * @return {@code true} if using the new telephony data stack.
-     */
-    // This flag and the old data stack code will be deleted in Android 14.
-    public boolean isUsingNewDataStack() {
-        return mNewDataStackEnabled;
-    }
-
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("Phone: subId=" + getSubId());
         pw.println(" mPhoneId=" + mPhoneId);
@@ -5006,10 +4866,10 @@
         pw.println(" getPhoneName()=" + getPhoneName());
         pw.println(" getPhoneType()=" + getPhoneType());
         pw.println(" getVoiceMessageCount()=" + getVoiceMessageCount());
+        pw.println(" getActiveApnTypes()=" + getActiveApnTypes());
         pw.println(" needsOtaServiceProvisioning=" + needsOtaServiceProvisioning());
         pw.println(" isInEmergencySmsMode=" + isInEmergencySmsMode());
         pw.println(" isEcmCanceledForEmergency=" + isEcmCanceledForEmergency());
-        pw.println(" isUsingNewDataStack=" + isUsingNewDataStack());
         pw.println(" service state=" + getServiceState());
         pw.flush();
         pw.println("++++++++++++++++++++++++++++++++");
@@ -5025,8 +4885,8 @@
             pw.println("++++++++++++++++++++++++++++++++");
         }
 
-        if (mAccessNetworksManager != null) {
-            for (int transport : mAccessNetworksManager.getAvailableTransports()) {
+        if (mTransportManager != null) {
+            for (int transport : mTransportManager.getAvailableTransports()) {
                 if (getDcTracker(transport) != null) {
                     getDcTracker(transport).dump(fd, pw, args);
                     pw.flush();
@@ -5035,16 +4895,6 @@
             }
         }
 
-        if (mDataNetworkController != null) {
-            try {
-                mDataNetworkController.dump(fd, pw, args);
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            pw.flush();
-            pw.println("++++++++++++++++++++++++++++++++");
-        }
-
         if (getServiceStateTracker() != null) {
             try {
                 getServiceStateTracker().dump(fd, pw, args);
@@ -5139,14 +4989,8 @@
             pw.println("++++++++++++++++++++++++++++++++");
         }
 
-        if (mSignalStrengthController != null) {
-            pw.println("SignalStrengthController:");
-            mSignalStrengthController.dump(fd, pw, args);
-            pw.println("++++++++++++++++++++++++++++++++");
-        }
-
-        if (mAccessNetworksManager != null) {
-            mAccessNetworksManager.dump(fd, pw, args);
+        if (mTransportManager != null) {
+            mTransportManager.dump(fd, pw, args);
         }
 
         if (mCi != null && mCi instanceof RIL) {
@@ -5199,4 +5043,16 @@
     private static String pii(String s) {
         return Rlog.pii(LOG_TAG, s);
     }
+
+    /**
+     * Used in unit tests to set whether the AllowedNetworkTypes is loaded from Db.  Should not
+     * be used otherwise.
+     *
+     * @return {@code true} if the AllowedNetworkTypes is loaded from Db,
+     * {@code false} otherwise.
+     */
+    @VisibleForTesting
+    public boolean isAllowedNetworkTypesLoadedFromDb() {
+        return mIsAllowedNetworkTypesLoadedFromDb;
+    }
 }
diff --git a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
index 05c325e..d92f96d 100644
--- a/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
+++ b/src/java/com/android/internal/telephony/PhoneConfigurationManager.java
@@ -22,12 +22,11 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.AsyncResult;
-import android.os.Build;
 import android.os.Handler;
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.RegistrantList;
-import android.os.SystemProperties;
+import android.os.storage.StorageManager;
 import android.sysprop.TelephonyProperties;
 import android.telephony.PhoneCapability;
 import android.telephony.SubscriptionManager;
@@ -70,8 +69,7 @@
     private MockableInterface mMi = new MockableInterface();
     private TelephonyManager mTelephonyManager;
     private static final RegistrantList sMultiSimConfigChangeRegistrants = new RegistrantList();
-    private static final String ALLOW_MOCK_MODEM_PROPERTY = "persist.radio.allow_mock_modem";
-    private static final boolean DEBUG = !"user".equals(Build.TYPE);
+
     /**
      * Init method to instantiate the object
      * Should only be called once.
@@ -111,7 +109,11 @@
     }
 
     private void registerForRadioState(Phone phone) {
-        phone.mCi.registerForAvailable(mHandler, Phone.EVENT_RADIO_AVAILABLE, phone);
+        if (!StorageManager.inCryptKeeperBounce()) {
+            phone.mCi.registerForAvailable(mHandler, Phone.EVENT_RADIO_AVAILABLE, phone);
+        } else {
+            phone.mCi.registerForOn(mHandler, Phone.EVENT_RADIO_ON, phone);
+        }
     }
 
     private PhoneCapability getDefaultCapability() {
@@ -334,7 +336,7 @@
             log("switchMultiSimConfig: sending the request for switching");
             Message callback = Message.obtain(
                     mHandler, EVENT_SWITCH_DSDS_CONFIG_DONE, numOfSims, 0 /**dummy arg*/);
-            mRadioConfig.setNumOfLiveModems(numOfSims, callback);
+            mRadioConfig.setModemsConfig(numOfSims, callback);
         } else {
             log("switchMultiSimConfig: No need to switch. getNumOfActiveSims is already "
                     + numOfSims);
@@ -391,24 +393,6 @@
                 registerForRadioState(phone);
                 phone.mCi.onSlotActiveStatusChange(SubscriptionManager.isValidPhoneId(phoneId));
             }
-
-            // When the user enables DSDS mode, the default VOICE and SMS subId should be switched
-            // to "No Preference".  Doing so will sync the network/sim settings and telephony.
-            // (see b/198123192)
-            if (numOfActiveModems > oldNumOfActiveModems && numOfActiveModems == 2) {
-                Log.i(LOG_TAG, " onMultiSimConfigChanged: DSDS mode enabled; "
-                        + "setting VOICE & SMS subId to -1 (No Preference)");
-
-                //Set the default VOICE subId to -1 ("No Preference")
-                SubscriptionController.getInstance().setDefaultVoiceSubId(
-                        SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-
-                //TODO:: Set the default SMS sub to "No Preference". Tracking this bug (b/227386042)
-            } else {
-                Log.i(LOG_TAG,
-                        "onMultiSimConfigChanged: DSDS mode NOT detected.  NOT setting the "
-                                + "default VOICE and SMS subId to -1 (No Preference)");
-            }
         }
     }
 
@@ -460,53 +444,6 @@
         intent.putExtra(EXTRA_ACTIVE_SIM_SUPPORTED_COUNT, numOfActiveModems);
         mContext.sendBroadcast(intent);
     }
-    /**
-     * This is invoked from shell commands during CTS testing only.
-     * @return true if the modem service is set successfully, false otherwise.
-     */
-    public boolean setModemService(String serviceName) {
-        if (mRadioConfig == null || mPhones[0] == null) {
-            return false;
-        }
-
-        log("setModemService: " + serviceName);
-        boolean statusRadioConfig = false;
-        boolean statusRil = false;
-        final boolean isAllowed = SystemProperties.getBoolean(ALLOW_MOCK_MODEM_PROPERTY, false);
-
-        // Check for ALLOW_MOCK_MODEM_PROPERTY on user builds
-        if (isAllowed || DEBUG) {
-            if (serviceName != null) {
-                statusRadioConfig = mRadioConfig.setModemService(serviceName);
-
-                //TODO: consider multi-sim case (b/210073692)
-                statusRil = mPhones[0].mCi.setModemService(serviceName);
-            } else {
-                statusRadioConfig = mRadioConfig.setModemService(null);
-
-                //TODO: consider multi-sim case
-                statusRil = mPhones[0].mCi.setModemService(null);
-            }
-
-            return statusRadioConfig && statusRil;
-        } else {
-            loge("setModemService is not allowed");
-            return false;
-        }
-    }
-
-     /**
-     * This is invoked from shell commands to query during CTS testing only.
-     * @return the service name of the connected service.
-     */
-    public String getModemService() {
-        //TODO: consider multi-sim case
-        if (mPhones[0] == null) {
-            return "";
-        }
-
-        return mPhones[0].mCi.getModemService();
-    }
 
     /**
      * A wrapper class that wraps some methods so that they can be replaced or mocked in unit-tests.
diff --git a/src/java/com/android/internal/telephony/PhoneFactory.java b/src/java/com/android/internal/telephony/PhoneFactory.java
index 3361b74..d51fa91 100644
--- a/src/java/com/android/internal/telephony/PhoneFactory.java
+++ b/src/java/com/android/internal/telephony/PhoneFactory.java
@@ -41,15 +41,15 @@
 import android.util.LocalLog;
 
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
-import com.android.internal.telephony.data.CellularNetworkValidator;
-import com.android.internal.telephony.data.PhoneSwitcher;
-import com.android.internal.telephony.data.TelephonyNetworkFactory;
+import com.android.internal.telephony.dataconnection.TelephonyNetworkFactory;
 import com.android.internal.telephony.euicc.EuiccCardController;
 import com.android.internal.telephony.euicc.EuiccController;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneFactory;
 import com.android.internal.telephony.metrics.MetricsCollector;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
+import com.android.internal.telephony.sip.SipPhone;
+import com.android.internal.telephony.sip.SipPhoneFactory;
 import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.telephony.util.NotificationChannelController;
 import com.android.internal.util.IndentingPrintWriter;
@@ -411,6 +411,15 @@
     }
 
     /**
+     * Makes a {@link SipPhone} object.
+     * @param sipUri the local SIP URI the phone runs on
+     * @return the {@code SipPhone} object or null if the SIP URI is not valid
+     */
+    public static SipPhone makeSipPhone(String sipUri) {
+        return SipPhoneFactory.makePhone(sipUri, sContext, sPhoneNotifier);
+    }
+
+    /**
      * Returns the preferred network type bitmask that should be set in the modem.
      *
      * @param phoneId The phone's id.
diff --git a/src/java/com/android/internal/telephony/PhoneInternalInterface.java b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
index 5b4d5e5..437459f 100644
--- a/src/java/com/android/internal/telephony/PhoneInternalInterface.java
+++ b/src/java/com/android/internal/telephony/PhoneInternalInterface.java
@@ -26,7 +26,6 @@
 import android.os.ResultReceiver;
 import android.os.WorkSource;
 import android.telecom.VideoProfile;
-import android.telephony.Annotation.DataActivityType;
 import android.telephony.ImsiEncryptionInfo;
 import android.telephony.NetworkScanRequest;
 import android.telephony.PreciseDataConnectionState;
@@ -209,7 +208,6 @@
     static final String REASON_IWLAN_DATA_SERVICE_DIED = "iwlanDataServiceDied";
     static final String REASON_VCN_REQUESTED_TEARDOWN = "vcnRequestedTeardown";
     static final String REASON_DATA_UNTHROTTLED = "dataUnthrottled";
-    static final String REASON_TRAFFIC_DESCRIPTORS_UPDATED = "trafficDescriptorsUpdated";
 
     // Reasons for Radio being powered off
     int RADIO_POWER_REASON_USER = 0;
@@ -313,10 +311,11 @@
     PreciseDataConnectionState getPreciseDataConnectionState(String apnType);
 
     /**
-     * Get the current data activity. No change notification exists at this
-     * interface.
+     * Get the current DataActivityState. No change notification exists at this
+     * interface -- use
+     * {@link android.telephony.TelephonyManager} instead.
      */
-    @DataActivityType int getDataActivityState();
+    DataActivityState getDataActivityState();
 
     /**
      * Returns a list of MMI codes that are pending. (They have initiated
@@ -1097,10 +1096,4 @@
      *  their mobile plan.
      */
     String getMobileProvisioningUrl();
-
-    /**
-     * Update the cellular usage setting if applicable.
-     */
-    boolean updateUsageSetting();
-
 }
diff --git a/src/java/com/android/internal/telephony/PhoneSubInfoController.java b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
index b1dfa5f..36ed749 100644
--- a/src/java/com/android/internal/telephony/PhoneSubInfoController.java
+++ b/src/java/com/android/internal/telephony/PhoneSubInfoController.java
@@ -39,8 +39,8 @@
 import android.util.EventLog;
 
 import com.android.internal.telephony.uicc.IsimRecords;
+import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccCardApplication;
-import com.android.internal.telephony.uicc.UiccPort;
 import com.android.telephony.Rlog;
 
 public class PhoneSubInfoController extends IPhoneSubInfo.Stub {
@@ -422,13 +422,13 @@
     public String getIccSimChallengeResponse(int subId, int appType, int authType, String data,
             String callingPackage, String callingFeatureId) throws RemoteException {
         CallPhoneMethodHelper<String> toExecute = (phone)-> {
-            UiccPort uiccPort = phone.getUiccPort();
-            if (uiccPort == null) {
-                loge("getIccSimChallengeResponse() uiccPort is null");
+            UiccCard uiccCard = phone.getUiccCard();
+            if (uiccCard == null) {
+                loge("getIccSimChallengeResponse() UiccCard is null");
                 return null;
             }
 
-            UiccCardApplication uiccApp = uiccPort.getApplicationByType(appType);
+            UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType);
             if (uiccApp == null) {
                 loge("getIccSimChallengeResponse() no app with specified type -- " + appType);
                 return null;
diff --git a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java b/src/java/com/android/internal/telephony/PhoneSwitcher.java
similarity index 86%
rename from src/java/com/android/internal/telephony/data/PhoneSwitcher.java
rename to src/java/com/android/internal/telephony/PhoneSwitcher.java
index cc5f447..5f312db 100644
--- a/src/java/com/android/internal/telephony/data/PhoneSwitcher.java
+++ b/src/java/com/android/internal/telephony/PhoneSwitcher.java
@@ -14,7 +14,7 @@
 * limitations under the License.
 */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony;
 
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 import static android.telephony.CarrierConfigManager.KEY_DATA_SWITCH_VALIDATION_TIMEOUT_LONG;
@@ -30,7 +30,6 @@
 
 import static java.util.Arrays.copyOf;
 
-import android.annotation.NonNull;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -65,24 +64,12 @@
 import android.telephony.ims.ImsRegistrationAttributes;
 import android.telephony.ims.RegistrationManager;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.util.ArrayMap;
 import android.util.LocalLog;
 
 import com.android.ims.ImsException;
 import com.android.ims.ImsManager;
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.ISetOpportunisticDataCallback;
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConfigurationManager;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.RadioConfig;
-import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.SubscriptionController.WatchedInt;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
-import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
 import com.android.internal.telephony.dataconnection.ApnConfigTypeRepository;
 import com.android.internal.telephony.dataconnection.DcRequest;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
@@ -99,7 +86,6 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 
@@ -183,7 +169,6 @@
     }
 
     protected final List<DcRequest> mPrioritizedDcRequests = new ArrayList<>();
-    private final @NonNull NetworkRequestList mNetworkRequestList = new NetworkRequestList();
     protected final RegistrantList mActivePhoneRegistrants;
     protected final SubscriptionController mSubscriptionController;
     protected final Context mContext;
@@ -312,7 +297,7 @@
 
     protected RadioConfig mRadioConfig;
 
-    private static final int MAX_LOCAL_LOG_LINES = 256;
+    private final static int MAX_LOCAL_LOG_LINES = 30;
 
     // Default timeout value of network validation in millisecond.
     private final static int DEFAULT_VALIDATION_EXPIRATION_TIME = 2000;
@@ -324,10 +309,6 @@
 
     private List<Set<CommandException.Error>> mCurrentDdsSwitchFailure;
 
-    /** Data settings manager callback. Key is the phone id. */
-    private final @NonNull Map<Integer, DataSettingsManagerCallback> mDataSettingsManagerCallbacks =
-            new ArrayMap<>();
-
     private class DefaultNetworkCallback extends ConnectivityManager.NetworkCallback {
         public int mExpectedSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
         public int mSwitchReason = TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN;
@@ -496,33 +477,18 @@
         mActivePhoneRegistrants = new RegistrantList();
         for (int i = 0; i < mActiveModemCount; i++) {
             mPhoneStates[i] = new PhoneState();
-            Phone phone = PhoneFactory.getPhone(i);
-            if (phone != null) {
-                phone.registerForEmergencyCallToggle(
+            if (PhoneFactory.getPhone(i) != null) {
+                PhoneFactory.getPhone(i).registerForEmergencyCallToggle(
                         this, EVENT_EMERGENCY_TOGGLE, null);
                 // TODO (b/135566422): combine register for both GsmCdmaPhone and ImsPhone.
-                phone.registerForPreciseCallStateChanged(
+                PhoneFactory.getPhone(i).registerForPreciseCallStateChanged(
                         this, EVENT_PRECISE_CALL_STATE_CHANGED, null);
-                if (phone.getImsPhone() != null) {
-                    phone.getImsPhone().registerForPreciseCallStateChanged(
+                if (PhoneFactory.getPhone(i).getImsPhone() != null) {
+                    PhoneFactory.getPhone(i).getImsPhone().registerForPreciseCallStateChanged(
                             this, EVENT_PRECISE_CALL_STATE_CHANGED, null);
                 }
-                if (phone.isUsingNewDataStack()) {
-                    mDataSettingsManagerCallbacks.computeIfAbsent(phone.getPhoneId(),
-                            v -> new DataSettingsManagerCallback(this::post) {
-                                @Override
-                                public void onDataEnabledChanged(boolean enabled,
-                                        @TelephonyManager.DataEnabledChangedReason int reason,
-                                        @NonNull String callingPackage) {
-                                    evaluateIfDataSwitchIsNeeded("EVENT_DATA_ENABLED_CHANGED");
-                                }});
-                    phone.getDataSettingsManager().registerCallback(
-                            mDataSettingsManagerCallbacks.get(phone.getPhoneId()));
-                } else {
-                    phone.getDataEnabledSettings().registerForDataEnabledChanged(
-                            this, EVENT_DATA_ENABLED_CHANGED, null);
-                }
-
+                PhoneFactory.getPhone(i).getDataEnabledSettings().registerForDataEnabledChanged(
+                        this, EVENT_DATA_ENABLED_CHANGED, null);
                 registerForImsRadioTechChange(context, i);
             }
             Set<CommandException.Error> ddsFailure = new HashSet<CommandException.Error>();
@@ -557,20 +523,12 @@
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_IA)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_MCX)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
-                .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_1)
-                .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_2)
-                .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_3)
-                .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_4)
-                .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_5)
                 .setNetworkSpecifier(new MatchAllNetworkSpecifier());
 
         NetworkFactory networkFactory = new PhoneSwitcherNetworkRequestListener(looper, context,
@@ -879,23 +837,8 @@
                 phone.getImsPhone().registerForPreciseCallStateChanged(
                         this, EVENT_PRECISE_CALL_STATE_CHANGED, null);
             }
-
-            if (phone.isUsingNewDataStack()) {
-                mDataSettingsManagerCallbacks.computeIfAbsent(phone.getPhoneId(),
-                        v -> new DataSettingsManagerCallback(this::post) {
-                            @Override
-                            public void onDataEnabledChanged(boolean enabled,
-                                    @TelephonyManager.DataEnabledChangedReason int reason,
-                                    @NonNull String callingPackage) {
-                                evaluateIfDataSwitchIsNeeded("EVENT_DATA_ENABLED_CHANGED");
-                            }
-                        });
-                phone.getDataSettingsManager().registerCallback(
-                        mDataSettingsManagerCallbacks.get(phone.getPhoneId()));
-            } else {
-                phone.getDataEnabledSettings().registerForDataEnabledChanged(
-                        this, EVENT_DATA_ENABLED_CHANGED, null);
-            }
+            phone.getDataEnabledSettings().registerForDataEnabledChanged(
+                    this, EVENT_DATA_ENABLED_CHANGED, null);
 
             Set<CommandException.Error> ddsFailure = new HashSet<CommandException.Error>();
             mCurrentDdsSwitchFailure.add(ddsFailure);
@@ -941,15 +884,6 @@
     }
 
     private void onRequestNetwork(NetworkRequest networkRequest) {
-        if (PhoneFactory.getDefaultPhone().isUsingNewDataStack()) {
-            TelephonyNetworkRequest telephonyNetworkRequest = new TelephonyNetworkRequest(
-                    networkRequest, PhoneFactory.getDefaultPhone());
-            if (!mNetworkRequestList.contains(telephonyNetworkRequest)) {
-                mNetworkRequestList.add(telephonyNetworkRequest);
-                onEvaluate(REQUESTS_CHANGED, "netRequest");
-            }
-            return;
-        }
         final DcRequest dcRequest =
                 DcRequest.create(networkRequest, createApnRepository(networkRequest));
         if (dcRequest != null) {
@@ -958,28 +892,19 @@
                 mPrioritizedDcRequests.add(dcRequest);
                 Collections.sort(mPrioritizedDcRequests);
                 onEvaluate(REQUESTS_CHANGED, "netRequest");
-                if (VDBG) log("Added DcRequest, size: " + mPrioritizedDcRequests.size());
+                log("Added DcRequest, size: " + mPrioritizedDcRequests.size());
             }
         }
     }
 
     private void onReleaseNetwork(NetworkRequest networkRequest) {
-        if (PhoneFactory.getDefaultPhone().isUsingNewDataStack()) {
-            TelephonyNetworkRequest telephonyNetworkRequest = new TelephonyNetworkRequest(
-                    networkRequest, PhoneFactory.getDefaultPhone());
-            if (mNetworkRequestList.remove(telephonyNetworkRequest)) {
-                onEvaluate(REQUESTS_CHANGED, "netReleased");
-                collectReleaseNetworkMetrics(networkRequest);
-            }
-            return;
-        }
         final DcRequest dcRequest =
                 DcRequest.create(networkRequest, createApnRepository(networkRequest));
         if (dcRequest != null) {
             if (mPrioritizedDcRequests.remove(dcRequest)) {
                 onEvaluate(REQUESTS_CHANGED, "netReleased");
                 collectReleaseNetworkMetrics(networkRequest);
-                if (VDBG) log("Removed DcRequest, size: " + mPrioritizedDcRequests.size());
+                log("Removed DcRequest, size: " + mPrioritizedDcRequests.size());
             }
         }
     }
@@ -1147,22 +1072,12 @@
                     }
 
                     if (newActivePhones.size() < mMaxDataAttachModemCount) {
-                        if (PhoneFactory.getDefaultPhone().isUsingNewDataStack()) {
-                            for (TelephonyNetworkRequest networkRequest : mNetworkRequestList) {
-                                int phoneIdForRequest = phoneIdForRequest(networkRequest);
-                                if (phoneIdForRequest == INVALID_PHONE_INDEX) continue;
-                                if (newActivePhones.contains(phoneIdForRequest)) continue;
-                                newActivePhones.add(phoneIdForRequest);
-                                if (newActivePhones.size() >= mMaxDataAttachModemCount) break;
-                            }
-                        } else {
-                            for (DcRequest dcRequest : mPrioritizedDcRequests) {
-                                int phoneIdForRequest = phoneIdForRequest(dcRequest.networkRequest);
-                                if (phoneIdForRequest == INVALID_PHONE_INDEX) continue;
-                                if (newActivePhones.contains(phoneIdForRequest)) continue;
-                                newActivePhones.add(phoneIdForRequest);
-                                if (newActivePhones.size() >= mMaxDataAttachModemCount) break;
-                            }
+                        for (DcRequest dcRequest : mPrioritizedDcRequests) {
+                            int phoneIdForRequest = phoneIdForRequest(dcRequest.networkRequest);
+                            if (phoneIdForRequest == INVALID_PHONE_INDEX) continue;
+                            if (newActivePhones.contains(phoneIdForRequest)) continue;
+                            newActivePhones.add(phoneIdForRequest);
+                            if (newActivePhones.size() >= mMaxDataAttachModemCount) break;
                         }
                     }
 
@@ -1264,7 +1179,7 @@
 
     protected void sendRilCommands(int phoneId) {
         if (!SubscriptionManager.isValidPhoneId(phoneId)) {
-            log("sendRilCommands: skip dds switch due to invalid phoneId=" + phoneId);
+            log("sendRilCommands: skip dds switch due to invalid phoneid=" + phoneId);
             return;
         }
 
@@ -1291,12 +1206,6 @@
         }
     }
 
-    // Merge phoneIdForRequest(NetworkRequest netRequest) after Phone.isUsingNewDataStack() is
-    // cleaned up.
-    private int phoneIdForRequest(TelephonyNetworkRequest networkRequest) {
-        return phoneIdForRequest(networkRequest.getNativeNetworkRequest());
-    }
-
     private int phoneIdForRequest(NetworkRequest netRequest) {
         int subId = getSubIdFromNetworkSpecifier(netRequest.getNetworkSpecifier());
 
@@ -1353,17 +1262,6 @@
     // requests.
     protected void updatePreferredDataPhoneId() {
         Phone voicePhone = findPhoneById(mPhoneIdInVoiceCall);
-        boolean isDataEnabled = false;
-        if (voicePhone != null) {
-            if (voicePhone.isUsingNewDataStack()) {
-                isDataEnabled = voicePhone.getDataSettingsManager()
-                        .isDataEnabled(ApnSetting.TYPE_DEFAULT);
-            } else {
-                isDataEnabled = voicePhone.getDataEnabledSettings()
-                        .isDataEnabled(ApnSetting.TYPE_DEFAULT);
-            }
-        }
-
         if (mEmergencyOverride != null && findPhoneById(mEmergencyOverride.mPhoneId) != null) {
             // Override DDS for emergency even if user data is not enabled, since it is an
             // emergency.
@@ -1372,7 +1270,8 @@
             log("updatePreferredDataPhoneId: preferred data overridden for emergency."
                     + " phoneId = " + mEmergencyOverride.mPhoneId);
             mPreferredDataPhoneId = mEmergencyOverride.mPhoneId;
-        } else if (isDataEnabled) {
+        } else if (voicePhone != null && voicePhone.getDataEnabledSettings().isDataEnabled(
+                ApnSetting.TYPE_DEFAULT)) {
             // If a phone is in call and user enabled its mobile data, we
             // should switch internet connection to it. Because the other modem
             // will lose data connection anyway.
@@ -1423,7 +1322,7 @@
     }
 
     public synchronized boolean shouldApplyNetworkRequest(
-            TelephonyNetworkRequest networkRequest, int phoneId) {
+            NetworkRequest networkRequest, int phoneId) {
         if (!SubscriptionManager.isValidPhoneId(phoneId)) return false;
 
         // In any case, if phone state is inactive, don't apply the network request.
@@ -1433,21 +1332,12 @@
             return false;
         }
 
-        NetworkRequest netRequest = networkRequest.getNativeNetworkRequest();
-        int subId = getSubIdFromNetworkSpecifier(netRequest.getNetworkSpecifier());
-
-        //if this phone is an emergency networkRequest
-        //and subId is not specified that is invalid or default
-        if (isAnyVoiceCallActiveOnDevice() && isEmergencyNetworkRequest(networkRequest)
-                && (subId == DEFAULT_SUBSCRIPTION_ID || subId == INVALID_SUBSCRIPTION_ID)) {
-            return phoneId == mPhoneIdInVoiceCall;
-        }
-
         int phoneIdToHandle = phoneIdForRequest(networkRequest);
+
         return phoneId == phoneIdToHandle;
     }
 
-    boolean isEmergencyNetworkRequest(TelephonyNetworkRequest networkRequest) {
+    boolean isEmergencyNetworkRequest(NetworkRequest networkRequest) {
         return networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS);
     }
 
@@ -1651,8 +1541,14 @@
         }
 
         // A phone in voice call might trigger data being switched to it.
-        return (!phone.getBackgroundCall().isIdle()
-                || !phone.getForegroundCall().isIdle());
+        // We only report true if its precise call state is ACTIVE, ALERTING or HOLDING.
+        // The reason is data switching is interrupting, so we only switch when necessary and
+        // acknowledged by the users. For incoming call, we don't switch until answered
+        // (RINGING -> ACTIVE), for outgoing call we don't switch until call is connected
+        // in network (DIALING -> ALERTING).
+        return (phone.getForegroundCall().getState() == Call.State.ACTIVE
+                || phone.getForegroundCall().getState() == Call.State.ALERTING
+                || phone.getBackgroundCall().getState() == Call.State.HOLDING);
     }
 
     private void updateHalCommandToUse() {
@@ -1674,54 +1570,8 @@
         mLocalLog.log(l);
     }
 
-    /**
-     * Convert data switch reason into string.
-     *
-     * @param reason The switch reason.
-     * @return The switch reason in string format.
-     */
-    private static @NonNull String switchReasonToString(int reason) {
-        switch(reason) {
-            case TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN:
-                return "UNKNOWN";
-            case TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL:
-                return "MANUAL";
-            case TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL:
-                return "IN_CALL";
-            case TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_CBRS:
-                return "CBRS";
-            default: return "UNKNOWN(" + reason + ")";
-        }
-    }
-
-    /**
-     * Concert switching state to string
-     *
-     * @param state The switching state.
-     * @return The switching state in string format.
-     */
-    private static @NonNull String switchStateToString(int state) {
-        switch(state) {
-            case TelephonyEvent.EventState.EVENT_STATE_UNKNOWN:
-                return "UNKNOWN";
-            case TelephonyEvent.EventState.EVENT_STATE_START:
-                return "START";
-            case TelephonyEvent.EventState.EVENT_STATE_END:
-                return "END";
-            default: return "UNKNOWN(" + state + ")";
-        }
-    }
-
-    /**
-     * Log data switch event
-     *
-     * @param subId Subscription index.
-     * @param state The switching state.
-     * @param reason The switching reason.
-     */
     private void logDataSwitchEvent(int subId, int state, int reason) {
-        log("Data switch event. subId=" + subId + ", state=" + switchStateToString(state)
-                + ", reason=" + switchReasonToString(reason));
+        log("logDataSwitchEvent subId " + subId + " state " + state + " reason " + reason);
         DataSwitch dataSwitch = new DataSwitch();
         dataSwitch.state = state;
         dataSwitch.reason = reason;
@@ -1754,7 +1604,6 @@
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
         pw.println("PhoneSwitcher:");
-        pw.increaseIndent();
         Calendar c = Calendar.getInstance();
         for (int i = 0; i < mActiveModemCount; i++) {
             PhoneState ps = mPhoneStates[i];
@@ -1763,29 +1612,14 @@
                     (ps.lastRequested == 0 ? "never" :
                      String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c)));
         }
-        pw.println("mPreferredDataPhoneId=" + mPreferredDataPhoneId);
-        pw.println("mPreferredDataSubId=" + mPreferredDataSubId.get());
-        pw.println("DefaultDataSubId=" + mSubscriptionController.getDefaultDataSubId());
-        pw.println("DefaultDataPhoneId=" + mSubscriptionController.getPhoneId(
-                mSubscriptionController.getDefaultDataSubId()));
-        pw.println("mPrimaryDataSubId=" + mPrimaryDataSubId);
-        pw.println("mOpptDataSubId=" + mOpptDataSubId);
-        pw.println("mIsRegisteredForImsRadioTechChange=" + mIsRegisteredForImsRadioTechChange);
-        pw.println("mPendingSwitchNeedValidation=" + mPendingSwitchNeedValidation);
-        pw.println("mMaxDataAttachModemCount=" + mMaxDataAttachModemCount);
-        pw.println("mActiveModemCount=" + mActiveModemCount);
-        pw.println("mPhoneIdInVoiceCall=" + mPhoneIdInVoiceCall);
-        pw.println("mCurrentDdsSwitchFailure=" + mCurrentDdsSwitchFailure);
-        pw.println("Local logs:");
         pw.increaseIndent();
         mLocalLog.dump(fd, pw, args);
         pw.decreaseIndent();
-        pw.decreaseIndent();
     }
 
     private boolean isAnyVoiceCallActiveOnDevice() {
         boolean ret = mPhoneIdInVoiceCall != SubscriptionManager.INVALID_PHONE_INDEX;
-        if (VDBG) log("isAnyVoiceCallActiveOnDevice: " + ret);
+        log("isAnyVoiceCallActiveOnDevice: " + ret);
         return ret;
     }
 
@@ -1832,26 +1666,16 @@
         if (ddsPhoneId != INVALID_PHONE_INDEX && ddsPhoneId == phoneId) {
             return true;
         } else {
-            if (PhoneFactory.getDefaultPhone().isUsingNewDataStack()) {
-                if (mNetworkRequestList.isEmpty()) return false;
-                for (TelephonyNetworkRequest networkRequest : mNetworkRequestList) {
-                    phoneIdForRequest = phoneIdForRequest(networkRequest);
+            if (mPrioritizedDcRequests.size() == 0) {
+                return false;
+            }
+            for (DcRequest dcRequest : mPrioritizedDcRequests) {
+                if (dcRequest != null) {
+                    phoneIdForRequest = phoneIdForRequest(dcRequest.networkRequest);
                     if (phoneIdForRequest == phoneId) {
                         return true;
                     }
                 }
-            } else {
-                if (mPrioritizedDcRequests.size() == 0) {
-                    return false;
-                }
-                for (DcRequest dcRequest : mPrioritizedDcRequests) {
-                    if (dcRequest != null) {
-                        phoneIdForRequest = phoneIdForRequest(dcRequest.networkRequest);
-                        if (phoneIdForRequest == phoneId) {
-                            return true;
-                        }
-                    }
-                }
             }
         }
         return false;
diff --git a/src/java/com/android/internal/telephony/ProxyController.java b/src/java/com/android/internal/telephony/ProxyController.java
index 76f0041..187f5e2 100644
--- a/src/java/com/android/internal/telephony/ProxyController.java
+++ b/src/java/com/android/internal/telephony/ProxyController.java
@@ -33,7 +33,6 @@
 import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.data.PhoneSwitcher;
 import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
@@ -45,8 +44,7 @@
     static final String LOG_TAG = "ProxyController";
 
     private static final int EVENT_NOTIFICATION_RC_CHANGED  = 1;
-    @VisibleForTesting
-    static final int EVENT_START_RC_RESPONSE                = 2;
+    private static final int EVENT_START_RC_RESPONSE        = 2;
     private static final int EVENT_APPLY_RC_RESPONSE        = 3;
     private static final int EVENT_FINISH_RC_RESPONSE       = 4;
     private static final int EVENT_TIMEOUT                  = 5;
@@ -366,24 +364,14 @@
             // Abort here only in Single SIM case, in Multi SIM cases
             // send FINISH with failure so that below layers can re-bind
             // old logical modems.
-            if (ar.exception != null) {
-                boolean isPermanaentFailure = false;
-                if (ar.exception instanceof CommandException) {
-                    CommandException.Error error =
-                            ((CommandException) (ar.exception)).getCommandError();
-                    if (error == CommandException.Error.REQUEST_NOT_SUPPORTED) {
-                        isPermanaentFailure = true;
-                    }
-                }
-                if (TelephonyManager.getDefault().getPhoneCount() == 1  || isPermanaentFailure) {
-                    // just abort now.  They didn't take our start so we don't have to revert
-                    logd("onStartRadioCapabilityResponse got exception=" + ar.exception);
-                    mRadioCapabilitySessionId = mUniqueIdGenerator.getAndIncrement();
-                    Intent intent = new Intent(TelephonyIntents.ACTION_SET_RADIO_CAPABILITY_FAILED);
-                    mContext.sendBroadcast(intent);
-                    clearTransaction();
-                    return;
-                }
+            if ((TelephonyManager.getDefault().getPhoneCount() == 1) && (ar.exception != null)) {
+                // just abort now.  They didn't take our start so we don't have to revert
+                logd("onStartRadioCapabilityResponse got exception=" + ar.exception);
+                mRadioCapabilitySessionId = mUniqueIdGenerator.getAndIncrement();
+                Intent intent = new Intent(TelephonyIntents.ACTION_SET_RADIO_CAPABILITY_FAILED);
+                mContext.sendBroadcast(intent);
+                clearTransaction();
+                return;
             }
             RadioCapability rc = (RadioCapability) ((AsyncResult) msg.obj).result;
             if ((rc == null) || (rc.getSession() != mRadioCapabilitySessionId)) {
@@ -393,7 +381,7 @@
             }
             mRadioAccessFamilyStatusCounter--;
             int id = rc.getPhoneId();
-            if (ar.exception != null) {
+            if (((AsyncResult) msg.obj).exception != null) {
                 logd("onStartRadioCapabilityResponse: Error response session=" + rc.getSession());
                 logd("onStartRadioCapabilityResponse: phoneId=" + id + " status=FAIL");
                 mSetRadioAccessFamilyStatus[id] = SET_RC_STATUS_FAIL;
@@ -630,24 +618,12 @@
                 mTransactionFailed = false;
             }
 
-            if (isWakeLockHeld()) {
+            if (mWakeLock.isHeld()) {
                 mWakeLock.release();
             }
         }
     }
 
-    /**
-     * check if wakelock is held.
-     *
-     * @return true if wakelock is held else false.
-     */
-    @VisibleForTesting
-    public boolean isWakeLockHeld() {
-        synchronized (mSetRadioAccessFamilyStatus) {
-            return mWakeLock.isHeld();
-        }
-    }
-
     private void resetRadioAccessFamilyStatusCounter() {
         mRadioAccessFamilyStatusCounter = mPhones.length;
     }
diff --git a/src/java/com/android/internal/telephony/RIL.java b/src/java/com/android/internal/telephony/RIL.java
index 49e8297..bd71b0b 100644
--- a/src/java/com/android/internal/telephony/RIL.java
+++ b/src/java/com/android/internal/telephony/RIL.java
@@ -17,32 +17,65 @@
 package com.android.internal.telephony;
 
 import static com.android.internal.telephony.RILConstants.*;
+import static com.android.internal.util.Preconditions.checkNotNull;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.hardware.radio.V1_0.Carrier;
+import android.hardware.radio.V1_0.CarrierRestrictions;
+import android.hardware.radio.V1_0.CdmaBroadcastSmsConfigInfo;
+import android.hardware.radio.V1_0.CdmaSmsAck;
+import android.hardware.radio.V1_0.CdmaSmsMessage;
+import android.hardware.radio.V1_0.CdmaSmsWriteArgs;
+import android.hardware.radio.V1_0.DataProfileId;
+import android.hardware.radio.V1_0.Dial;
+import android.hardware.radio.V1_0.GsmBroadcastSmsConfigInfo;
+import android.hardware.radio.V1_0.GsmSmsMessage;
+import android.hardware.radio.V1_0.HardwareConfigModem;
 import android.hardware.radio.V1_0.IRadio;
+import android.hardware.radio.V1_0.IccIo;
+import android.hardware.radio.V1_0.ImsSmsMessage;
+import android.hardware.radio.V1_0.LceDataInfo;
+import android.hardware.radio.V1_0.MvnoType;
+import android.hardware.radio.V1_0.NvWriteItem;
 import android.hardware.radio.V1_0.RadioError;
 import android.hardware.radio.V1_0.RadioIndicationType;
 import android.hardware.radio.V1_0.RadioResponseInfo;
 import android.hardware.radio.V1_0.RadioResponseType;
+import android.hardware.radio.V1_0.RadioTechnologyFamily;
+import android.hardware.radio.V1_0.ResetNvType;
+import android.hardware.radio.V1_0.SelectUiccSub;
+import android.hardware.radio.V1_0.SimApdu;
+import android.hardware.radio.V1_0.SmsWriteArgs;
+import android.hardware.radio.V1_0.UusInfo;
+import android.hardware.radio.V1_4.CarrierRestrictionsWithPriority;
+import android.hardware.radio.V1_4.SimLockMultiSimPolicy;
+import android.hardware.radio.V1_5.AccessNetwork;
+import android.hardware.radio.V1_5.IndicationFilter;
+import android.hardware.radio.V1_5.PersoSubstate;
+import android.hardware.radio.V1_5.RadioAccessNetworks;
+import android.hardware.radio.V1_6.OptionalDnn;
+import android.hardware.radio.V1_6.OptionalOsAppId;
+import android.hardware.radio.V1_6.OptionalSliceInfo;
+import android.hardware.radio.V1_6.OptionalTrafficDescriptor;
+import android.net.InetAddresses;
 import android.net.KeepalivePacketData;
+import android.net.LinkAddress;
 import android.net.LinkProperties;
 import android.os.AsyncResult;
 import android.os.Build;
 import android.os.Handler;
 import android.os.HwBinder;
-import android.os.IBinder;
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.SystemClock;
-import android.os.SystemProperties;
 import android.os.WorkSource;
 import android.provider.Settings;
+import android.service.carrier.CarrierIdentifier;
 import android.sysprop.TelephonyProperties;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.CarrierRestrictionRules;
@@ -55,26 +88,38 @@
 import android.telephony.CellSignalStrengthWcdma;
 import android.telephony.ClientRequestStats;
 import android.telephony.ImsiEncryptionInfo;
+import android.telephony.LinkCapacityEstimate;
 import android.telephony.ModemActivityInfo;
 import android.telephony.NeighboringCellInfo;
 import android.telephony.NetworkScanRequest;
+import android.telephony.PhoneNumberUtils;
 import android.telephony.RadioAccessFamily;
 import android.telephony.RadioAccessSpecifier;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SignalThresholdInfo;
+import android.telephony.SmsManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyHistogram;
 import android.telephony.TelephonyManager;
 import android.telephony.TelephonyManager.PrefNetworkMode;
+import android.telephony.data.ApnSetting;
+import android.telephony.data.DataCallResponse;
+import android.telephony.data.DataCallResponse.HandoverFailureMode;
 import android.telephony.data.DataProfile;
+import android.telephony.data.DataService;
 import android.telephony.data.NetworkSliceInfo;
+import android.telephony.data.Qos;
+import android.telephony.data.QosBearerSession;
 import android.telephony.data.TrafficDescriptor;
 import android.telephony.emergency.EmergencyNumber;
 import android.text.TextUtils;
+import android.util.Log;
 import android.util.SparseArray;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.cat.ComprehensionTlv;
+import com.android.internal.telephony.cat.ComprehensionTlvTag;
 import com.android.internal.telephony.cdma.CdmaInformationRecords;
 import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
@@ -87,18 +132,24 @@
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
 
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
 import java.io.FileDescriptor;
+import java.io.IOException;
 import java.io.PrintWriter;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import java.util.NoSuchElementException;
-import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.stream.Collectors;
 
 /**
  * RIL implementation of the CommandsInterface.
@@ -155,12 +206,22 @@
     /** @hide */
     public static final HalVersion RADIO_HAL_VERSION_1_6 = new HalVersion(1, 6);
 
-    /** @hide */
-    public static final HalVersion RADIO_HAL_VERSION_2_0 = new HalVersion(2, 0);
-
     // IRadio version
     private HalVersion mRadioVersion = RADIO_HAL_VERSION_UNKNOWN;
 
+    private static final int INDICATION_FILTERS_ALL_V1_0 =
+            IndicationFilter.SIGNAL_STRENGTH
+            | IndicationFilter.FULL_NETWORK_STATE
+            | IndicationFilter.DATA_CALL_DORMANCY_CHANGED;
+    private static final int INDICATION_FILTERS_ALL_V1_2 =
+            INDICATION_FILTERS_ALL_V1_0
+            | IndicationFilter.LINK_CAPACITY_ESTIMATE
+            | IndicationFilter.PHYSICAL_CHANNEL_CONFIG;
+    private static final  int INDICATION_FILTERS_ALL_V1_5 =
+            INDICATION_FILTERS_ALL_V1_2
+            | IndicationFilter.REGISTRATION_FAILURE
+            | IndicationFilter.BARRING_INFO;
+
     //***** Instance Variables
 
     @UnsupportedAppUsage
@@ -179,15 +240,14 @@
     volatile int mAckWlSequenceNum = 0;
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    SparseArray<RILRequest> mRequestList = new SparseArray<>();
-    static SparseArray<TelephonyHistogram> sRilTimeHistograms = new SparseArray<>();
+    SparseArray<RILRequest> mRequestList = new SparseArray<RILRequest>();
+    static SparseArray<TelephonyHistogram> mRilTimeHistograms = new
+            SparseArray<TelephonyHistogram>();
 
     Object[] mLastNITZTimeInfo;
 
     int mLastRadioPowerResult = RadioError.NONE;
 
-    boolean mIsRadioProxyInitialized = false;
-
     // When we are testing emergency calls using ril.test.emergencynumber, this will trigger test
     // ECbM when the call is ended.
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -195,25 +255,11 @@
 
     final Integer mPhoneId;
 
-    private static final String PROPERTY_IS_VONR_ENABLED = "persist.radio.is_vonr_enabled_";
-
-    static final int RADIO_SERVICE = 0;
-    static final int DATA_SERVICE = 1;
-    static final int MESSAGING_SERVICE = 2;
-    static final int MODEM_SERVICE = 3;
-    static final int NETWORK_SERVICE = 4;
-    static final int SIM_SERVICE = 5;
-    static final int VOICE_SERVICE = 6;
-    static final int MIN_SERVICE_IDX = RADIO_SERVICE;
-    static final int MAX_SERVICE_IDX = VOICE_SERVICE;
-
     /**
-     * An array of sets that records if services are disabled in the HAL for a specific phone ID
-     * slot to avoid further getService requests for that service. See XXX_SERVICE for the indices.
-     * RADIO_SERVICE is the HIDL IRadio service, and mDisabledRadioServices.get(RADIO_SERVICE)
-     * will return a set of all phone ID slots that are disabled for IRadio.
+     * A set that records if radio service is disabled in hal for
+     * a specific phone id slot to avoid further getService request.
      */
-    private final SparseArray<Set<Integer>> mDisabledRadioServices = new SparseArray<>();
+    Set<Integer> mDisabledRadioServices = new HashSet();
 
     /* default work source which will blame phone process */
     private WorkSource mRILDefaultWorkSource;
@@ -226,53 +272,42 @@
     /** Radio bug detector instance */
     private RadioBugDetector mRadioBugDetector = null;
 
-    private boolean mIsCellularSupported;
-    private RadioResponse mRadioResponse;
-    private RadioIndication mRadioIndication;
-    private volatile IRadio mRadioProxy = null;
-    private DataResponse mDataResponse;
-    private DataIndication mDataIndication;
-    private MessagingResponse mMessagingResponse;
-    private MessagingIndication mMessagingIndication;
-    private ModemResponse mModemResponse;
-    private ModemIndication mModemIndication;
-    private NetworkResponse mNetworkResponse;
-    private NetworkIndication mNetworkIndication;
-    private SimResponse mSimResponse;
-    private SimIndication mSimIndication;
-    private VoiceResponse mVoiceResponse;
-    private VoiceIndication mVoiceIndication;
-    private SparseArray<RadioServiceProxy> mServiceProxies = new SparseArray<>();
-    private final SparseArray<BinderServiceDeathRecipient> mDeathRecipients = new SparseArray<>();
-    private final SparseArray<AtomicLong> mServiceCookies = new SparseArray<>();
-    private final RadioProxyDeathRecipient mRadioProxyDeathRecipient;
+    boolean mIsCellularSupported;
+    RadioResponse mRadioResponse;
+    RadioIndication mRadioIndication;
+    volatile IRadio mRadioProxy = null;
+    final AtomicLong mRadioProxyCookie = new AtomicLong(0);
+    final RadioProxyDeathRecipient mRadioProxyDeathRecipient;
     final RilHandler mRilHandler;
-    private MockModem mMockModem;
 
     // Thread-safe HashMap to map from RIL_REQUEST_XXX constant to HalVersion.
     // This is for Radio HAL Fallback Compatibility feature. When a RIL request
     // is received, the HAL method from the mapping HalVersion here (if present),
     // instead of the latest HalVersion, will be invoked.
-    private final ConcurrentHashMap<Integer, HalVersion> mCompatOverrides =
+    private ConcurrentHashMap<Integer, HalVersion> mCompatOverrides =
             new ConcurrentHashMap<>();
 
     //***** Events
-    static final int EVENT_WAKE_LOCK_TIMEOUT = 2;
-    static final int EVENT_ACK_WAKE_LOCK_TIMEOUT = 4;
+    static final int EVENT_WAKE_LOCK_TIMEOUT    = 2;
+    static final int EVENT_ACK_WAKE_LOCK_TIMEOUT    = 4;
     static final int EVENT_BLOCKING_RESPONSE_TIMEOUT = 5;
-    static final int EVENT_RADIO_PROXY_DEAD = 6;
-    static final int EVENT_AIDL_PROXY_DEAD = 7;
+    static final int EVENT_RADIO_PROXY_DEAD     = 6;
 
     //***** Constants
 
     static final String[] HIDL_SERVICE_NAME = {"slot1", "slot2", "slot3"};
 
+    static final int IRADIO_GET_SERVICE_DELAY_MILLIS = 4 * 1000;
+
+    static final String EMPTY_ALPHA_LONG = "";
+    static final String EMPTY_ALPHA_SHORT = "";
+
     public static List<TelephonyHistogram> getTelephonyRILTimingHistograms() {
         List<TelephonyHistogram> list;
-        synchronized (sRilTimeHistograms) {
-            list = new ArrayList<>(sRilTimeHistograms.size());
-            for (int i = 0; i < sRilTimeHistograms.size(); i++) {
-                TelephonyHistogram entry = new TelephonyHistogram(sRilTimeHistograms.valueAt(i));
+        synchronized (mRilTimeHistograms) {
+            list = new ArrayList<>(mRilTimeHistograms.size());
+            for (int i = 0; i < mRilTimeHistograms.size(); i++) {
+                TelephonyHistogram entry = new TelephonyHistogram(mRilTimeHistograms.valueAt(i));
                 list.add(entry);
             }
         }
@@ -313,7 +348,7 @@
                                 for (int i = 0; i < count; i++) {
                                     rr = mRequestList.valueAt(i);
                                     Rlog.d(RILJ_LOG_TAG, i + ": [" + rr.mSerial + "] "
-                                            + RILUtils.requestToString(rr.mRequest));
+                                            + requestToString(rr.mRequest));
                                 }
                             }
                         }
@@ -329,17 +364,17 @@
                     break;
 
                 case EVENT_BLOCKING_RESPONSE_TIMEOUT:
-                    int serial = (int) msg.obj;
+                    int serial = msg.arg1;
                     rr = findAndRemoveRequestFromList(serial);
                     // If the request has already been processed, do nothing
-                    if (rr == null) {
+                    if(rr == null) {
                         break;
                     }
 
-                    // Build a response if expected
+                    //build a response if expected
                     if (rr.mResult != null) {
                         Object timeoutResponse = getResponseForTimedOutRILRequest(rr);
-                        AsyncResult.forMessage(rr.mResult, timeoutResponse, null);
+                        AsyncResult.forMessage( rr.mResult, timeoutResponse, null);
                         rr.mResult.sendToTarget();
                         mMetrics.writeOnRilTimeoutResponse(mPhoneId, rr.mSerial, rr.mRequest);
                     }
@@ -349,25 +384,10 @@
                     break;
 
                 case EVENT_RADIO_PROXY_DEAD:
-                    int service = msg.arg1;
-                    riljLog("handleMessage: EVENT_RADIO_PROXY_DEAD cookie = " + msg.obj
-                            + ", service = " + serviceToString(service) + ", service cookie = "
-                            + mServiceCookies.get(service));
-                    if ((long) msg.obj == mServiceCookies.get(service).get()) {
-                        mIsRadioProxyInitialized = false;
-                        resetProxyAndRequestList(service);
-                    }
-                    break;
-
-                case EVENT_AIDL_PROXY_DEAD:
-                    int aidlService = msg.arg1;
-                    AtomicLong obj = (AtomicLong) msg.obj;
-                    riljLog("handleMessage: EVENT_AIDL_PROXY_DEAD cookie = " + msg.obj
-                            + ", service = " + serviceToString(aidlService) + ", cookie = "
-                            + mServiceCookies.get(aidlService));
-                    if (obj.get() == mServiceCookies.get(aidlService).get()) {
-                        mIsRadioProxyInitialized = false;
-                        resetProxyAndRequestList(aidlService);
+                    riljLog("handleMessage: EVENT_RADIO_PROXY_DEAD cookie = " + msg.obj +
+                            " mRadioProxyCookie = " + mRadioProxyCookie.get());
+                    if ((long) msg.obj == mRadioProxyCookie.get()) {
+                        resetProxyAndRequestList();
                     }
                     break;
             }
@@ -412,155 +432,23 @@
         public void serviceDied(long cookie) {
             // Deal with service going away
             riljLog("serviceDied");
-            mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD, RADIO_SERVICE,
-                    0 /* ignored arg2 */, cookie));
+            mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_RADIO_PROXY_DEAD, cookie));
         }
     }
 
-    private final class BinderServiceDeathRecipient implements IBinder.DeathRecipient {
-        private IBinder mBinder;
-        private final int mService;
+    private synchronized void resetProxyAndRequestList() {
+        mRadioProxy = null;
 
-        BinderServiceDeathRecipient(int service) {
-            mService = service;
-        }
+        // increment the cookie so that death notification can be ignored
+        mRadioProxyCookie.incrementAndGet();
 
-        public void linkToDeath(IBinder service) throws RemoteException {
-            if (service != null) {
-                mBinder = service;
-                mBinder.linkToDeath(this, (int) mServiceCookies.get(mService).incrementAndGet());
-            }
-        }
-
-        public synchronized void unlinkToDeath() {
-            if (mBinder != null) {
-                mBinder.unlinkToDeath(this, 0);
-                mBinder = null;
-            }
-        }
-
-        @Override
-        public void binderDied() {
-            riljLog("Service " + serviceToString(mService) + " has died.");
-            mRilHandler.sendMessage(mRilHandler.obtainMessage(EVENT_AIDL_PROXY_DEAD, mService,
-                    0 /* ignored arg2 */, mServiceCookies.get(mService)));
-            unlinkToDeath();
-        }
-    }
-
-    private synchronized void resetProxyAndRequestList(int service) {
-        if (service == RADIO_SERVICE) {
-            mRadioProxy = null;
-        } else {
-            mServiceProxies.get(service).clear();
-        }
-
-        // Increment the cookie so that death notification can be ignored
-        mServiceCookies.get(service).incrementAndGet();
-
-        // TODO: If a service doesn't exist or is unimplemented, it shouldn't cause the radio to
-        //  become unavailable for all other services
         setRadioState(TelephonyManager.RADIO_POWER_UNAVAILABLE, true /* forceNotifyRegistrants */);
 
         RILRequest.resetSerial();
         // Clear request list on close
         clearRequestList(RADIO_NOT_AVAILABLE, false);
 
-        if (service == RADIO_SERVICE) {
-            getRadioProxy(null);
-        } else {
-            getRadioServiceProxy(service, null);
-        }
-    }
-
-    /**
-     * Request to enable/disable the mock modem service.
-     * This is invoked from shell commands during CTS testing only.
-     *
-     * @param serviceName the service name we want to bind to
-     */
-    public boolean setModemService(String serviceName) {
-        boolean serviceBound = true;
-
-        if (serviceName != null) {
-            riljLog("Binding to MockModemService");
-            mMockModem = null;
-
-            mMockModem = new MockModem(mContext, serviceName, mPhoneId);
-            if (mMockModem == null) {
-                riljLoge("MockModem create fail.");
-                return false;
-            }
-
-            // Disable HIDL service
-            if (mRadioProxy != null) {
-                riljLog("Disable HIDL service");
-                mDisabledRadioServices.get(RADIO_SERVICE).add(mPhoneId);
-            }
-
-            mMockModem.bindAllMockModemService();
-
-            for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) {
-                if (service == RADIO_SERVICE) continue;
-
-                int retryCount = 0;
-                IBinder binder;
-                do {
-                    binder = mMockModem.getServiceBinder(service);
-
-                    retryCount++;
-                    if (binder == null) {
-                        riljLog("Retry(" + retryCount + ") Service " + serviceToString(service));
-                        try {
-                            Thread.sleep(MockModem.BINDER_RETRY_MILLIS);
-                        } catch (InterruptedException e) {
-                        }
-                    }
-                } while ((binder == null) && (retryCount < MockModem.BINDER_MAX_RETRY));
-
-                if (binder == null) {
-                    riljLoge("Service " + serviceToString(service) + " bind fail");
-                    serviceBound = false;
-                    break;
-                }
-            }
-
-            if (serviceBound) {
-                mIsRadioProxyInitialized = false;
-                for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) {
-                    resetProxyAndRequestList(service);
-                }
-            }
-        }
-
-        if ((serviceName == null) || (!serviceBound)) {
-            if (serviceBound) riljLog("Unbinding to MockModemService");
-
-            if (mDisabledRadioServices.get(RADIO_SERVICE).contains(mPhoneId)) {
-                mDisabledRadioServices.get(RADIO_SERVICE).clear();
-            }
-
-            if (mMockModem != null) {
-                mRadioVersion = RADIO_HAL_VERSION_UNKNOWN;
-                mMockModem = null;
-                for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) {
-                    resetProxyAndRequestList(service);
-                }
-            }
-        }
-
-        return serviceBound;
-    }
-
-    /**
-     * Get current bound service in Radio Module
-     */
-    public String getModemService() {
-        if (mMockModem != null) {
-            return mMockModem.getServiceName();
-        } else {
-            return "default";
-        }
+        getRadioProxy(null);
     }
 
     /** Set a radio HAL fallback compatibility override. */
@@ -585,7 +473,6 @@
     /** Returns a {@link IRadio} instance or null if the service is not available. */
     @VisibleForTesting
     public synchronized IRadio getRadioProxy(Message result) {
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_2_0)) return null;
         if (!SubscriptionManager.isValidPhoneId(mPhoneId)) return null;
         if (!mIsCellularSupported) {
             if (RILJ_LOGV) riljLog("getRadioProxy: Not calling getService(): wifi-only");
@@ -602,7 +489,7 @@
         }
 
         try {
-            if (mDisabledRadioServices.get(RADIO_SERVICE).contains(mPhoneId)) {
+            if (mDisabledRadioServices.contains(mPhoneId)) {
                 riljLoge("getRadioProxy: mRadioProxy for " + HIDL_SERVICE_NAME[mPhoneId]
                         + " is disabled");
             } else {
@@ -668,16 +555,13 @@
                 }
 
                 if (mRadioProxy != null) {
-                    if (!mIsRadioProxyInitialized) {
-                        mIsRadioProxyInitialized = true;
-                        mRadioProxy.linkToDeath(mRadioProxyDeathRecipient,
-                                mServiceCookies.get(RADIO_SERVICE).incrementAndGet());
-                        mRadioProxy.setResponseFunctions(mRadioResponse, mRadioIndication);
-                    }
+                    mRadioProxy.linkToDeath(mRadioProxyDeathRecipient,
+                            mRadioProxyCookie.incrementAndGet());
+                    mRadioProxy.setResponseFunctions(mRadioResponse, mRadioIndication);
                 } else {
-                    mDisabledRadioServices.get(RADIO_SERVICE).add(mPhoneId);
-                    riljLoge("getRadioProxy: set mRadioProxy for "
-                            + HIDL_SERVICE_NAME[mPhoneId] + " as disabled");
+                    mDisabledRadioServices.add(mPhoneId);
+                    riljLoge("getRadioProxy: mRadioProxy for "
+                            + HIDL_SERVICE_NAME[mPhoneId] + " is disabled");
                 }
             }
         } catch (RemoteException e) {
@@ -698,318 +582,13 @@
         return mRadioProxy;
     }
 
-    /**
-     * Returns a {@link RadioDataProxy}, {@link RadioMessagingProxy}, {@link RadioModemProxy},
-     * {@link RadioNetworkProxy}, {@link RadioSimProxy}, {@link RadioVoiceProxy}, or an empty {@link RadioServiceProxy}
-     * if the service is not available.
-     */
-    @NonNull
-    public <T extends RadioServiceProxy> T getRadioServiceProxy(Class<T> serviceClass,
-            Message result) {
-        if (serviceClass == RadioDataProxy.class) {
-            return (T) getRadioServiceProxy(DATA_SERVICE, result);
-        }
-        if (serviceClass == RadioMessagingProxy.class) {
-            return (T) getRadioServiceProxy(MESSAGING_SERVICE, result);
-        }
-        if (serviceClass == RadioModemProxy.class) {
-            return (T) getRadioServiceProxy(MODEM_SERVICE, result);
-        }
-        if (serviceClass == RadioNetworkProxy.class) {
-            return (T) getRadioServiceProxy(NETWORK_SERVICE, result);
-        }
-        if (serviceClass == RadioSimProxy.class) {
-            return (T) getRadioServiceProxy(SIM_SERVICE, result);
-        }
-        if (serviceClass == RadioVoiceProxy.class) {
-            return (T) getRadioServiceProxy(VOICE_SERVICE, result);
-        }
-        riljLoge("getRadioServiceProxy: unrecognized " + serviceClass);
-        return null;
-    }
-
-    /**
-     * Returns a {@link RadioServiceProxy}, which is empty if the service is not available.
-     * For RADIO_SERVICE, use {@link #getRadioProxy} instead, as this will always return null.
-     */
-    @VisibleForTesting
-    @NonNull
-    public synchronized RadioServiceProxy getRadioServiceProxy(int service, Message result) {
-        if (!SubscriptionManager.isValidPhoneId(mPhoneId)) return mServiceProxies.get(service);
-        if (!mIsCellularSupported) {
-            if (RILJ_LOGV) riljLog("getRadioServiceProxy: Not calling getService(): wifi-only");
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
-                result.sendToTarget();
-            }
-            return mServiceProxies.get(service);
-        }
-
-        RadioServiceProxy serviceProxy = mServiceProxies.get(service);
-        if (!serviceProxy.isEmpty()) {
-            return serviceProxy;
-        }
-
-        try {
-            if (mDisabledRadioServices.get(service).contains(mPhoneId)) {
-                riljLoge("getRadioServiceProxy: " + serviceToString(service) + " for "
-                        + HIDL_SERVICE_NAME[mPhoneId] + " is disabled");
-            } else {
-                IBinder binder;
-                switch (service) {
-                    case DATA_SERVICE:
-                        if (mMockModem == null) {
-                            binder = ServiceManager.waitForDeclaredService(
-                                    android.hardware.radio.data.IRadioData.DESCRIPTOR + "/"
-                                            + HIDL_SERVICE_NAME[mPhoneId]);
-                        } else {
-                            binder = mMockModem.getServiceBinder(DATA_SERVICE);
-                        }
-                        if (binder != null) {
-                            mRadioVersion = RADIO_HAL_VERSION_2_0;
-                            ((RadioDataProxy) serviceProxy).setAidl(mRadioVersion,
-                                    android.hardware.radio.data.IRadioData.Stub.asInterface(
-                                            binder));
-                        }
-                        break;
-                    case MESSAGING_SERVICE:
-                        if (mMockModem == null) {
-                            binder = ServiceManager.waitForDeclaredService(
-                                    android.hardware.radio.messaging.IRadioMessaging.DESCRIPTOR
-                                            + "/" + HIDL_SERVICE_NAME[mPhoneId]);
-                        } else {
-                            binder = mMockModem.getServiceBinder(MESSAGING_SERVICE);
-                        }
-                        if (binder != null) {
-                            mRadioVersion = RADIO_HAL_VERSION_2_0;
-                            ((RadioMessagingProxy) serviceProxy).setAidl(mRadioVersion,
-                                    android.hardware.radio.messaging.IRadioMessaging.Stub
-                                            .asInterface(binder));
-                        }
-                        break;
-                    case MODEM_SERVICE:
-                        if (mMockModem == null) {
-                            binder = ServiceManager.waitForDeclaredService(
-                                    android.hardware.radio.modem.IRadioModem.DESCRIPTOR + "/"
-                                            + HIDL_SERVICE_NAME[mPhoneId]);
-                        } else {
-                            binder = mMockModem.getServiceBinder(MODEM_SERVICE);
-                        }
-                        if (binder != null) {
-                            mRadioVersion = RADIO_HAL_VERSION_2_0;
-                            ((RadioModemProxy) serviceProxy).setAidl(mRadioVersion,
-                                    android.hardware.radio.modem.IRadioModem.Stub
-                                            .asInterface(binder));
-                        }
-                        break;
-                    case NETWORK_SERVICE:
-                        if (mMockModem == null) {
-                            binder = ServiceManager.waitForDeclaredService(
-                                    android.hardware.radio.network.IRadioNetwork.DESCRIPTOR + "/"
-                                            + HIDL_SERVICE_NAME[mPhoneId]);
-                        } else {
-                            binder = mMockModem.getServiceBinder(NETWORK_SERVICE);
-                        }
-                        if (binder != null) {
-                            mRadioVersion = RADIO_HAL_VERSION_2_0;
-                            ((RadioNetworkProxy) serviceProxy).setAidl(mRadioVersion,
-                                    android.hardware.radio.network.IRadioNetwork.Stub
-                                            .asInterface(binder));
-                        }
-                        break;
-                    case SIM_SERVICE:
-                        if (mMockModem == null) {
-                            binder = ServiceManager.waitForDeclaredService(
-                                    android.hardware.radio.sim.IRadioSim.DESCRIPTOR + "/"
-                                            + HIDL_SERVICE_NAME[mPhoneId]);
-                        } else {
-                            binder = mMockModem.getServiceBinder(SIM_SERVICE);
-                        }
-                        if (binder != null) {
-                            mRadioVersion = RADIO_HAL_VERSION_2_0;
-                            ((RadioSimProxy) serviceProxy).setAidl(mRadioVersion,
-                                    android.hardware.radio.sim.IRadioSim.Stub
-                                            .asInterface(binder));
-                        }
-                        break;
-                    case VOICE_SERVICE:
-                        if (mMockModem == null) {
-                            binder = ServiceManager.waitForDeclaredService(
-                                    android.hardware.radio.voice.IRadioVoice.DESCRIPTOR + "/"
-                                            + HIDL_SERVICE_NAME[mPhoneId]);
-                        } else {
-                            binder = mMockModem.getServiceBinder(VOICE_SERVICE);
-                        }
-                        if (binder != null) {
-                            mRadioVersion = RADIO_HAL_VERSION_2_0;
-                            ((RadioVoiceProxy) serviceProxy).setAidl(mRadioVersion,
-                                    android.hardware.radio.voice.IRadioVoice.Stub
-                                            .asInterface(binder));
-                        }
-                        break;
-                }
-
-                if (serviceProxy.isEmpty() && mRadioVersion.less(RADIO_HAL_VERSION_2_0)) {
-                    try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_6;
-                        serviceProxy.setHidl(mRadioVersion,
-                                android.hardware.radio.V1_6.IRadio.getService(
-                                        HIDL_SERVICE_NAME[mPhoneId], true));
-                    } catch (NoSuchElementException e) {
-                    }
-                }
-
-                if (serviceProxy.isEmpty() && mRadioVersion.less(RADIO_HAL_VERSION_2_0)) {
-                    try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_5;
-                        serviceProxy.setHidl(mRadioVersion,
-                                android.hardware.radio.V1_5.IRadio.getService(
-                                        HIDL_SERVICE_NAME[mPhoneId], true));
-                    } catch (NoSuchElementException e) {
-                    }
-                }
-
-                if (serviceProxy.isEmpty() && mRadioVersion.less(RADIO_HAL_VERSION_2_0)) {
-                    try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_4;
-                        serviceProxy.setHidl(mRadioVersion,
-                                android.hardware.radio.V1_4.IRadio.getService(
-                                        HIDL_SERVICE_NAME[mPhoneId], true));
-                    } catch (NoSuchElementException e) {
-                    }
-                }
-
-                if (serviceProxy.isEmpty() && mRadioVersion.less(RADIO_HAL_VERSION_2_0)) {
-                    try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_3;
-                        serviceProxy.setHidl(mRadioVersion,
-                                android.hardware.radio.V1_3.IRadio.getService(
-                                        HIDL_SERVICE_NAME[mPhoneId], true));
-                    } catch (NoSuchElementException e) {
-                    }
-                }
-
-                if (serviceProxy.isEmpty() && mRadioVersion.less(RADIO_HAL_VERSION_2_0)) {
-                    try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_2;
-                        serviceProxy.setHidl(mRadioVersion,
-                                android.hardware.radio.V1_2.IRadio.getService(
-                                        HIDL_SERVICE_NAME[mPhoneId], true));
-                    } catch (NoSuchElementException e) {
-                    }
-                }
-
-                if (serviceProxy.isEmpty() && mRadioVersion.less(RADIO_HAL_VERSION_2_0)) {
-                    try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_1;
-                        serviceProxy.setHidl(mRadioVersion,
-                                android.hardware.radio.V1_1.IRadio.getService(
-                                        HIDL_SERVICE_NAME[mPhoneId], true));
-                    } catch (NoSuchElementException e) {
-                    }
-                }
-
-                if (serviceProxy.isEmpty() && mRadioVersion.less(RADIO_HAL_VERSION_2_0)) {
-                    try {
-                        mRadioVersion = RADIO_HAL_VERSION_1_0;
-                        serviceProxy.setHidl(mRadioVersion,
-                                android.hardware.radio.V1_0.IRadio.getService(
-                                        HIDL_SERVICE_NAME[mPhoneId], true));
-                    } catch (NoSuchElementException e) {
-                    }
-                }
-
-                if (!serviceProxy.isEmpty()) {
-                    if (serviceProxy.isAidl()) {
-                        switch (service) {
-                            case DATA_SERVICE:
-                                mDeathRecipients.get(service).linkToDeath(
-                                        ((RadioDataProxy) serviceProxy).getAidl().asBinder());
-                                ((RadioDataProxy) serviceProxy).getAidl().setResponseFunctions(
-                                        mDataResponse, mDataIndication);
-                                break;
-                            case MESSAGING_SERVICE:
-                                mDeathRecipients.get(service).linkToDeath(
-                                        ((RadioMessagingProxy) serviceProxy).getAidl().asBinder());
-                                ((RadioMessagingProxy) serviceProxy).getAidl().setResponseFunctions(
-                                        mMessagingResponse, mMessagingIndication);
-                                break;
-                            case MODEM_SERVICE:
-                                mDeathRecipients.get(service).linkToDeath(
-                                        ((RadioModemProxy) serviceProxy).getAidl().asBinder());
-                                ((RadioModemProxy) serviceProxy).getAidl().setResponseFunctions(
-                                        mModemResponse, mModemIndication);
-                                break;
-                            case NETWORK_SERVICE:
-                                mDeathRecipients.get(service).linkToDeath(
-                                        ((RadioNetworkProxy) serviceProxy).getAidl().asBinder());
-                                ((RadioNetworkProxy) serviceProxy).getAidl().setResponseFunctions(
-                                        mNetworkResponse, mNetworkIndication);
-                                break;
-                            case SIM_SERVICE:
-                                mDeathRecipients.get(service).linkToDeath(
-                                        ((RadioSimProxy) serviceProxy).getAidl().asBinder());
-                                ((RadioSimProxy) serviceProxy).getAidl().setResponseFunctions(
-                                        mSimResponse, mSimIndication);
-                                break;
-                            case VOICE_SERVICE:
-                                mDeathRecipients.get(service).linkToDeath(
-                                        ((RadioVoiceProxy) serviceProxy).getAidl().asBinder());
-                                ((RadioVoiceProxy) serviceProxy).getAidl().setResponseFunctions(
-                                        mVoiceResponse, mVoiceIndication);
-                                break;
-                        }
-                    } else {
-                        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
-                            throw new AssertionError("serviceProxy shouldn't be HIDL with HAL 2.0");
-                        }
-                        if (!mIsRadioProxyInitialized) {
-                            mIsRadioProxyInitialized = true;
-                            serviceProxy.getHidl().linkToDeath(mRadioProxyDeathRecipient,
-                                    mServiceCookies.get(service).incrementAndGet());
-                            serviceProxy.getHidl().setResponseFunctions(
-                                    mRadioResponse, mRadioIndication);
-                        }
-                    }
-                } else {
-                    mDisabledRadioServices.get(service).add(mPhoneId);
-                    riljLoge("getRadioServiceProxy: set " + serviceToString(service) + " for "
-                            + HIDL_SERVICE_NAME[mPhoneId] + " as disabled");
-                }
-            }
-        } catch (RemoteException e) {
-            serviceProxy.clear();
-            riljLoge("ServiceProxy getService/setResponseFunctions: " + e);
-        }
-
-        if (serviceProxy.isEmpty()) {
-            // getService() is a blocking call, so this should never happen
-            riljLoge("getRadioServiceProxy: serviceProxy == null");
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
-                result.sendToTarget();
-            }
-        }
-
-        return serviceProxy;
-    }
-
     @Override
     public synchronized void onSlotActiveStatusChange(boolean active) {
-        mIsRadioProxyInitialized = false;
-        for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) {
-            if (active) {
-                // Try to connect to RIL services and set response functions.
-                if (service == RADIO_SERVICE) {
-                    getRadioProxy(null);
-                } else {
-                    getRadioServiceProxy(service, null);
-                }
-            } else {
-                resetProxyAndRequestList(service);
-            }
+        if (active) {
+            // Try to connect to RIL services and set response functions.
+            getRadioProxy(null);
+        } else {
+            resetProxyAndRequestList();
         }
     }
 
@@ -1021,13 +600,8 @@
     }
 
     @UnsupportedAppUsage
-    public RIL(Context context, int allowedNetworkTypes, int cdmaSubscription, Integer instanceId) {
-        this(context, allowedNetworkTypes, cdmaSubscription, instanceId, null);
-    }
-
-    @VisibleForTesting
-    public RIL(Context context, int allowedNetworkTypes, int cdmaSubscription, Integer instanceId,
-            SparseArray<RadioServiceProxy> proxies) {
+    public RIL(Context context, int allowedNetworkTypes,
+            int cdmaSubscription, Integer instanceId) {
         super(context);
         if (RILJ_LOGD) {
             riljLog("RIL: init allowedNetworkTypes=" + allowedNetworkTypes
@@ -1042,14 +616,6 @@
         if (isRadioBugDetectionEnabled()) {
             mRadioBugDetector = new RadioBugDetector(context, mPhoneId);
         }
-        try {
-            if (isRadioVersion2_0()) mRadioVersion = RADIO_HAL_VERSION_2_0;
-        } catch (SecurityException ex) {
-            /* TODO(b/211920208): instead of the following workaround (guessing if we're in a test
-             * based on proxies being populated), mock ServiceManager to not throw
-             * SecurityException and return correct value based on what HAL we're testing. */
-            if (proxies == null) throw ex;
-        }
 
         TelephonyManager tm = (TelephonyManager) context.getSystemService(
                 Context.TELEPHONY_SERVICE);
@@ -1057,37 +623,8 @@
 
         mRadioResponse = new RadioResponse(this);
         mRadioIndication = new RadioIndication(this);
-        mDataResponse = new DataResponse(this);
-        mDataIndication = new DataIndication(this);
-        mMessagingResponse = new MessagingResponse(this);
-        mMessagingIndication = new MessagingIndication(this);
-        mModemResponse = new ModemResponse(this);
-        mModemIndication = new ModemIndication(this);
-        mNetworkResponse = new NetworkResponse(this);
-        mNetworkIndication = new NetworkIndication(this);
-        mSimResponse = new SimResponse(this);
-        mSimIndication = new SimIndication(this);
-        mVoiceResponse = new VoiceResponse(this);
-        mVoiceIndication = new VoiceIndication(this);
         mRilHandler = new RilHandler();
         mRadioProxyDeathRecipient = new RadioProxyDeathRecipient();
-        for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) {
-            if (service != RADIO_SERVICE) {
-                mDeathRecipients.put(service, new BinderServiceDeathRecipient(service));
-            }
-            mDisabledRadioServices.put(service, new HashSet<>());
-            mServiceCookies.put(service, new AtomicLong(0));
-        }
-        if (proxies == null) {
-            mServiceProxies.put(DATA_SERVICE, new RadioDataProxy());
-            mServiceProxies.put(MESSAGING_SERVICE, new RadioMessagingProxy());
-            mServiceProxies.put(MODEM_SERVICE, new RadioModemProxy());
-            mServiceProxies.put(NETWORK_SERVICE, new RadioNetworkProxy());
-            mServiceProxies.put(SIM_SERVICE, new RadioSimProxy());
-            mServiceProxies.put(VOICE_SERVICE, new RadioVoiceProxy());
-        } else {
-            mServiceProxies = proxies;
-        }
 
         PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, RILJ_WAKELOCK_TAG);
@@ -1104,50 +641,22 @@
         mActiveWakelockWorkSource = new WorkSource();
 
         TelephonyDevController tdc = TelephonyDevController.getInstance();
-        if (proxies == null) {
-            // TelephonyDevController#registerRIL will call getHardwareConfig.
-            // To prevent extra requests when running tests, only registerRIL when proxies is null
-            tdc.registerRIL(this);
-        }
+        tdc.registerRIL(this);
 
-        // Set radio callback; needed to set RadioIndication callback (should be done after
+        // set radio callback; needed to set RadioIndication callback (should be done after
         // wakelock stuff is initialized above as callbacks are received on separate binder threads)
-        for (int service = MIN_SERVICE_IDX; service <= MAX_SERVICE_IDX; service++) {
-            if (service == RADIO_SERVICE) {
-                getRadioProxy(null);
-            } else {
-                if (proxies == null) {
-                    // Prevent telephony tests from calling the service
-                    getRadioServiceProxy(service, null);
-                }
-            }
-        }
+        getRadioProxy(null);
 
         if (RILJ_LOGD) {
             riljLog("Radio HAL version: " + mRadioVersion);
         }
     }
 
-    private boolean isRadioVersion2_0() {
-        final String[] serviceNames = new String[] {
-            android.hardware.radio.data.IRadioData.DESCRIPTOR,
-            android.hardware.radio.messaging.IRadioMessaging.DESCRIPTOR,
-            android.hardware.radio.modem.IRadioModem.DESCRIPTOR,
-            android.hardware.radio.network.IRadioNetwork.DESCRIPTOR,
-            android.hardware.radio.sim.IRadioSim.DESCRIPTOR,
-            android.hardware.radio.voice.IRadioVoice.DESCRIPTOR,
-        };
-        for (String serviceName : serviceNames) {
-            if (ServiceManager.isDeclared(serviceName + '/' + HIDL_SERVICE_NAME[mPhoneId])) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     private boolean isRadioBugDetectionEnabled() {
-        return Settings.Global.getInt(mContext.getContentResolver(),
-                Settings.Global.ENABLE_RADIO_BUG_DETECTION, 1) != 0;
+        return Settings.Global.getInt(
+                mContext.getContentResolver(),
+                Settings.Global.ENABLE_RADIO_BUG_DETECTION,
+                1) != 0;
     }
 
     @Override
@@ -1156,7 +665,9 @@
 
         // Send the last NITZ time if we have it
         if (mLastNITZTimeInfo != null) {
-            mNITZTimeRegistrant.notifyRegistrant(new AsyncResult(null, mLastNITZTimeInfo, null));
+            mNITZTimeRegistrant
+                .notifyRegistrant(
+                    new AsyncResult (null, mLastNITZTimeInfo, null));
         }
     }
 
@@ -1181,35 +692,34 @@
         return rr;
     }
 
-    private void handleRadioProxyExceptionForRR(int service, String caller, Exception e) {
+    private void handleRadioProxyExceptionForRR(RILRequest rr, String caller, Exception e) {
         riljLoge(caller + ": " + e);
-        e.printStackTrace();
-        mIsRadioProxyInitialized = false;
-        resetProxyAndRequestList(service);
+        resetProxyAndRequestList();
+    }
+
+    private static String convertNullToEmptyString(String string) {
+        return string != null ? string : "";
     }
 
     @Override
     public void getIccCardStatus(Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SIM_STATUS, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                simProxy.getIccCardStatus(rr.mSerial);
+                radioProxy.getIccCardStatus(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getIccCardStatus", e);
+                handleRadioProxyExceptionForRR(rr, "getIccCardStatus", e);
             }
         }
     }
 
     @Override
     public void getIccSlotsStatus(Message result) {
-        if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "getIccSlotsStatus: REQUEST_NOT_SUPPORTED");
         if (result != null) {
             AsyncResult.forMessage(result, null,
                     CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
@@ -1219,9 +729,6 @@
 
     @Override
     public void setLogicalToPhysicalSlotMapping(int[] physicalSlots, Message result) {
-        if (RILJ_LOGD) {
-            Rlog.d(RILJ_LOG_TAG, "setLogicalToPhysicalSlotMapping: REQUEST_NOT_SUPPORTED");
-        }
         if (result != null) {
             AsyncResult.forMessage(result, null,
                     CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
@@ -1236,20 +743,22 @@
 
     @Override
     public void supplyIccPinForApp(String pin, String aid, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PIN, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PIN, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " aid = " + aid);
             }
 
             try {
-                simProxy.supplyIccPinForApp(rr.mSerial, RILUtils.convertNullToEmptyString(pin),
-                        RILUtils.convertNullToEmptyString(aid));
+                radioProxy.supplyIccPinForApp(rr.mSerial,
+                        convertNullToEmptyString(pin),
+                        convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "supplyIccPinForApp", e);
+                handleRadioProxyExceptionForRR(rr, "supplyIccPinForApp", e);
             }
         }
     }
@@ -1261,22 +770,25 @@
 
     @Override
     public void supplyIccPukForApp(String puk, String newPin, String aid, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PUK, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PUK, result,
+                    mRILDefaultWorkSource);
 
-            String pukStr = RILUtils.convertNullToEmptyString(puk);
+            String pukStr = convertNullToEmptyString(puk);
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " isPukEmpty = " + pukStr.isEmpty() + " aid = " + aid);
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                        + " isPukEmpty = " + pukStr.isEmpty()
+                        + " aid = " + aid);
             }
 
             try {
-                simProxy.supplyIccPukForApp(rr.mSerial, pukStr,
-                        RILUtils.convertNullToEmptyString(newPin),
-                        RILUtils.convertNullToEmptyString(aid));
+                radioProxy.supplyIccPukForApp(rr.mSerial,
+                        pukStr,
+                        convertNullToEmptyString(newPin),
+                        convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "supplyIccPukForApp", e);
+                handleRadioProxyExceptionForRR(rr, "supplyIccPukForApp", e);
             }
         }
     }
@@ -1288,21 +800,22 @@
 
     @Override
     public void supplyIccPin2ForApp(String pin, String aid, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PIN2, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " aid = " + aid);
             }
 
             try {
-                simProxy.supplyIccPin2ForApp(rr.mSerial, RILUtils.convertNullToEmptyString(pin),
-                        RILUtils.convertNullToEmptyString(aid));
+                radioProxy.supplyIccPin2ForApp(rr.mSerial,
+                        convertNullToEmptyString(pin),
+                        convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "supplyIccPin2ForApp", e);
+                handleRadioProxyExceptionForRR(rr, "supplyIccPin2ForApp", e);
             }
         }
     }
@@ -1314,22 +827,23 @@
 
     @Override
     public void supplyIccPuk2ForApp(String puk, String newPin2, String aid, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_PUK2, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " aid = " + aid);
             }
 
             try {
-                simProxy.supplyIccPuk2ForApp(rr.mSerial, RILUtils.convertNullToEmptyString(puk),
-                        RILUtils.convertNullToEmptyString(newPin2),
-                        RILUtils.convertNullToEmptyString(aid));
+                radioProxy.supplyIccPuk2ForApp(rr.mSerial,
+                        convertNullToEmptyString(puk),
+                        convertNullToEmptyString(newPin2),
+                        convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "supplyIccPuk2ForApp", e);
+                handleRadioProxyExceptionForRR(rr, "supplyIccPuk2ForApp", e);
             }
         }
     }
@@ -1341,23 +855,23 @@
 
     @Override
     public void changeIccPinForApp(String oldPin, String newPin, String aid, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CHANGE_SIM_PIN, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " oldPin = " + oldPin + " newPin = " + newPin + " aid = " + aid);
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " oldPin = "
+                        + oldPin + " newPin = " + newPin + " aid = " + aid);
             }
 
             try {
-                simProxy.changeIccPinForApp(rr.mSerial,
-                        RILUtils.convertNullToEmptyString(oldPin),
-                        RILUtils.convertNullToEmptyString(newPin),
-                        RILUtils.convertNullToEmptyString(aid));
+                radioProxy.changeIccPinForApp(rr.mSerial,
+                        convertNullToEmptyString(oldPin),
+                        convertNullToEmptyString(newPin),
+                        convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "changeIccPinForApp", e);
+                handleRadioProxyExceptionForRR(rr, "changeIccPinForApp", e);
             }
         }
     }
@@ -1369,77 +883,72 @@
 
     @Override
     public void changeIccPin2ForApp(String oldPin2, String newPin2, String aid, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CHANGE_SIM_PIN2, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " oldPin = " + oldPin2 + " newPin = " + newPin2 + " aid = " + aid);
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " oldPin = "
+                        + oldPin2 + " newPin = " + newPin2 + " aid = " + aid);
             }
 
             try {
-                simProxy.changeIccPin2ForApp(rr.mSerial,
-                        RILUtils.convertNullToEmptyString(oldPin2),
-                        RILUtils.convertNullToEmptyString(newPin2),
-                        RILUtils.convertNullToEmptyString(aid));
+                radioProxy.changeIccPin2ForApp(rr.mSerial,
+                        convertNullToEmptyString(oldPin2),
+                        convertNullToEmptyString(newPin2),
+                        convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "changeIccPin2ForApp", e);
+                handleRadioProxyExceptionForRR(rr, "changeIccPin2ForApp", e);
             }
         }
     }
 
     @Override
     public void supplyNetworkDepersonalization(String netpin, Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " netpin = " + netpin);
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " netpin = "
+                        + netpin);
             }
 
             try {
-                networkProxy.supplyNetworkDepersonalization(rr.mSerial,
-                        RILUtils.convertNullToEmptyString(netpin));
+                radioProxy.supplyNetworkDepersonalization(rr.mSerial,
+                        convertNullToEmptyString(netpin));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(
-                        NETWORK_SERVICE, "supplyNetworkDepersonalization", e);
+                handleRadioProxyExceptionForRR(rr, "supplyNetworkDepersonalization", e);
             }
         }
     }
 
     @Override
-    public void supplySimDepersonalization(PersoSubState persoType, String controlKey,
-            Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (simProxy.isEmpty()) return;
+    public void supplySimDepersonalization(PersoSubState persoType,
+            String controlKey, Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        // IRadio V1.5
         if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION, result,
-                    mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " controlKey = " + controlKey + " persoType" + persoType);
-            }
-
-            try {
-                simProxy.supplySimDepersonalization(rr.mSerial, persoType,
-                        RILUtils.convertNullToEmptyString(controlKey));
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "supplySimDepersonalization", e);
+            android.hardware.radio.V1_5.IRadio radioProxy15 =
+                (android.hardware.radio.V1_5.IRadio) radioProxy;
+            if (radioProxy15 != null) {
+                RILRequest rr = obtainRequest(RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION, result,
+                        mRILDefaultWorkSource);
+                if (RILJ_LOGD) {
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " controlKey = "
+                        + controlKey + " persoType" + persoType);
+                }
+                try {
+                    radioProxy15.supplySimDepersonalization(rr.mSerial,
+                            convertPersoTypeToHalPersoType(persoType),
+                            convertNullToEmptyString(controlKey));
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "supplySimDepersonalization", e);
+                }
             }
         } else {
-            if (PersoSubState.PERSOSUBSTATE_SIM_NETWORK == persoType) {
-                supplyNetworkDepersonalization(controlKey, result);
-                return;
-            }
-            if (RILJ_LOGD) {
-                Rlog.d(RILJ_LOG_TAG, "supplySimDepersonalization: REQUEST_NOT_SUPPORTED");
-            }
             if (result != null) {
                 AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
@@ -1448,190 +957,377 @@
         }
     }
 
+    private static int convertPersoTypeToHalPersoType(PersoSubState persoType) {
+
+        switch(persoType) {
+
+            case PERSOSUBSTATE_IN_PROGRESS:
+                return PersoSubstate.IN_PROGRESS;
+            case  PERSOSUBSTATE_READY:
+                return PersoSubstate.READY;
+            case PERSOSUBSTATE_SIM_NETWORK:
+                return PersoSubstate.SIM_NETWORK;
+            case PERSOSUBSTATE_SIM_NETWORK_SUBSET:
+                return PersoSubstate.SIM_NETWORK_SUBSET;
+            case PERSOSUBSTATE_SIM_CORPORATE:
+                return PersoSubstate.SIM_CORPORATE;
+            case PERSOSUBSTATE_SIM_SERVICE_PROVIDER:
+                return PersoSubstate.SIM_SERVICE_PROVIDER;
+            case PERSOSUBSTATE_SIM_SIM:
+                return PersoSubstate.SIM_SIM;
+            case PERSOSUBSTATE_SIM_NETWORK_PUK:
+                return PersoSubstate.SIM_NETWORK_PUK;
+            case PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:
+                return PersoSubstate.SIM_NETWORK_SUBSET_PUK;
+            case PERSOSUBSTATE_SIM_CORPORATE_PUK:
+                return PersoSubstate.SIM_CORPORATE_PUK;
+            case PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:
+                return PersoSubstate.SIM_SERVICE_PROVIDER_PUK;
+            case PERSOSUBSTATE_SIM_SIM_PUK:
+                return PersoSubstate.SIM_SIM_PUK;
+            case PERSOSUBSTATE_RUIM_NETWORK1:
+                return PersoSubstate.RUIM_NETWORK1;
+            case PERSOSUBSTATE_RUIM_NETWORK2:
+                return PersoSubstate.RUIM_NETWORK2;
+            case PERSOSUBSTATE_RUIM_HRPD:
+                return PersoSubstate.RUIM_HRPD;
+            case PERSOSUBSTATE_RUIM_CORPORATE:
+                return PersoSubstate.RUIM_CORPORATE;
+            case PERSOSUBSTATE_RUIM_SERVICE_PROVIDER:
+                return PersoSubstate.RUIM_SERVICE_PROVIDER;
+            case PERSOSUBSTATE_RUIM_RUIM:
+                return PersoSubstate.RUIM_RUIM;
+            case PERSOSUBSTATE_RUIM_NETWORK1_PUK:
+                return PersoSubstate.RUIM_NETWORK1_PUK;
+            case PERSOSUBSTATE_RUIM_NETWORK2_PUK:
+                return PersoSubstate.RUIM_NETWORK2_PUK;
+            case PERSOSUBSTATE_RUIM_HRPD_PUK:
+                return PersoSubstate.RUIM_HRPD_PUK;
+            case PERSOSUBSTATE_RUIM_CORPORATE_PUK:
+                return PersoSubstate.RUIM_CORPORATE_PUK;
+            case PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK:
+                return PersoSubstate.RUIM_SERVICE_PROVIDER_PUK;
+            case PERSOSUBSTATE_RUIM_RUIM_PUK:
+                return PersoSubstate.RUIM_RUIM_PUK;
+            case PERSOSUBSTATE_SIM_SPN:
+                return PersoSubstate.SIM_SPN;
+            case PERSOSUBSTATE_SIM_SPN_PUK:
+                return PersoSubstate.SIM_SPN_PUK;
+            case PERSOSUBSTATE_SIM_SP_EHPLMN:
+                return PersoSubstate.SIM_SP_EHPLMN;
+            case PERSOSUBSTATE_SIM_SP_EHPLMN_PUK:
+                return PersoSubstate.SIM_SP_EHPLMN_PUK;
+            case PERSOSUBSTATE_SIM_ICCID:
+                return PersoSubstate.SIM_ICCID;
+            case PERSOSUBSTATE_SIM_ICCID_PUK:
+                return PersoSubstate.SIM_ICCID_PUK;
+            case PERSOSUBSTATE_SIM_IMPI:
+                return PersoSubstate.SIM_IMPI;
+            case PERSOSUBSTATE_SIM_IMPI_PUK:
+                return PersoSubstate.SIM_IMPI_PUK;
+            case PERSOSUBSTATE_SIM_NS_SP:
+                return PersoSubstate.SIM_NS_SP;
+            case PERSOSUBSTATE_SIM_NS_SP_PUK:
+                return PersoSubstate.SIM_NS_SP_PUK;
+            default:
+                return PersoSubstate.UNKNOWN;
+        }
+    }
+
     @Override
     public void getCurrentCalls(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_CURRENT_CALLS, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
             try {
-                voiceProxy.getCurrentCalls(rr.mSerial);
+                if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                    // IRadio V1.6
+                    android.hardware.radio.V1_6.IRadio radioProxy16 =
+                            (android.hardware.radio.V1_6.IRadio) radioProxy;
+                    radioProxy16.getCurrentCalls_1_6(rr.mSerial);
+                } else {
+                    radioProxy.getCurrentCalls(rr.mSerial);
+                }
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getCurrentCalls", e);
+                handleRadioProxyExceptionForRR(rr, "getCurrentCalls", e);
             }
         }
     }
 
     @Override
     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-            boolean hasKnownUserIntentEmergency, int clirMode, Message result) {
+                     boolean hasKnownUserIntentEmergency, int clirMode, Message result) {
         dial(address, isEmergencyCall, emergencyNumberInfo, hasKnownUserIntentEmergency,
                 clirMode, null, result);
     }
 
     @Override
     public void enableModem(boolean enable, Message result) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (modemProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_3)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_MODEM, result, mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " enable = " + enable);
-            }
-
-            try {
-                modemProxy.enableModem(rr.mSerial, enable);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "enableModem", e);
-            }
-        } else {
+        IRadio radioProxy = getRadioProxy(result);
+        if (mRadioVersion.less(RADIO_HAL_VERSION_1_3)) {
             if (RILJ_LOGV) riljLog("enableModem: not supported.");
             if (result != null) {
                 AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
                 result.sendToTarget();
             }
+            return;
+        }
+
+        android.hardware.radio.V1_3.IRadio radioProxy13 =
+                (android.hardware.radio.V1_3.IRadio) radioProxy;
+        if (radioProxy13 != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_MODEM, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " enable = "
+                        + enable);
+            }
+
+            try {
+                radioProxy13.enableModem(rr.mSerial, enable);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "enableModem", e);
+            }
         }
     }
 
     @Override
     public void setSystemSelectionChannels(@NonNull List<RadioAccessSpecifier> specifiers,
-            Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_3)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS, result,
-                    mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " setSystemSelectionChannels_1.3= " + specifiers);
-            }
-
-            try {
-                networkProxy.setSystemSelectionChannels(rr.mSerial, specifiers);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setSystemSelectionChannels", e);
-            }
-        } else {
+            Message onComplete) {
+        IRadio radioProxy = getRadioProxy(onComplete);
+        if (mRadioVersion.less(RADIO_HAL_VERSION_1_3)) {
             if (RILJ_LOGV) riljLog("setSystemSelectionChannels: not supported.");
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
+            if (onComplete != null) {
+                AsyncResult.forMessage(onComplete, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
+                onComplete.sendToTarget();
+            }
+            return;
+        }
+
+        RILRequest rr = obtainRequest(RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS, onComplete,
+                mRILDefaultWorkSource);
+
+        if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
+            android.hardware.radio.V1_3.IRadio radioProxy13 =
+                    (android.hardware.radio.V1_3.IRadio) radioProxy;
+            if (radioProxy13 != null) {
+                if (RILJ_LOGD) {
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                            + " setSystemSelectionChannels_1.3= "
+                            + specifiers);
+                }
+
+                ArrayList<android.hardware.radio.V1_1.RadioAccessSpecifier> halSpecifiers =
+                        specifiers.stream()
+                                .map(this::convertRadioAccessSpecifierToRadioHAL)
+                                .collect(Collectors.toCollection(ArrayList::new));
+
+                try {
+                    radioProxy13.setSystemSelectionChannels(rr.mSerial,
+                            !halSpecifiers.isEmpty(),
+                            halSpecifiers);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setSystemSelectionChannels", e);
+                }
+            }
+        }
+
+        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+            android.hardware.radio.V1_5.IRadio radioProxy15 =
+                    (android.hardware.radio.V1_5.IRadio) radioProxy;
+
+            if (radioProxy15 != null) {
+                if (RILJ_LOGD) {
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                            + " setSystemSelectionChannels_1.5= "
+                            + specifiers);
+                }
+
+                ArrayList<android.hardware.radio.V1_5.RadioAccessSpecifier> halSpecifiers =
+                        specifiers.stream()
+                                .map(this::convertRadioAccessSpecifierToRadioHAL_1_5)
+                                .collect(Collectors.toCollection(ArrayList::new));
+
+                try {
+                    radioProxy15.setSystemSelectionChannels_1_5(rr.mSerial,
+                            !halSpecifiers.isEmpty(),
+                            halSpecifiers);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setSystemSelectionChannels", e);
+                }
             }
         }
     }
 
     @Override
-    public void getSystemSelectionChannels(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_GET_SYSTEM_SELECTION_CHANNELS, result,
-                    mRILDefaultWorkSource);
+    public void getSystemSelectionChannels(Message onComplete) {
+        IRadio radioProxy = getRadioProxy(onComplete);
+        if (mRadioVersion.less(RADIO_HAL_VERSION_1_6)) {
+            if (RILJ_LOGV) riljLog("getSystemSelectionChannels: not supported.");
+            if (onComplete != null) {
+                AsyncResult.forMessage(onComplete, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                onComplete.sendToTarget();
+            }
+            return;
+        }
 
+        RILRequest rr = obtainRequest(RIL_REQUEST_GET_SYSTEM_SELECTION_CHANNELS, onComplete,
+                mRILDefaultWorkSource);
+
+        android.hardware.radio.V1_6.IRadio radioProxy16 =
+                (android.hardware.radio.V1_6.IRadio) radioProxy;
+
+        if (radioProxy16 != null) {
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " getSystemSelectionChannels");
             }
 
             try {
-                networkProxy.getSystemSelectionChannels(rr.mSerial);
+                radioProxy16.getSystemSelectionChannels(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getSystemSelectionChannels", e);
-            }
-        } else {
-            if (RILJ_LOGV) riljLog("getSystemSelectionChannels: not supported.");
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
+                handleRadioProxyExceptionForRR(rr, "getSystemSelectionChannels", e);
             }
         }
     }
 
     @Override
     public void getModemStatus(Message result) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (modemProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_3)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_GET_MODEM_STATUS, result,
-                    mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
-
-            try {
-                modemProxy.getModemStackStatus(rr.mSerial);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getModemStatus", e);
-            }
-        } else {
+        IRadio radioProxy = getRadioProxy(result);
+        if (mRadioVersion.less(RADIO_HAL_VERSION_1_3)) {
             if (RILJ_LOGV) riljLog("getModemStatus: not supported.");
             if (result != null) {
                 AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
                 result.sendToTarget();
             }
+            return;
+        }
+
+        android.hardware.radio.V1_3.IRadio radioProxy13 =
+                (android.hardware.radio.V1_3.IRadio) radioProxy;
+        if (radioProxy13 != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_GET_MODEM_STATUS, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+            }
+
+            try {
+                radioProxy13.getModemStackStatus(rr.mSerial);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "getModemStatus", e);
+            }
         }
     }
 
     @Override
     public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
-            boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo, Message result) {
+                     boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo,
+                     Message result) {
         if (isEmergencyCall && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)
                 && emergencyNumberInfo != null) {
             emergencyDial(address, emergencyNumberInfo, hasKnownUserIntentEmergency, clirMode,
                     uusInfo, result);
             return;
         }
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_DIAL, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_DIAL, result,
+                    mRILDefaultWorkSource);
+
+            Dial dialInfo = new Dial();
+            dialInfo.address = convertNullToEmptyString(address);
+            dialInfo.clir = clirMode;
+            if (uusInfo != null) {
+                UusInfo info = new UusInfo();
+                info.uusType = uusInfo.getType();
+                info.uusDcs = uusInfo.getDcs();
+                info.uusData = new String(uusInfo.getUserData());
+                dialInfo.uusInfo.add(info);
+            }
 
             if (RILJ_LOGD) {
                 // Do not log function arg for privacy
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
             try {
-                voiceProxy.dial(rr.mSerial, address, clirMode, uusInfo);
+                radioProxy.dial(rr.mSerial, dialInfo);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "dial", e);
+                handleRadioProxyExceptionForRR(rr, "dial", e);
             }
         }
     }
 
     private void emergencyDial(String address, EmergencyNumber emergencyNumberInfo,
             boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (voiceProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_EMERGENCY_DIAL, result,
                     mRILDefaultWorkSource);
+            Dial dialInfo = new Dial();
+            dialInfo.address = convertNullToEmptyString(address);
+            dialInfo.clir = clirMode;
+            if (uusInfo != null) {
+                UusInfo info = new UusInfo();
+                info.uusType = uusInfo.getType();
+                info.uusDcs = uusInfo.getDcs();
+                info.uusData = new String(uusInfo.getUserData());
+                dialInfo.uusInfo.add(info);
+            }
 
             if (RILJ_LOGD) {
                 // Do not log function arg for privacy
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
-            try {
-                voiceProxy.emergencyDial(rr.mSerial, RILUtils.convertNullToEmptyString(address),
-                        emergencyNumberInfo, hasKnownUserIntentEmergency, clirMode, uusInfo);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "emergencyDial", e);
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                android.hardware.radio.V1_6.IRadio radioProxy16 =
+                        (android.hardware.radio.V1_6.IRadio) radioProxy;
+                try {
+                    radioProxy16.emergencyDial_1_6(rr.mSerial, dialInfo,
+                        emergencyNumberInfo.getEmergencyServiceCategoryBitmaskInternalDial(),
+                        emergencyNumberInfo.getEmergencyUrns() != null
+                                ? new ArrayList(emergencyNumberInfo.getEmergencyUrns())
+                                        : new ArrayList<>(),
+                        emergencyNumberInfo.getEmergencyCallRouting(),
+                        hasKnownUserIntentEmergency,
+                        emergencyNumberInfo.getEmergencyNumberSourceBitmask()
+                                == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "emergencyDial_1_6", e);
+                }
+            } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
+                android.hardware.radio.V1_4.IRadio radioProxy14 =
+                        (android.hardware.radio.V1_4.IRadio) radioProxy;
+                try {
+                    radioProxy14.emergencyDial(rr.mSerial, dialInfo,
+                            emergencyNumberInfo.getEmergencyServiceCategoryBitmaskInternalDial(),
+                            emergencyNumberInfo.getEmergencyUrns() != null
+                                    ? new ArrayList(emergencyNumberInfo.getEmergencyUrns())
+                                            : new ArrayList<>(),
+                            emergencyNumberInfo.getEmergencyCallRouting(),
+                            hasKnownUserIntentEmergency,
+                            emergencyNumberInfo.getEmergencyNumberSourceBitmask()
+                                    == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "emergencyDial", e);
+                }
+            } else {
+                riljLoge("emergencyDial is not supported with 1.4 below IRadio");
             }
-        } else {
-            riljLoge("emergencyDial is not supported with 1.4 below IRadio");
         }
     }
 
@@ -1642,37 +1338,39 @@
 
     @Override
     public void getIMSIForApp(String aid, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_GET_IMSI, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_GET_IMSI, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + ">  " + RILUtils.requestToString(rr.mRequest)
-                        + " aid = " + aid);
+                riljLog(rr.serialString()
+                        + ">  " + requestToString(rr.mRequest) + " aid = " + aid);
             }
             try {
-                simProxy.getImsiForApp(rr.mSerial, RILUtils.convertNullToEmptyString(aid));
+                radioProxy.getImsiForApp(rr.mSerial, convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getImsiForApp", e);
+                handleRadioProxyExceptionForRR(rr, "getIMSIForApp", e);
             }
         }
     }
 
     @Override
     public void hangupConnection(int gsmIndex, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_HANGUP, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_HANGUP, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " gsmIndex = " + gsmIndex);
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " gsmIndex = "
+                        + gsmIndex);
             }
 
             try {
-                voiceProxy.hangup(rr.mSerial, gsmIndex);
+                radioProxy.hangup(rr.mSerial, gsmIndex);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "hangup", e);
+                handleRadioProxyExceptionForRR(rr, "hangupConnection", e);
             }
         }
     }
@@ -1680,19 +1378,17 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     @Override
     public void hangupWaitingOrBackground(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.hangupWaitingOrBackground(rr.mSerial);
+                radioProxy.hangupWaitingOrBackground(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "hangupWaitingOrBackground", e);
+                handleRadioProxyExceptionForRR(rr, "hangupWaitingOrBackground", e);
             }
         }
     }
@@ -1700,179 +1396,225 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     @Override
     public void hangupForegroundResumeBackground(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.hangupForegroundResumeBackground(rr.mSerial);
+                radioProxy.hangupForegroundResumeBackground(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(
-                        VOICE_SERVICE, "hangupForegroundResumeBackground", e);
+                handleRadioProxyExceptionForRR(rr, "hangupForegroundResumeBackground", e);
             }
         }
     }
 
     @Override
     public void switchWaitingOrHoldingAndActive(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.switchWaitingOrHoldingAndActive(rr.mSerial);
+                radioProxy.switchWaitingOrHoldingAndActive(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "switchWaitingOrHoldingAndActive", e);
+                handleRadioProxyExceptionForRR(rr, "switchWaitingOrHoldingAndActive", e);
             }
         }
     }
 
     @Override
     public void conference(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_CONFERENCE, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_CONFERENCE, result,
+                    mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.conference(rr.mSerial);
+                radioProxy.conference(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "conference", e);
+                handleRadioProxyExceptionForRR(rr, "conference", e);
             }
         }
     }
 
     @Override
     public void rejectCall(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_UDUB, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_UDUB, result,
+                    mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.rejectCall(rr.mSerial);
+                radioProxy.rejectCall(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "rejectCall", e);
+                handleRadioProxyExceptionForRR(rr, "rejectCall", e);
             }
         }
     }
 
     @Override
     public void getLastCallFailCause(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_LAST_CALL_FAIL_CAUSE, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.getLastCallFailCause(rr.mSerial);
+                radioProxy.getLastCallFailCause(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getLastCallFailCause", e);
+                handleRadioProxyExceptionForRR(rr, "getLastCallFailCause", e);
             }
         }
     }
 
     @Override
     public void getSignalStrength(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SIGNAL_STRENGTH, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
-            try {
-                networkProxy.getSignalStrength(rr.mSerial);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getSignalStrength", e);
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                android.hardware.radio.V1_6.IRadio radioProxy16 =
+                        (android.hardware.radio.V1_6.IRadio) radioProxy;
+                try {
+                    radioProxy16.getSignalStrength_1_6(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "getSignalStrength_1_6", e);
+                }
+            } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
+                android.hardware.radio.V1_4.IRadio radioProxy14 =
+                        (android.hardware.radio.V1_4.IRadio) radioProxy;
+                try {
+                    radioProxy14.getSignalStrength_1_4(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "getSignalStrength_1_4", e);
+                }
+            } else {
+                try {
+                    radioProxy.getSignalStrength(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "getSignalStrength", e);
+                }
             }
         }
     }
 
     @Override
     public void getVoiceRegistrationState(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_VOICE_REGISTRATION_STATE, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             HalVersion overrideHalVersion = getCompatVersion(RIL_REQUEST_VOICE_REGISTRATION_STATE);
             if (RILJ_LOGD) {
                 riljLog("getVoiceRegistrationState: overrideHalVersion=" + overrideHalVersion);
             }
 
-            try {
-                networkProxy.getVoiceRegistrationState(rr.mSerial, overrideHalVersion);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getVoiceRegistrationState", e);
+            if ((overrideHalVersion == null
+                        || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6))
+                    && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                final android.hardware.radio.V1_6.IRadio radioProxy16 =
+                        (android.hardware.radio.V1_6.IRadio) radioProxy;
+                try {
+                    radioProxy16.getVoiceRegistrationState_1_6(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "getVoiceRegistrationState_1_6", e);
+                }
+            } else if ((overrideHalVersion == null
+                        || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5))
+                    && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+                final android.hardware.radio.V1_5.IRadio radioProxy15 =
+                        (android.hardware.radio.V1_5.IRadio) radioProxy;
+                try {
+                    radioProxy15.getVoiceRegistrationState_1_5(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "getVoiceRegistrationState_1_5", e);
+                }
+            } else {
+                try {
+                    radioProxy.getVoiceRegistrationState(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "getVoiceRegistrationState", e);
+                }
             }
         }
     }
 
     @Override
     public void getDataRegistrationState(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_DATA_REGISTRATION_STATE, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             HalVersion overrideHalVersion = getCompatVersion(RIL_REQUEST_DATA_REGISTRATION_STATE);
             if (RILJ_LOGD) {
                 riljLog("getDataRegistrationState: overrideHalVersion=" + overrideHalVersion);
             }
 
-            try {
-                networkProxy.getDataRegistrationState(rr.mSerial, overrideHalVersion);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getDataRegistrationState", e);
+            if ((overrideHalVersion == null
+                        || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6))
+                    && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                final android.hardware.radio.V1_6.IRadio radioProxy16 =
+                        (android.hardware.radio.V1_6.IRadio) radioProxy;
+                try {
+                    radioProxy16.getDataRegistrationState_1_6(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "getDataRegistrationState_1_6", e);
+                }
+            } else if ((overrideHalVersion == null
+                        || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5))
+                    && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+                final android.hardware.radio.V1_5.IRadio radioProxy15 =
+                        (android.hardware.radio.V1_5.IRadio) radioProxy;
+                try {
+                    radioProxy15.getDataRegistrationState_1_5(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "getDataRegistrationState_1_5", e);
+                }
+            } else {
+                try {
+                    radioProxy.getDataRegistrationState(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "getDataRegistrationState", e);
+                }
             }
         }
     }
 
     @Override
     public void getOperator(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_OPERATOR, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_OPERATOR, result,
+                    mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                networkProxy.getOperator(rr.mSerial);
+                radioProxy.getOperator(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getOperator", e);
+                handleRadioProxyExceptionForRR(rr, "getOperator", e);
             }
         }
     }
@@ -1881,62 +1623,103 @@
     @Override
     public void setRadioPower(boolean on, boolean forEmergencyCall,
             boolean preferredForEmergencyCall, Message result) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (!modemProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_RADIO_POWER, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_RADIO_POWER, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " on = " + on + " forEmergencyCall= " + forEmergencyCall
                         + " preferredForEmergencyCall="  + preferredForEmergencyCall);
             }
 
-            try {
-                modemProxy.setRadioPower(rr.mSerial, on, forEmergencyCall,
-                        preferredForEmergencyCall);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "setRadioPower", e);
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                android.hardware.radio.V1_6.IRadio radioProxy16 =
+                        (android.hardware.radio.V1_6.IRadio) radioProxy;
+                try {
+                    radioProxy16.setRadioPower_1_6(rr.mSerial, on, forEmergencyCall,
+                            preferredForEmergencyCall);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setRadioPower_1_6", e);
+                }
+            } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+                android.hardware.radio.V1_5.IRadio radioProxy15 =
+                        (android.hardware.radio.V1_5.IRadio) radioProxy;
+                try {
+                    radioProxy15.setRadioPower_1_5(rr.mSerial, on, forEmergencyCall,
+                            preferredForEmergencyCall);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setRadioPower_1_5", e);
+                }
+            } else {
+                try {
+                    radioProxy.setRadioPower(rr.mSerial, on);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setRadioPower", e);
+                }
             }
         }
     }
 
     @Override
     public void sendDtmf(char c, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_DTMF, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_DTMF, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
                 // Do not log function arg for privacy
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
             try {
-                voiceProxy.sendDtmf(rr.mSerial, c + "");
+                radioProxy.sendDtmf(rr.mSerial, c + "");
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "sendDtmf", e);
+                handleRadioProxyExceptionForRR(rr, "sendDtmf", e);
             }
         }
     }
 
+    private GsmSmsMessage constructGsmSendSmsRilRequest(String smscPdu, String pdu) {
+        GsmSmsMessage msg = new GsmSmsMessage();
+        msg.smscPdu = smscPdu == null ? "" : smscPdu;
+        msg.pdu = pdu == null ? "" : pdu;
+        return msg;
+    }
+
     @Override
     public void sendSMS(String smscPdu, String pdu, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SEND_SMS, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SEND_SMS, result,
+                    mRILDefaultWorkSource);
 
             // Do not log function args for privacy
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
-            try {
-                messagingProxy.sendSms(rr.mSerial, smscPdu, pdu);
-                mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
-                        SmsSession.Event.Format.SMS_FORMAT_3GPP, getOutgoingSmsMessageId(result));
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "sendSMS", e);
+            GsmSmsMessage msg = constructGsmSendSmsRilRequest(smscPdu, pdu);
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                try {
+                    android.hardware.radio.V1_6.IRadio radioProxy16 =
+                            (android.hardware.radio.V1_6.IRadio) radioProxy;
+                    radioProxy16.sendSms_1_6(rr.mSerial, msg);
+                    mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
+                            SmsSession.Event.Format.SMS_FORMAT_3GPP,
+                            getOutgoingSmsMessageId(result));
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "sendSMS", e);
+                }
+            } else {
+                try {
+                    radioProxy.sendSms(rr.mSerial, msg);
+                    mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
+                            SmsSession.Event.Format.SMS_FORMAT_3GPP,
+                            getOutgoingSmsMessageId(result));
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "sendSMS", e);
+                }
             }
         }
     }
@@ -1961,486 +1744,937 @@
 
     @Override
     public void sendSMSExpectMore(String smscPdu, String pdu, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SEND_SMS_EXPECT_MORE, result,
                     mRILDefaultWorkSource);
 
             // Do not log function arg for privacy
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
-            try {
-                messagingProxy.sendSmsExpectMore(rr.mSerial, smscPdu, pdu);
-                mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
-                        SmsSession.Event.Format.SMS_FORMAT_3GPP, getOutgoingSmsMessageId(result));
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "sendSMSExpectMore", e);
+            GsmSmsMessage msg = constructGsmSendSmsRilRequest(smscPdu, pdu);
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                try {
+                    android.hardware.radio.V1_6.IRadio radioProxy16 =
+                            (android.hardware.radio.V1_6.IRadio) radioProxy;
+                    radioProxy16.sendSmsExpectMore_1_6(rr.mSerial, msg);
+                    mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
+                            SmsSession.Event.Format.SMS_FORMAT_3GPP,
+                            getOutgoingSmsMessageId(result));
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "sendSMSExpectMore", e);
+                }
+            } else {
+                try {
+                    radioProxy.sendSMSExpectMore(rr.mSerial, msg);
+                    mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_GSM,
+                            SmsSession.Event.Format.SMS_FORMAT_3GPP,
+                            getOutgoingSmsMessageId(result));
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "sendSMSExpectMore", e);
+                }
             }
         }
     }
 
+    /**
+     * Convert MVNO type string into MvnoType defined in types.hal.
+     * @param mvnoType MVNO type
+     * @return MVNO type in integer
+     */
+    private static int convertToHalMvnoType(String mvnoType) {
+        switch (mvnoType) {
+            case "imsi" : return MvnoType.IMSI;
+            case "gid" : return MvnoType.GID;
+            case "spn" : return MvnoType.SPN;
+            default: return MvnoType.NONE;
+        }
+    }
+
+    /**
+     * Convert to DataProfileInfo defined in radio/1.0/types.hal
+     * @param dp Data profile
+     * @return A converted data profile
+     */
+    private static android.hardware.radio.V1_0.DataProfileInfo convertToHalDataProfile10(
+            DataProfile dp) {
+        android.hardware.radio.V1_0.DataProfileInfo dpi =
+                new android.hardware.radio.V1_0.DataProfileInfo();
+
+        dpi.profileId = dp.getProfileId();
+        dpi.apn = dp.getApn();
+        dpi.protocol = ApnSetting.getProtocolStringFromInt(dp.getProtocolType());
+        dpi.roamingProtocol = ApnSetting.getProtocolStringFromInt(dp.getRoamingProtocolType());
+        dpi.authType = dp.getAuthType();
+        dpi.user = dp.getUserName();
+        dpi.password = dp.getPassword();
+        dpi.type = dp.getType();
+        dpi.maxConnsTime = dp.getMaxConnectionsTime();
+        dpi.maxConns = dp.getMaxConnections();
+        dpi.waitTime = dp.getWaitTime();
+        dpi.enabled = dp.isEnabled();
+        dpi.supportedApnTypesBitmap = dp.getSupportedApnTypesBitmask();
+        // Shift by 1 bit due to the discrepancy between
+        // android.hardware.radio.V1_0.RadioAccessFamily and the bitmask version of
+        // ServiceState.RIL_RADIO_TECHNOLOGY_XXXX.
+        dpi.bearerBitmap = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
+                dp.getBearerBitmask()) << 1;
+        dpi.mtu = dp.getMtuV4();
+        dpi.mvnoType = MvnoType.NONE;
+        dpi.mvnoMatchData = "";
+
+        return dpi;
+    }
+
+    /**
+     * Convert to DataProfileInfo defined in radio/1.4/types.hal
+     * @param dp Data profile
+     * @return A converted data profile
+     */
+    private static android.hardware.radio.V1_4.DataProfileInfo convertToHalDataProfile14(
+            DataProfile dp) {
+        android.hardware.radio.V1_4.DataProfileInfo dpi =
+                new android.hardware.radio.V1_4.DataProfileInfo();
+
+        dpi.apn = dp.getApn();
+        dpi.protocol = dp.getProtocolType();
+        dpi.roamingProtocol = dp.getRoamingProtocolType();
+        dpi.authType = dp.getAuthType();
+        dpi.user = dp.getUserName();
+        dpi.password = dp.getPassword();
+        dpi.type = dp.getType();
+        dpi.maxConnsTime = dp.getMaxConnectionsTime();
+        dpi.maxConns = dp.getMaxConnections();
+        dpi.waitTime = dp.getWaitTime();
+        dpi.enabled = dp.isEnabled();
+        dpi.supportedApnTypesBitmap = dp.getSupportedApnTypesBitmask();
+        // Shift by 1 bit due to the discrepancy between
+        // android.hardware.radio.V1_0.RadioAccessFamily and the bitmask version of
+        // ServiceState.RIL_RADIO_TECHNOLOGY_XXXX.
+        dpi.bearerBitmap = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
+                dp.getBearerBitmask()) << 1;
+        dpi.mtu = dp.getMtuV4();
+        dpi.persistent = dp.isPersistent();
+        dpi.preferred = dp.isPreferred();
+
+        // profile id is only meaningful when it's persistent on the modem.
+        dpi.profileId = (dpi.persistent) ? dp.getProfileId() : DataProfileId.INVALID;
+
+        return dpi;
+    }
+
+    private static OptionalSliceInfo convertToHalSliceInfo(@Nullable NetworkSliceInfo sliceInfo) {
+        OptionalSliceInfo optionalSliceInfo = new OptionalSliceInfo();
+        if (sliceInfo == null) {
+            return optionalSliceInfo;
+        }
+
+        android.hardware.radio.V1_6.SliceInfo si = new android.hardware.radio.V1_6.SliceInfo();
+        si.sst = (byte) sliceInfo.getSliceServiceType();
+        si.mappedHplmnSst = (byte) sliceInfo.getMappedHplmnSliceServiceType();
+        si.sliceDifferentiator = sliceInfo.getSliceDifferentiator();
+        si.mappedHplmnSD = sliceInfo.getMappedHplmnSliceDifferentiator();
+        optionalSliceInfo.value(si);
+        return optionalSliceInfo;
+    }
+
+    private static OptionalTrafficDescriptor convertToHalTrafficDescriptor(
+            @Nullable TrafficDescriptor trafficDescriptor) {
+        OptionalTrafficDescriptor optionalTrafficDescriptor = new OptionalTrafficDescriptor();
+        if (trafficDescriptor == null) {
+            return optionalTrafficDescriptor;
+        }
+
+        android.hardware.radio.V1_6.TrafficDescriptor td =
+                new android.hardware.radio.V1_6.TrafficDescriptor();
+
+        OptionalDnn optionalDnn = new OptionalDnn();
+        if (trafficDescriptor.getDataNetworkName() != null) {
+            optionalDnn.value(trafficDescriptor.getDataNetworkName());
+        }
+        td.dnn = optionalDnn;
+
+        OptionalOsAppId optionalOsAppId = new OptionalOsAppId();
+        if (trafficDescriptor.getOsAppId() != null) {
+            android.hardware.radio.V1_6.OsAppId osAppId = new android.hardware.radio.V1_6.OsAppId();
+            osAppId.osAppId = primitiveArrayToArrayList(trafficDescriptor.getOsAppId());
+            optionalOsAppId.value(osAppId);
+        }
+        td.osAppId = optionalOsAppId;
+
+        optionalTrafficDescriptor.value(td);
+        return optionalTrafficDescriptor;
+    }
+
+    private static ArrayList<android.hardware.radio.V1_5.LinkAddress> convertToHalLinkProperties15(
+            LinkProperties linkProperties) {
+        ArrayList<android.hardware.radio.V1_5.LinkAddress> addresses15 = new ArrayList<>();
+        if (linkProperties != null) {
+            for (LinkAddress la : linkProperties.getAllLinkAddresses()) {
+                android.hardware.radio.V1_5.LinkAddress linkAddress =
+                        new android.hardware.radio.V1_5.LinkAddress();
+                linkAddress.address = la.getAddress().getHostAddress();
+                linkAddress.properties = la.getFlags();
+                linkAddress.deprecationTime = la.getDeprecationTime();
+                linkAddress.expirationTime = la.getExpirationTime();
+                addresses15.add(linkAddress);
+            }
+        }
+        return addresses15;
+    }
+
+    /**
+     * Convert to DataProfileInfo defined in radio/1.5/types.hal
+     * @param dp Data profile
+     * @return A converted data profile
+     */
+    private static android.hardware.radio.V1_5.DataProfileInfo convertToHalDataProfile15(
+            DataProfile dp) {
+        android.hardware.radio.V1_5.DataProfileInfo dpi =
+                new android.hardware.radio.V1_5.DataProfileInfo();
+
+        dpi.apn = dp.getApn();
+        dpi.protocol = dp.getProtocolType();
+        dpi.roamingProtocol = dp.getRoamingProtocolType();
+        dpi.authType = dp.getAuthType();
+        dpi.user = dp.getUserName();
+        dpi.password = dp.getPassword();
+        dpi.type = dp.getType();
+        dpi.maxConnsTime = dp.getMaxConnectionsTime();
+        dpi.maxConns = dp.getMaxConnections();
+        dpi.waitTime = dp.getWaitTime();
+        dpi.enabled = dp.isEnabled();
+        dpi.supportedApnTypesBitmap = dp.getSupportedApnTypesBitmask();
+        // Shift by 1 bit due to the discrepancy between
+        // android.hardware.radio.V1_0.RadioAccessFamily and the bitmask version of
+        // ServiceState.RIL_RADIO_TECHNOLOGY_XXXX.
+        dpi.bearerBitmap = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
+            dp.getBearerBitmask()) << 1;
+        dpi.mtuV4 = dp.getMtuV4();
+        dpi.mtuV6 = dp.getMtuV6();
+        dpi.persistent = dp.isPersistent();
+        dpi.preferred = dp.isPreferred();
+
+        // profile id is only meaningful when it's persistent on the modem.
+        dpi.profileId = (dpi.persistent) ? dp.getProfileId() : DataProfileId.INVALID;
+
+        return dpi;
+    }
+
+    /**
+     * Convert NV reset type into ResetNvType defined in types.hal.
+     * @param resetType NV reset type.
+     * @return Converted reset type in integer or -1 if param is invalid.
+     */
+    private static int convertToHalResetNvType(int resetType) {
+        /**
+         * resetType values
+         * 1 - reload all NV items
+         * 2 - erase NV reset (SCRTN)
+         * 3 - factory reset (RTN)
+         */
+        switch (resetType) {
+            case 1: return ResetNvType.RELOAD;
+            case 2: return ResetNvType.ERASE;
+            case 3: return ResetNvType.FACTORY_RESET;
+        }
+        return -1;
+    }
+
     @Override
     public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming,
             boolean allowRoaming, int reason, LinkProperties linkProperties, int pduSessionId,
             NetworkSliceInfo sliceInfo, TrafficDescriptor trafficDescriptor,
             boolean matchAllRuleAllowed, Message result) {
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (!dataProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+
+        if (radioProxy != null) {
+
             RILRequest rr = obtainRequest(RIL_REQUEST_SETUP_DATA_CALL, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + ",reason=" + RILUtils.setupDataReasonToString(reason)
-                        + ",accessNetworkType=" + AccessNetworkType.toString(accessNetworkType)
-                        + ",dataProfile=" + dataProfile + ",isRoaming=" + isRoaming
-                        + ",allowRoaming=" + allowRoaming
-                        + ",linkProperties=" + linkProperties + ",pduSessionId=" + pduSessionId
-                        + ",sliceInfo=" + sliceInfo + ",trafficDescriptor=" + trafficDescriptor
-                        + ",matchAllRuleAllowed=" + matchAllRuleAllowed);
+            ArrayList<String> addresses = new ArrayList<>();
+            ArrayList<String> dnses = new ArrayList<>();
+            if (linkProperties != null) {
+                for (InetAddress address : linkProperties.getAddresses()) {
+                    addresses.add(address.getHostAddress());
+                }
+                for (InetAddress dns : linkProperties.getDnsServers()) {
+                    dnses.add(dns.getHostAddress());
+                }
             }
 
             try {
-                dataProxy.setupDataCall(rr.mSerial, mPhoneId, accessNetworkType, dataProfile,
-                        isRoaming, allowRoaming, reason, linkProperties, pduSessionId, sliceInfo,
-                        trafficDescriptor, matchAllRuleAllowed);
+                if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                    // IRadio V1.6
+                    android.hardware.radio.V1_6.IRadio radioProxy16 =
+                            (android.hardware.radio.V1_6.IRadio) radioProxy;
+
+                    // Convert to HAL data profile
+                    android.hardware.radio.V1_5.DataProfileInfo dpi =
+                            convertToHalDataProfile15(dataProfile);
+
+                    OptionalSliceInfo si = convertToHalSliceInfo(sliceInfo);
+
+                    ArrayList<android.hardware.radio.V1_5.LinkAddress> addresses15 =
+                            convertToHalLinkProperties15(linkProperties);
+
+                    OptionalTrafficDescriptor td = convertToHalTrafficDescriptor(trafficDescriptor);
+
+                    if (RILJ_LOGD) {
+                        riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                                + ",accessNetworkType="
+                                + AccessNetworkType.toString(accessNetworkType) + ",isRoaming="
+                                + isRoaming + ",allowRoaming=" + allowRoaming + "," + dataProfile
+                                + ",addresses=" + addresses15 + ",dnses=" + dnses
+                                + ",pduSessionId=" + pduSessionId + ",sliceInfo=" + si
+                                + ",trafficDescriptor=" + td + ",matchAllRuleAllowed="
+                                + matchAllRuleAllowed);
+                    }
+
+                    radioProxy16.setupDataCall_1_6(rr.mSerial, accessNetworkType, dpi, allowRoaming,
+                            reason, addresses15, dnses, pduSessionId, si, td, matchAllRuleAllowed);
+                } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+                    // IRadio V1.5
+                    android.hardware.radio.V1_5.IRadio radioProxy15 =
+                            (android.hardware.radio.V1_5.IRadio) radioProxy;
+
+                    // Convert to HAL data profile
+                    android.hardware.radio.V1_5.DataProfileInfo dpi =
+                            convertToHalDataProfile15(dataProfile);
+
+                    ArrayList<android.hardware.radio.V1_5.LinkAddress> addresses15 =
+                            convertToHalLinkProperties15(linkProperties);
+
+                    if (RILJ_LOGD) {
+                        riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                                + ",accessNetworkType="
+                                + AccessNetworkType.toString(accessNetworkType) + ",isRoaming="
+                                + isRoaming + ",allowRoaming=" + allowRoaming + "," + dataProfile
+                                + ",addresses=" + addresses15 + ",dnses=" + dnses);
+                    }
+
+                    radioProxy15.setupDataCall_1_5(rr.mSerial, accessNetworkType, dpi, allowRoaming,
+                             reason, addresses15, dnses);
+                } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
+                    // IRadio V1.4
+                    android.hardware.radio.V1_4.IRadio radioProxy14 =
+                            (android.hardware.radio.V1_4.IRadio) radioProxy;
+
+                    // Convert to HAL data profile
+                    android.hardware.radio.V1_4.DataProfileInfo dpi =
+                            convertToHalDataProfile14(dataProfile);
+
+                    if (RILJ_LOGD) {
+                        riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                                + ",accessNetworkType="
+                                + AccessNetworkType.toString(accessNetworkType) + ",isRoaming="
+                                + isRoaming + ",allowRoaming=" + allowRoaming + "," + dataProfile
+                                + ",addresses=" + addresses + ",dnses=" + dnses);
+                    }
+
+                    radioProxy14.setupDataCall_1_4(rr.mSerial, accessNetworkType, dpi, allowRoaming,
+                            reason, addresses, dnses);
+                } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
+                    // IRadio V1.2 and IRadio V1.3
+                    android.hardware.radio.V1_2.IRadio radioProxy12 =
+                            (android.hardware.radio.V1_2.IRadio) radioProxy;
+
+                    // Convert to HAL data profile
+                    android.hardware.radio.V1_0.DataProfileInfo dpi =
+                            convertToHalDataProfile10(dataProfile);
+
+                    if (RILJ_LOGD) {
+                        riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                                + ",accessNetworkType="
+                                + AccessNetworkType.toString(accessNetworkType) + ",isRoaming="
+                                + isRoaming + ",allowRoaming=" + allowRoaming + ","
+                                + dataProfile + ",addresses=" + addresses + ",dnses=" + dnses);
+                    }
+
+                    radioProxy12.setupDataCall_1_2(rr.mSerial, accessNetworkType, dpi,
+                            dataProfile.isPersistent(), allowRoaming, isRoaming, reason,
+                            addresses, dnses);
+                } else {
+                    // IRadio V1.0 and IRadio V1.1
+
+                    // Convert to HAL data profile
+                    android.hardware.radio.V1_0.DataProfileInfo dpi =
+                            convertToHalDataProfile10(dataProfile);
+
+                    // Getting data RAT here is just a workaround to support the older 1.0
+                    // vendor RIL. The new data service interface passes access network type
+                    // instead of RAT for setup data request. It is impossible to convert access
+                    // network type back to RAT here, so we directly get the data RAT from
+                    // phone.
+                    int dataRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
+                    Phone phone = PhoneFactory.getPhone(mPhoneId);
+                    if (phone != null) {
+                        ServiceState ss = phone.getServiceState();
+                        if (ss != null) {
+                            dataRat = ss.getRilDataRadioTechnology();
+                        }
+                    }
+                    if (RILJ_LOGD) {
+                        riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                                + ",dataRat=" + dataRat + ",isRoaming=" + isRoaming
+                                + ",allowRoaming=" + allowRoaming + "," + dataProfile);
+                    }
+
+                    radioProxy.setupDataCall(rr.mSerial, dataRat, dpi,
+                            dataProfile.isPersistent(), allowRoaming, isRoaming);
+                }
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "setupDataCall", e);
+                handleRadioProxyExceptionForRR(rr, "setupDataCall", e);
             }
         }
     }
 
     @Override
-    public void iccIO(int command, int fileId, String path, int p1, int p2, int p3, String data,
-            String pin2, Message result) {
+    public void iccIO(int command, int fileId, String path, int p1, int p2, int p3,
+                      String data, String pin2, Message result) {
         iccIOForApp(command, fileId, path, p1, p2, p3, data, pin2, null, result);
     }
 
     @Override
     public void iccIOForApp(int command, int fileId, String path, int p1, int p2, int p3,
-            String data, String pin2, String aid, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SIM_IO, result, mRILDefaultWorkSource);
+                 String data, String pin2, String aid, Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SIM_IO, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
                 if (TelephonyUtils.IS_DEBUGGABLE) {
-                    riljLog(rr.serialString() + "> iccIO: " + RILUtils.requestToString(rr.mRequest)
-                            + " command = 0x" + Integer.toHexString(command) + " fileId = 0x"
-                            + Integer.toHexString(fileId) + " path = " + path + " p1 = " + p1
-                            + " p2 = " + p2 + " p3 = " + " data = " + data + " aid = " + aid);
-                } else {
                     riljLog(rr.serialString() + "> iccIO: "
-                            + RILUtils.requestToString(rr.mRequest));
+                            + requestToString(rr.mRequest) + " command = 0x"
+                            + Integer.toHexString(command) + " fileId = 0x"
+                            + Integer.toHexString(fileId) + " path = " + path + " p1 = "
+                            + p1 + " p2 = " + p2 + " p3 = " + " data = " + data
+                            + " aid = " + aid);
+                } else {
+                    riljLog(rr.serialString() + "> iccIO: " + requestToString(rr.mRequest));
                 }
             }
 
+            IccIo iccIo = new IccIo();
+            iccIo.command = command;
+            iccIo.fileId = fileId;
+            iccIo.path = convertNullToEmptyString(path);
+            iccIo.p1 = p1;
+            iccIo.p2 = p2;
+            iccIo.p3 = p3;
+            iccIo.data = convertNullToEmptyString(data);
+            iccIo.pin2 = convertNullToEmptyString(pin2);
+            iccIo.aid = convertNullToEmptyString(aid);
+
             try {
-                simProxy.iccIoForApp(rr.mSerial, command, fileId,
-                        RILUtils.convertNullToEmptyString(path), p1, p2, p3,
-                        RILUtils.convertNullToEmptyString(data),
-                        RILUtils.convertNullToEmptyString(pin2),
-                        RILUtils.convertNullToEmptyString(aid));
+                radioProxy.iccIOForApp(rr.mSerial, iccIo);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "iccIoForApp", e);
+                handleRadioProxyExceptionForRR(rr, "iccIOForApp", e);
             }
         }
     }
 
     @Override
     public void sendUSSD(String ussd, Message result) {
-        RadioVoiceProxy voiceProxy =
-                getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SEND_USSD, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SEND_USSD, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
                 String logUssd = "*******";
                 if (RILJ_LOGV) logUssd = ussd;
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " ussd = " + logUssd);
             }
 
             try {
-                voiceProxy.sendUssd(rr.mSerial, RILUtils.convertNullToEmptyString(ussd));
+                radioProxy.sendUssd(rr.mSerial, convertNullToEmptyString(ussd));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "sendUssd", e);
+                handleRadioProxyExceptionForRR(rr, "sendUSSD", e);
             }
         }
     }
 
     @Override
     public void cancelPendingUssd(Message result) {
-        RadioVoiceProxy voiceProxy =
-                getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_CANCEL_USSD, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_CANCEL_USSD, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString()
+                        + "> " + requestToString(rr.mRequest));
             }
 
             try {
-                voiceProxy.cancelPendingUssd(rr.mSerial);
+                radioProxy.cancelPendingUssd(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "cancelPendingUssd", e);
+                handleRadioProxyExceptionForRR(rr, "cancelPendingUssd", e);
             }
         }
     }
 
     @Override
     public void getCLIR(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_GET_CLIR, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_GET_CLIR, result,
+                    mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.getClir(rr.mSerial);
+                radioProxy.getClir(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getClir", e);
+                handleRadioProxyExceptionForRR(rr, "getCLIR", e);
             }
         }
     }
 
     @Override
     public void setCLIR(int clirMode, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_CLIR, result, mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " clirMode = " + clirMode);
             }
 
             try {
-                voiceProxy.setClir(rr.mSerial, clirMode);
+                radioProxy.setClir(rr.mSerial, clirMode);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "setClir", e);
+                handleRadioProxyExceptionForRR(rr, "setCLIR", e);
             }
         }
     }
 
     @Override
-    public void queryCallForwardStatus(int cfReason, int serviceClass, String number,
-            Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+    public void queryCallForwardStatus(int cfReason, int serviceClass,
+                           String number, Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CALL_FORWARD_STATUS, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " cfreason = " + cfReason + " serviceClass = " + serviceClass);
             }
 
+            android.hardware.radio.V1_0.CallForwardInfo cfInfo =
+                    new android.hardware.radio.V1_0.CallForwardInfo();
+            cfInfo.reason = cfReason;
+            cfInfo.serviceClass = serviceClass;
+            cfInfo.toa = PhoneNumberUtils.toaFromString(number);
+            cfInfo.number = convertNullToEmptyString(number);
+            cfInfo.timeSeconds = 0;
+
             try {
-                voiceProxy.getCallForwardStatus(rr.mSerial, cfReason, serviceClass, number);
+                radioProxy.getCallForwardStatus(rr.mSerial, cfInfo);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getCallForwardStatus", e);
+                handleRadioProxyExceptionForRR(rr, "queryCallForwardStatus", e);
             }
         }
     }
 
     @Override
-    public void setCallForward(int action, int cfReason, int serviceClass, String number,
-            int timeSeconds, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+    public void setCallForward(int action, int cfReason, int serviceClass,
+                   String number, int timeSeconds, Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_CALL_FORWARD, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " action = " + action + " cfReason = " + cfReason + " serviceClass = "
                         + serviceClass + " timeSeconds = " + timeSeconds);
             }
 
+            android.hardware.radio.V1_0.CallForwardInfo cfInfo =
+                    new android.hardware.radio.V1_0.CallForwardInfo();
+            cfInfo.status = action;
+            cfInfo.reason = cfReason;
+            cfInfo.serviceClass = serviceClass;
+            cfInfo.toa = PhoneNumberUtils.toaFromString(number);
+            cfInfo.number = convertNullToEmptyString(number);
+            cfInfo.timeSeconds = timeSeconds;
+
             try {
-                voiceProxy.setCallForward(
-                        rr.mSerial, action, cfReason, serviceClass, number, timeSeconds);
+                radioProxy.setCallForward(rr.mSerial, cfInfo);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "setCallForward", e);
+                handleRadioProxyExceptionForRR(rr, "setCallForward", e);
+
             }
         }
     }
 
     @Override
     public void queryCallWaiting(int serviceClass, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CALL_WAITING, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " serviceClass = " + serviceClass);
             }
 
             try {
-                voiceProxy.getCallWaiting(rr.mSerial, serviceClass);
+                radioProxy.getCallWaiting(rr.mSerial, serviceClass);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getCallWaiting", e);
+                handleRadioProxyExceptionForRR(rr, "queryCallWaiting", e);
             }
         }
     }
 
     @Override
     public void setCallWaiting(boolean enable, int serviceClass, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_CALL_WAITING, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " enable = " + enable + " serviceClass = " + serviceClass);
             }
 
             try {
-                voiceProxy.setCallWaiting(rr.mSerial, enable, serviceClass);
+                radioProxy.setCallWaiting(rr.mSerial, enable, serviceClass);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "setCallWaiting", e);
+                handleRadioProxyExceptionForRR(rr, "setCallWaiting", e);
             }
         }
     }
 
     @Override
     public void acknowledgeLastIncomingGsmSms(boolean success, int cause, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SMS_ACKNOWLEDGE, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " success = " + success + " cause = " + cause);
             }
 
             try {
-                messagingProxy.acknowledgeLastIncomingGsmSms(rr.mSerial, success, cause);
+                radioProxy.acknowledgeLastIncomingGsmSms(rr.mSerial, success, cause);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE,
-                        "acknowledgeLastIncomingGsmSms", e);
+                handleRadioProxyExceptionForRR(rr, "acknowledgeLastIncomingGsmSms", e);
             }
         }
     }
 
     @Override
     public void acceptCall(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_ANSWER, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_ANSWER, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
             try {
-                voiceProxy.acceptCall(rr.mSerial);
+                radioProxy.acceptCall(rr.mSerial);
                 mMetrics.writeRilAnswer(mPhoneId, rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "acceptCall", e);
+                handleRadioProxyExceptionForRR(rr, "acceptCall", e);
             }
         }
     }
 
     @Override
     public void deactivateDataCall(int cid, int reason, Message result) {
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (!dataProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_DEACTIVATE_DATA_CALL, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " cid = " + cid + " reason = "
-                        + RILUtils.deactivateDataReasonToString(reason));
+                riljLog(rr.serialString() + "> "
+                        + requestToString(rr.mRequest) + " cid = " + cid + " reason = " + reason);
             }
 
             try {
-                dataProxy.deactivateDataCall(rr.mSerial, cid, reason);
+                if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
+                    android.hardware.radio.V1_2.IRadio radioProxy12 =
+                            (android.hardware.radio.V1_2.IRadio) radioProxy;
+
+                    radioProxy12.deactivateDataCall_1_2(rr.mSerial, cid, reason);
+                } else {
+                    radioProxy.deactivateDataCall(rr.mSerial, cid,
+                            (reason == DataService.REQUEST_REASON_SHUTDOWN));
+                }
                 mMetrics.writeRilDeactivateDataCall(mPhoneId, rr.mSerial, cid, reason);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "deactivateDataCall", e);
+                handleRadioProxyExceptionForRR(rr, "deactivateDataCall", e);
             }
         }
     }
 
     @Override
     public void queryFacilityLock(String facility, String password, int serviceClass,
-            Message result) {
+                                  Message result) {
         queryFacilityLockForApp(facility, password, serviceClass, null, result);
     }
 
     @Override
     public void queryFacilityLockForApp(String facility, String password, int serviceClass,
-            String appId, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+                                        String appId, Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_FACILITY_LOCK, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " facility = " + facility + " serviceClass = " + serviceClass
                         + " appId = " + appId);
             }
 
             try {
-                simProxy.getFacilityLockForApp(rr.mSerial,
-                        RILUtils.convertNullToEmptyString(facility),
-                        RILUtils.convertNullToEmptyString(password),
-                        serviceClass, RILUtils.convertNullToEmptyString(appId));
+                radioProxy.getFacilityLockForApp(rr.mSerial,
+                        convertNullToEmptyString(facility),
+                        convertNullToEmptyString(password),
+                        serviceClass,
+                        convertNullToEmptyString(appId));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getFacilityLockForApp", e);
+                handleRadioProxyExceptionForRR(rr, "getFacilityLockForApp", e);
             }
         }
     }
 
     @Override
     public void setFacilityLock(String facility, boolean lockState, String password,
-            int serviceClass, Message result) {
+                                int serviceClass, Message result) {
         setFacilityLockForApp(facility, lockState, password, serviceClass, null, result);
     }
 
     @Override
     public void setFacilityLockForApp(String facility, boolean lockState, String password,
-            int serviceClass, String appId, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+                                      int serviceClass, String appId, Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_FACILITY_LOCK, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " facility = " + facility + " lockstate = " + lockState
                         + " serviceClass = " + serviceClass + " appId = " + appId);
             }
 
             try {
-                simProxy.setFacilityLockForApp(rr.mSerial,
-                        RILUtils.convertNullToEmptyString(facility), lockState,
-                        RILUtils.convertNullToEmptyString(password), serviceClass,
-                        RILUtils.convertNullToEmptyString(appId));
+                radioProxy.setFacilityLockForApp(rr.mSerial,
+                        convertNullToEmptyString(facility),
+                        lockState,
+                        convertNullToEmptyString(password),
+                        serviceClass,
+                        convertNullToEmptyString(appId));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "setFacilityLockForApp", e);
+                handleRadioProxyExceptionForRR(rr, "setFacilityLockForApp", e);
             }
         }
     }
 
     @Override
     public void changeBarringPassword(String facility, String oldPwd, String newPwd,
-            Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+                                      Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CHANGE_BARRING_PASSWORD, result,
                     mRILDefaultWorkSource);
 
             // Do not log all function args for privacy
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + "facility = " + facility);
             }
 
             try {
-                networkProxy.setBarringPassword(rr.mSerial,
-                        RILUtils.convertNullToEmptyString(facility),
-                        RILUtils.convertNullToEmptyString(oldPwd),
-                        RILUtils.convertNullToEmptyString(newPwd));
+                radioProxy.setBarringPassword(rr.mSerial,
+                        convertNullToEmptyString(facility),
+                        convertNullToEmptyString(oldPwd),
+                        convertNullToEmptyString(newPwd));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "changeBarringPassword", e);
+                handleRadioProxyExceptionForRR(rr, "changeBarringPassword", e);
             }
         }
     }
 
     @Override
     public void getNetworkSelectionMode(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                networkProxy.getNetworkSelectionMode(rr.mSerial);
+                radioProxy.getNetworkSelectionMode(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getNetworkSelectionMode", e);
+                handleRadioProxyExceptionForRR(rr, "getNetworkSelectionMode", e);
             }
         }
     }
 
     @Override
     public void setNetworkSelectionModeAutomatic(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                networkProxy.setNetworkSelectionModeAutomatic(rr.mSerial);
+                radioProxy.setNetworkSelectionModeAutomatic(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(
-                        NETWORK_SERVICE, "setNetworkSelectionModeAutomatic", e);
+                handleRadioProxyExceptionForRR(rr, "setNetworkSelectionModeAutomatic", e);
             }
         }
     }
 
     @Override
     public void setNetworkSelectionModeManual(String operatorNumeric, int ran, Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL, result,
                     mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " operatorNumeric = " + operatorNumeric + ", ran = " + ran);
-            }
-
             try {
-                networkProxy.setNetworkSelectionModeManual(rr.mSerial,
-                        RILUtils.convertNullToEmptyString(operatorNumeric), ran);
+                int halRan = convertAntToRan(ran);
+                if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+                    android.hardware.radio.V1_5.IRadio radioProxy15 =
+                            (android.hardware.radio.V1_5.IRadio) radioProxy;
+                    if (RILJ_LOGD) {
+                        riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                                + " operatorNumeric = " + operatorNumeric
+                                + ", ran = " + halRan);
+                    }
+                    radioProxy15.setNetworkSelectionModeManual_1_5(rr.mSerial,
+                            convertNullToEmptyString(operatorNumeric), halRan);
+                } else {
+                    if (RILJ_LOGD) {
+                        riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                                + " operatorNumeric = " + operatorNumeric);
+                    }
+                    radioProxy.setNetworkSelectionModeManual(rr.mSerial,
+                            convertNullToEmptyString(operatorNumeric));
+                }
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setNetworkSelectionModeManual", e);
+                handleRadioProxyExceptionForRR(rr, "setNetworkSelectionModeManual", e);
             }
         }
     }
 
     @Override
     public void getAvailableNetworks(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_AVAILABLE_NETWORKS, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                networkProxy.getAvailableNetworks(rr.mSerial);
+                radioProxy.getAvailableNetworks(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getAvailableNetworks", e);
+                handleRadioProxyExceptionForRR(rr, "getAvailableNetworks", e);
             }
         }
     }
 
+    private android.hardware.radio.V1_1.RadioAccessSpecifier convertRadioAccessSpecifierToRadioHAL(
+            RadioAccessSpecifier ras) {
+        android.hardware.radio.V1_1.RadioAccessSpecifier rasInHalFormat =
+                new android.hardware.radio.V1_1.RadioAccessSpecifier();
+        rasInHalFormat.radioAccessNetwork = ras.getRadioAccessNetwork();
+        ArrayList<Integer> bands = new ArrayList<>();
+        if (ras.getBands() != null) {
+            for (int band : ras.getBands()) {
+                bands.add(band);
+            }
+        }
+        switch (ras.getRadioAccessNetwork()) {
+            case AccessNetworkType.GERAN:
+                rasInHalFormat.geranBands = bands;
+                break;
+            case AccessNetworkType.UTRAN:
+                rasInHalFormat.utranBands = bands;
+                break;
+            case AccessNetworkType.EUTRAN:
+                rasInHalFormat.eutranBands = bands;
+                break;
+            default:
+                Log.wtf(RILJ_LOG_TAG, "radioAccessNetwork " + ras.getRadioAccessNetwork()
+                        + " not supported on IRadio < 1.5!");
+                return null;
+        }
+
+        if (ras.getChannels() != null) {
+            for (int channel : ras.getChannels()) {
+                rasInHalFormat.channels.add(channel);
+            }
+        }
+
+        return rasInHalFormat;
+    }
+
+    private android.hardware.radio.V1_5.RadioAccessSpecifier
+            convertRadioAccessSpecifierToRadioHAL_1_5(RadioAccessSpecifier ras) {
+        android.hardware.radio.V1_5.RadioAccessSpecifier rasInHalFormat =
+                new android.hardware.radio.V1_5.RadioAccessSpecifier();
+        android.hardware.radio.V1_5.RadioAccessSpecifier.Bands bandsInHalFormat =
+                new android.hardware.radio.V1_5.RadioAccessSpecifier.Bands();
+        rasInHalFormat.radioAccessNetwork = convertAntToRan(ras.getRadioAccessNetwork());
+        ArrayList<Integer> bands = new ArrayList<>();
+        if (ras.getBands() != null) {
+            for (int band : ras.getBands()) {
+                bands.add(band);
+            }
+        }
+        switch (ras.getRadioAccessNetwork()) {
+            case AccessNetworkType.GERAN:
+                bandsInHalFormat.geranBands(bands);
+                break;
+            case AccessNetworkType.UTRAN:
+                bandsInHalFormat.utranBands(bands);
+                break;
+            case AccessNetworkType.EUTRAN:
+                bandsInHalFormat.eutranBands(bands);
+                break;
+            case AccessNetworkType.NGRAN:
+                bandsInHalFormat.ngranBands(bands);
+                break;
+            default:
+                Log.wtf(RILJ_LOG_TAG, "radioAccessNetwork " + ras.getRadioAccessNetwork()
+                        + " not supported on IRadio 1.5!");
+                return null;
+        }
+        rasInHalFormat.bands = bandsInHalFormat;
+
+        if (ras.getChannels() != null) {
+            for (int channel : ras.getChannels()) {
+                rasInHalFormat.channels.add(channel);
+            }
+        }
+
+        return rasInHalFormat;
+    }
+
     /**
      * Radio HAL fallback compatibility feature (b/151106728) assumes that the input parameter
      * networkScanRequest is immutable (read-only) here. Once the caller invokes the method, the
@@ -2449,30 +2683,130 @@
      */
     @Override
     public void startNetworkScan(NetworkScanRequest networkScanRequest, Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
+        final NetworkScanRequest nsr = networkScanRequest;
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+
             HalVersion overrideHalVersion = getCompatVersion(RIL_REQUEST_START_NETWORK_SCAN);
             if (RILJ_LOGD) {
                 riljLog("startNetworkScan: overrideHalVersion=" + overrideHalVersion);
             }
+            if ((overrideHalVersion == null
+                        || overrideHalVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5))
+                    && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+                android.hardware.radio.V1_5.NetworkScanRequest request =
+                        new android.hardware.radio.V1_5.NetworkScanRequest();
+                request.type = nsr.getScanType();
+                request.interval = nsr.getSearchPeriodicity();
+                request.maxSearchTime = nsr.getMaxSearchTime();
+                request.incrementalResultsPeriodicity = nsr.getIncrementalResultsPeriodicity();
+                request.incrementalResults = nsr.getIncrementalResults();
 
-            RILRequest rr = obtainRequest(RIL_REQUEST_START_NETWORK_SCAN, result,
-                    mRILDefaultWorkSource, networkScanRequest);
+                for (RadioAccessSpecifier ras : nsr.getSpecifiers()) {
+                    android.hardware.radio.V1_5.RadioAccessSpecifier rasInHalFormat =
+                            convertRadioAccessSpecifierToRadioHAL_1_5(ras);
+                    if (rasInHalFormat == null) {
+                        AsyncResult.forMessage(result, null,
+                                CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                        result.sendToTarget();
+                        return;
+                    }
+                    request.specifiers.add(rasInHalFormat);
+                }
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+                request.mccMncs.addAll(nsr.getPlmns());
+                RILRequest rr = obtainRequest(RIL_REQUEST_START_NETWORK_SCAN, result,
+                        mRILDefaultWorkSource, nsr);
 
-            try {
-                networkProxy.startNetworkScan(rr.mSerial, networkScanRequest, overrideHalVersion,
-                        result);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "startNetworkScan", e);
-            }
-        } else {
-            if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "startNetworkScan: REQUEST_NOT_SUPPORTED");
-            if (result != null) {
+                if (RILJ_LOGD) {
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+                }
+
+                try {
+                    android.hardware.radio.V1_5.IRadio radioProxy15 =
+                            (android.hardware.radio.V1_5.IRadio) radioProxy;
+                    radioProxy15.startNetworkScan_1_5(rr.mSerial, request);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "startNetworkScan", e);
+                }
+            } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
+                android.hardware.radio.V1_2.NetworkScanRequest request =
+                        new android.hardware.radio.V1_2.NetworkScanRequest();
+                request.type = nsr.getScanType();
+                request.interval = nsr.getSearchPeriodicity();
+                request.maxSearchTime = nsr.getMaxSearchTime();
+                request.incrementalResultsPeriodicity = nsr.getIncrementalResultsPeriodicity();
+                request.incrementalResults = nsr.getIncrementalResults();
+
+                for (RadioAccessSpecifier ras : nsr.getSpecifiers()) {
+
+                    android.hardware.radio.V1_1.RadioAccessSpecifier rasInHalFormat =
+                            convertRadioAccessSpecifierToRadioHAL(ras);
+                    if (rasInHalFormat == null) {
+                        AsyncResult.forMessage(result, null,
+                                CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                        result.sendToTarget();
+                        return;
+                    }
+
+                    request.specifiers.add(rasInHalFormat);
+                }
+
+                request.mccMncs.addAll(nsr.getPlmns());
+                RILRequest rr = obtainRequest(RIL_REQUEST_START_NETWORK_SCAN, result,
+                        mRILDefaultWorkSource);
+
+                if (RILJ_LOGD) {
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+                }
+
+                try {
+                    if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
+                        android.hardware.radio.V1_4.IRadio radioProxy14 =
+                                (android.hardware.radio.V1_4.IRadio) radioProxy;
+                        radioProxy14.startNetworkScan_1_4(rr.mSerial, request);
+                    } else {
+                        android.hardware.radio.V1_2.IRadio radioProxy12 =
+                                (android.hardware.radio.V1_2.IRadio) radioProxy;
+                        radioProxy12.startNetworkScan_1_2(rr.mSerial, request);
+                    }
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "startNetworkScan", e);
+                }
+            } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
+                android.hardware.radio.V1_1.IRadio radioProxy11 =
+                        (android.hardware.radio.V1_1.IRadio) radioProxy;
+
+                android.hardware.radio.V1_1.NetworkScanRequest request =
+                        new android.hardware.radio.V1_1.NetworkScanRequest();
+                request.type = nsr.getScanType();
+                request.interval = nsr.getSearchPeriodicity();
+                for (RadioAccessSpecifier ras : nsr.getSpecifiers()) {
+                    android.hardware.radio.V1_1.RadioAccessSpecifier rasInHalFormat =
+                            convertRadioAccessSpecifierToRadioHAL(ras);
+                    if (rasInHalFormat == null) {
+                        AsyncResult.forMessage(result, null,
+                                CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                        result.sendToTarget();
+                        return;
+                    }
+
+                    request.specifiers.add(rasInHalFormat);
+                }
+
+                RILRequest rr = obtainRequest(RIL_REQUEST_START_NETWORK_SCAN, result,
+                        mRILDefaultWorkSource);
+
+                if (RILJ_LOGD) {
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+                }
+
+                try {
+                    radioProxy11.startNetworkScan(rr.mSerial, request);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "startNetworkScan", e);
+                }
+            } else if (result != null) {
                 AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
                 result.sendToTarget();
@@ -2482,24 +2816,25 @@
 
     @Override
     public void stopNetworkScan(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_STOP_NETWORK_SCAN, result,
-                    mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
+                android.hardware.radio.V1_1.IRadio radioProxy11 =
+                        (android.hardware.radio.V1_1.IRadio) radioProxy;
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+                RILRequest rr = obtainRequest(RIL_REQUEST_STOP_NETWORK_SCAN, result,
+                        mRILDefaultWorkSource);
 
-            try {
-                networkProxy.stopNetworkScan(rr.mSerial);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "stopNetworkScan", e);
-            }
-        } else {
-            if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "stopNetworkScan: REQUEST_NOT_SUPPORTED");
-            if (result != null) {
+                if (RILJ_LOGD) {
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+                }
+
+                try {
+                    radioProxy11.stopNetworkScan(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "stopNetworkScan", e);
+                }
+            } else if (result != null) {
                 AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
                 result.sendToTarget();
@@ -2509,131 +2844,126 @@
 
     @Override
     public void startDtmf(char c, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_DTMF_START, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_DTMF_START, result,
+                    mRILDefaultWorkSource);
 
             // Do not log function arg for privacy
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.startDtmf(rr.mSerial, c + "");
+                radioProxy.startDtmf(rr.mSerial, c + "");
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "startDtmf", e);
+                handleRadioProxyExceptionForRR(rr, "startDtmf", e);
             }
         }
     }
 
     @Override
     public void stopDtmf(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_DTMF_STOP, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_DTMF_STOP, result,
+                    mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.stopDtmf(rr.mSerial);
+                radioProxy.stopDtmf(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "stopDtmf", e);
+                handleRadioProxyExceptionForRR(rr, "stopDtmf", e);
             }
         }
     }
 
     @Override
     public void separateConnection(int gsmIndex, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SEPARATE_CONNECTION, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " gsmIndex = " + gsmIndex);
             }
 
             try {
-                voiceProxy.separateConnection(rr.mSerial, gsmIndex);
+                radioProxy.separateConnection(rr.mSerial, gsmIndex);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "separateConnection", e);
+                handleRadioProxyExceptionForRR(rr, "separateConnection", e);
             }
         }
     }
 
     @Override
     public void getBasebandVersion(Message result) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (!modemProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_BASEBAND_VERSION, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                modemProxy.getBasebandVersion(rr.mSerial);
+                radioProxy.getBasebandVersion(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getBasebandVersion", e);
+                handleRadioProxyExceptionForRR(rr, "getBasebandVersion", e);
             }
         }
     }
 
     @Override
     public void setMute(boolean enableMute, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SET_MUTE, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SET_MUTE, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " enableMute = " + enableMute);
             }
 
             try {
-                voiceProxy.setMute(rr.mSerial, enableMute);
+                radioProxy.setMute(rr.mSerial, enableMute);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "setMute", e);
+                handleRadioProxyExceptionForRR(rr, "setMute", e);
             }
         }
     }
 
     @Override
     public void getMute(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_GET_MUTE, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_GET_MUTE, result,
+                    mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.getMute(rr.mSerial);
+                radioProxy.getMute(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getMute", e);
+                handleRadioProxyExceptionForRR(rr, "getMute", e);
             }
         }
     }
 
     @Override
     public void queryCLIP(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CLIP, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_CLIP, result,
+                    mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.getClip(rr.mSerial);
+                radioProxy.getClip(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getClip", e);
+                handleRadioProxyExceptionForRR(rr, "queryCLIP", e);
             }
         }
     }
@@ -2649,19 +2979,23 @@
 
     @Override
     public void getDataCallList(Message result) {
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (!dataProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_DATA_CALL_LIST, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                dataProxy.getDataCallList(rr.mSerial);
+                if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                    android.hardware.radio.V1_6.IRadio radioProxy16 =
+                            (android.hardware.radio.V1_6.IRadio) radioProxy;
+                    radioProxy16.getDataCallList_1_6(rr.mSerial);
+                } else {
+                    radioProxy.getDataCallList(rr.mSerial);
+                }
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "getDataCallList", e);
+                handleRadioProxyExceptionForRR(rr, "getDataCallList", e);
             }
         }
     }
@@ -2679,225 +3013,409 @@
 
     @Override
     public void setSuppServiceNotifications(boolean enable, Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " enable = " + enable);
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " enable = "
+                        + enable);
             }
 
             try {
-                networkProxy.setSuppServiceNotifications(rr.mSerial, enable);
+                radioProxy.setSuppServiceNotifications(rr.mSerial, enable);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setSuppServiceNotifications", e);
+                handleRadioProxyExceptionForRR(rr, "setSuppServiceNotifications", e);
             }
         }
     }
 
     @Override
     public void writeSmsToSim(int status, String smsc, String pdu, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        status = translateStatus(status);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_WRITE_SMS_TO_SIM, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGV) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> "
+                        + requestToString(rr.mRequest)
                         + " " + status);
             }
 
+            SmsWriteArgs args = new SmsWriteArgs();
+            args.status = status;
+            args.smsc = convertNullToEmptyString(smsc);
+            args.pdu = convertNullToEmptyString(pdu);
+
             try {
-                messagingProxy.writeSmsToSim(rr.mSerial, status,
-                        RILUtils.convertNullToEmptyString(smsc),
-                        RILUtils.convertNullToEmptyString(pdu));
+                radioProxy.writeSmsToSim(rr.mSerial, args);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "writeSmsToSim", e);
+                handleRadioProxyExceptionForRR(rr, "writeSmsToSim", e);
             }
         }
     }
 
     @Override
     public void deleteSmsOnSim(int index, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_DELETE_SMS_ON_SIM, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGV) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " index = " + index);
+                riljLog(rr.serialString() + "> "
+                        + requestToString(rr.mRequest) + " index = " + index);
             }
 
             try {
-                messagingProxy.deleteSmsOnSim(rr.mSerial, index);
+                radioProxy.deleteSmsOnSim(rr.mSerial, index);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "deleteSmsOnSim", e);
+                handleRadioProxyExceptionForRR(rr, "deleteSmsOnSim", e);
             }
         }
     }
 
     @Override
     public void setBandMode(int bandMode, Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SET_BAND_MODE, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SET_BAND_MODE, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " bandMode = " + bandMode);
             }
 
             try {
-                networkProxy.setBandMode(rr.mSerial, bandMode);
+                radioProxy.setBandMode(rr.mSerial, bandMode);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setBandMode", e);
+                handleRadioProxyExceptionForRR(rr, "setBandMode", e);
             }
         }
     }
 
     @Override
     public void queryAvailableBandMode(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                networkProxy.getAvailableBandModes(rr.mSerial);
+                radioProxy.getAvailableBandModes(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "queryAvailableBandMode", e);
+                handleRadioProxyExceptionForRR(rr, "queryAvailableBandMode", e);
             }
         }
     }
 
     @Override
     public void sendEnvelope(String contents, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " contents = " + contents);
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " contents = "
+                        + contents);
             }
 
             try {
-                simProxy.sendEnvelope(rr.mSerial, RILUtils.convertNullToEmptyString(contents));
+                radioProxy.sendEnvelope(rr.mSerial, convertNullToEmptyString(contents));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "sendEnvelope", e);
+                handleRadioProxyExceptionForRR(rr, "sendEnvelope", e);
             }
         }
     }
 
     @Override
     public void sendTerminalResponse(String contents, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " contents = " + (TelephonyUtils.IS_DEBUGGABLE
-                        ? contents : RILUtils.convertToCensoredTerminalResponse(contents)));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " contents = "
+                        + (TelephonyUtils.IS_DEBUGGABLE
+                            ? contents : censoredTerminalResponse(contents)));
             }
 
             try {
-                simProxy.sendTerminalResponseToSim(rr.mSerial,
-                        RILUtils.convertNullToEmptyString(contents));
+                radioProxy.sendTerminalResponseToSim(rr.mSerial,
+                        convertNullToEmptyString(contents));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "sendTerminalResponse", e);
+                handleRadioProxyExceptionForRR(rr, "sendTerminalResponse", e);
             }
         }
     }
 
+    private String censoredTerminalResponse(String terminalResponse) {
+        try {
+            byte[] bytes = IccUtils.hexStringToBytes(terminalResponse);
+            if (bytes != null) {
+                List<ComprehensionTlv> ctlvs = ComprehensionTlv.decodeMany(bytes, 0);
+                int from = 0;
+                for (ComprehensionTlv ctlv : ctlvs) {
+                    // Find text strings which might be personal information input by user,
+                    // then replace it with "********".
+                    if (ComprehensionTlvTag.TEXT_STRING.value() == ctlv.getTag()) {
+                        byte[] target = Arrays.copyOfRange(ctlv.getRawValue(), from,
+                                ctlv.getValueIndex() + ctlv.getLength());
+                        terminalResponse = terminalResponse.toLowerCase().replace(
+                                IccUtils.bytesToHexString(target).toLowerCase(), "********");
+                    }
+                    // The text string tag and the length field should also be hidden.
+                    from = ctlv.getValueIndex() + ctlv.getLength();
+                }
+            }
+        } catch (Exception e) {
+            Rlog.e(RILJ_LOG_TAG, "Could not censor the terminal response: " + e);
+            terminalResponse = null;
+        }
+
+        return terminalResponse;
+    }
+
     @Override
     public void sendEnvelopeWithStatus(String contents, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " contents = " + contents);
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " contents = "
+                        + contents);
             }
 
             try {
-                simProxy.sendEnvelopeWithStatus(rr.mSerial,
-                        RILUtils.convertNullToEmptyString(contents));
+                radioProxy.sendEnvelopeWithStatus(rr.mSerial, convertNullToEmptyString(contents));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "sendEnvelopeWithStatus", e);
+                handleRadioProxyExceptionForRR(rr, "sendEnvelopeWithStatus", e);
             }
         }
     }
 
     @Override
     public void explicitCallTransfer(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_EXPLICIT_CALL_TRANSFER, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.explicitCallTransfer(rr.mSerial);
+                radioProxy.explicitCallTransfer(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "explicitCallTransfer", e);
+                handleRadioProxyExceptionForRR(rr, "explicitCallTransfer", e);
             }
         }
     }
 
     @Override
     public void setPreferredNetworkType(@PrefNetworkMode int networkType , Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " networkType = " + networkType);
             }
             mAllowedNetworkTypesBitmask = RadioAccessFamily.getRafFromNetworkType(networkType);
             mMetrics.writeSetPreferredNetworkType(mPhoneId, networkType);
 
-            try {
-                networkProxy.setPreferredNetworkTypeBitmap(rr.mSerial, mAllowedNetworkTypesBitmask);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setPreferredNetworkType", e);
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
+                android.hardware.radio.V1_4.IRadio radioProxy14 =
+                        (android.hardware.radio.V1_4.IRadio) radioProxy;
+                try {
+                    radioProxy14.setPreferredNetworkTypeBitmap(
+                            rr.mSerial, convertToHalRadioAccessFamily(mAllowedNetworkTypesBitmask));
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setPreferredNetworkTypeBitmap", e);
+                }
+            } else {
+                try {
+                    radioProxy.setPreferredNetworkType(rr.mSerial, networkType);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setPreferredNetworkType", e);
+                }
             }
         }
     }
 
+    /**
+     * convert RAF from {@link android.hardware.radio.V1_0.RadioAccessFamily} to
+     * {@link TelephonyManager.NetworkTypeBitMask}, the bitmask represented by
+     * {@link android.telephony.Annotation.NetworkType}.
+     *
+     * @param raf {@link android.hardware.radio.V1_0.RadioAccessFamily}
+     * @return {@link TelephonyManager.NetworkTypeBitMask}
+     */
+    @TelephonyManager.NetworkTypeBitMask
+    public static int convertToNetworkTypeBitMask(int raf) {
+        int networkTypeRaf = 0;
+
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GSM) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GSM;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GPRS) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GPRS;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EDGE) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EDGE;
+        }
+        // convert both IS95A/IS95B to CDMA as network mode doesn't support CDMA
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95A) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95B) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.ONE_X_RTT) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_0) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_A) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_B) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EHRPD) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSUPA) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSDPA) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPA) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPA;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPAP) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.UMTS) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_UMTS;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.TD_SCDMA) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE;
+        }
+        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE_CA) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA;
+        }
+        if ((raf & android.hardware.radio.V1_4.RadioAccessFamily.NR) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_NR;
+        }
+        // TODO: need hal definition
+        if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) != 0) {
+            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN;
+        }
+        return (networkTypeRaf == 0) ? TelephonyManager.NETWORK_TYPE_UNKNOWN : networkTypeRaf;
+    }
+
+    // convert to android.hardware.radio.V1_0.RadioAccessFamily
+    private static int convertToHalRadioAccessFamily(
+            @TelephonyManager.NetworkTypeBitMask int networkTypeBitmask) {
+        int raf = 0;
+
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_GSM) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.GSM;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_GPRS) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.GPRS;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EDGE) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EDGE;
+        }
+        // convert CDMA to IS95A, consistent with ServiceState.networkTypeToRilRadioTechnology
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_CDMA) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.IS95A;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.ONE_X_RTT;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EVDO_0;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EVDO_A;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EVDO_B;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EHRPD;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSUPA;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSDPA;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSPA) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSPA;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSPAP;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_UMTS) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.UMTS;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.TD_SCDMA;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_LTE) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.LTE;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA) != 0) {
+            raf |= android.hardware.radio.V1_0.RadioAccessFamily.LTE_CA;
+        }
+        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_NR) != 0) {
+            raf |= android.hardware.radio.V1_4.RadioAccessFamily.NR;
+        }
+        // TODO: need hal definition for IWLAN
+        return (raf == 0) ? android.hardware.radio.V1_4.RadioAccessFamily.UNKNOWN : raf;
+    }
+
     @Override
     public void getPreferredNetworkType(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE, result,
                     mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
-
-            try {
-                networkProxy.getAllowedNetworkTypesBitmap(rr.mSerial);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getPreferredNetworkType", e);
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
+                android.hardware.radio.V1_4.IRadio radioProxy14 =
+                        (android.hardware.radio.V1_4.IRadio) radioProxy;
+                try {
+                    radioProxy14.getPreferredNetworkTypeBitmap(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "getPreferredNetworkTypeBitmap", e);
+                }
+            } else {
+                try {
+                    radioProxy.getPreferredNetworkType(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "getPreferredNetworkType", e);
+                }
             }
         }
     }
@@ -2905,65 +3423,76 @@
     @Override
     public void setAllowedNetworkTypesBitmap(
             @TelephonyManager.NetworkTypeBitMask int networkTypeBitmask, Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             if (mRadioVersion.less(RADIO_HAL_VERSION_1_6)) {
                 // For older HAL, redirects the call to setPreferredNetworkType.
                 setPreferredNetworkType(
                         RadioAccessFamily.getNetworkTypeFromRaf(networkTypeBitmask), result);
                 return;
             }
+
+            android.hardware.radio.V1_6.IRadio radioProxy16 =
+                    (android.hardware.radio.V1_6.IRadio) radioProxy;
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_ALLOWED_NETWORK_TYPES_BITMAP, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
             mAllowedNetworkTypesBitmask = networkTypeBitmask;
-
             try {
-                networkProxy.setAllowedNetworkTypesBitmap(rr.mSerial, mAllowedNetworkTypesBitmask);
+                radioProxy16.setAllowedNetworkTypesBitmap(rr.mSerial,
+                        convertToHalRadioAccessFamily(mAllowedNetworkTypesBitmask));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setAllowedNetworkTypeBitmask", e);
+                handleRadioProxyExceptionForRR(rr, "setAllowedNetworkTypeBitmask", e);
             }
         }
     }
 
     @Override
     public void getAllowedNetworkTypesBitmap(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            if (mRadioVersion.less(RADIO_HAL_VERSION_1_6)) {
+                // For older HAL, redirects the call to getPreferredNetworkType.
+                getPreferredNetworkType(result);
+                return;
+            }
+
+            android.hardware.radio.V1_6.IRadio radioProxy16 =
+                    (android.hardware.radio.V1_6.IRadio) radioProxy;
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
             try {
-                networkProxy.getAllowedNetworkTypesBitmap(rr.mSerial);
+                radioProxy16.getAllowedNetworkTypesBitmap(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getAllowedNetworkTypeBitmask", e);
+                handleRadioProxyExceptionForRR(rr, "getAllowedNetworkTypeBitmask", e);
             }
         }
     }
 
     @Override
     public void setLocationUpdates(boolean enable, WorkSource workSource, Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_LOCATION_UPDATES, result,
-                    getDefaultWorkSourceIfInvalid(workSource));
+                    workSource == null ? mRILDefaultWorkSource : workSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " enable = " + enable);
+                riljLog(rr.serialString() + "> "
+                        + requestToString(rr.mRequest) + " enable = " + enable);
             }
 
             try {
-                networkProxy.setLocationUpdates(rr.mSerial, enable);
+                radioProxy.setLocationUpdates(rr.mSerial, enable);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setLocationUpdates", e);
+                handleRadioProxyExceptionForRR(rr, "setLocationUpdates", e);
             }
         }
     }
@@ -2973,29 +3502,32 @@
      */
     @Override
     public void isNrDualConnectivityEnabled(Message result, WorkSource workSource) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            if (mRadioVersion.less(RADIO_HAL_VERSION_1_6)) {
+                if (result != null) {
+                    AsyncResult.forMessage(result, null,
+                            CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                    result.sendToTarget();
+                }
+                return;
+            }
+
+            android.hardware.radio.V1_6.IRadio radioProxy16 =
+                    (android.hardware.radio.V1_6.IRadio) radioProxy;
+
             RILRequest rr = obtainRequest(RIL_REQUEST_IS_NR_DUAL_CONNECTIVITY_ENABLED, result,
-                    getDefaultWorkSourceIfInvalid(workSource));
+                    workSource == null ? mRILDefaultWorkSource : workSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> "
+                        + requestToString(rr.mRequest));
             }
 
             try {
-                networkProxy.isNrDualConnectivityEnabled(rr.mSerial);
+                radioProxy16.isNrDualConnectivityEnabled(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "isNrDualConnectivityEnabled", e);
-            }
-        } else {
-            if (RILJ_LOGD) {
-                Rlog.d(RILJ_LOG_TAG, "isNrDualConnectivityEnabled: REQUEST_NOT_SUPPORTED");
-            }
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
+                handleRadioProxyExceptionForRR(rr, "isNRDualConnectivityEnabled", e);
             }
         }
     }
@@ -3012,1276 +3544,1373 @@
      * </ol>
      */
     @Override
-    public void setNrDualConnectivityState(int nrDualConnectivityState, Message result,
-            WorkSource workSource) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+    public void setNrDualConnectivityState(int nrDualConnectivityState,
+            Message result, WorkSource workSource) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            if (mRadioVersion.less(RADIO_HAL_VERSION_1_6)) {
+                if (result != null) {
+                    AsyncResult.forMessage(result, null,
+                            CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                    result.sendToTarget();
+                }
+                return;
+            }
+
+            android.hardware.radio.V1_6.IRadio radioProxy16 =
+                    (android.hardware.radio.V1_6.IRadio) radioProxy;
             RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_NR_DUAL_CONNECTIVITY, result,
-                    getDefaultWorkSourceIfInvalid(workSource));
+                    workSource == null ? mRILDefaultWorkSource : workSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " enable = " + nrDualConnectivityState);
+                riljLog(rr.serialString() + "> "
+                        + requestToString(rr.mRequest) + " enable = " + nrDualConnectivityState);
             }
 
             try {
-                networkProxy.setNrDualConnectivityState(rr.mSerial, (byte) nrDualConnectivityState);
+                radioProxy16.setNrDualConnectivityState(rr.mSerial,
+                        (byte) nrDualConnectivityState);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "enableNrDualConnectivity", e);
-            }
-        } else {
-            if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "enableNrDualConnectivity: REQUEST_NOT_SUPPORTED");
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
-            }
-        }
-    }
-
-    private void setVoNrEnabled(boolean enabled) {
-        SystemProperties.set(PROPERTY_IS_VONR_ENABLED + mPhoneId, String.valueOf(enabled));
-    }
-
-    private boolean isVoNrEnabled() {
-        return SystemProperties.getBoolean(PROPERTY_IS_VONR_ENABLED + mPhoneId, true);
-    }
-
-    /**
-     * Is voice over NR enabled
-     */
-    @Override
-    public void isVoNrEnabled(Message result, WorkSource workSource) {
-
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
-            RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-            if (!voiceProxy.isEmpty()) {
-                RILRequest rr = obtainRequest(RIL_REQUEST_IS_VONR_ENABLED , result,
-                        getDefaultWorkSourceIfInvalid(workSource));
-
-                if (RILJ_LOGD) {
-                    riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-                }
-
-                try {
-                    voiceProxy.isVoNrEnabled(rr.mSerial);
-                } catch (RemoteException | RuntimeException e) {
-                    handleRadioProxyExceptionForRR(VOICE_SERVICE, "isVoNrEnabled", e);
-                }
-            }
-        } else {
-            boolean isEnabled = isVoNrEnabled();
-            if (result != null) {
-                AsyncResult.forMessage(result, isEnabled, null);
-                result.sendToTarget();
-            }
-        }
-    }
-
-    /**
-     * Enable or disable Voice over NR (VoNR)
-     * @param enabled enable or disable VoNR.
-     */
-    @Override
-    public void setVoNrEnabled(boolean enabled, Message result, WorkSource workSource) {
-        setVoNrEnabled(enabled);
-
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
-            RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-            if (!voiceProxy.isEmpty()) {
-                RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_VONR, result,
-                        getDefaultWorkSourceIfInvalid(workSource));
-
-                if (RILJ_LOGD) {
-                    riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-                }
-
-                try {
-                    voiceProxy.setVoNrEnabled(rr.mSerial, enabled);
-                } catch (RemoteException | RuntimeException e) {
-                    handleRadioProxyExceptionForRR(VOICE_SERVICE, "setVoNrEnabled", e);
-                }
-            }
-        } else {
-            /* calling a query api to let HAL know that VoNREnabled state is updated.
-               This is a work around as new AIDL API is not allowed for older HAL version devices.
-               HAL can check the value of PROPERTY_IS_VONR_ENABLED property to determine
-               if there is any change whenever it receives isNrDualConnectivityEnabled request.
-            */
-            isNrDualConnectivityEnabled(null, workSource);
-            if (result != null) {
-                AsyncResult.forMessage(result, null, null);
-                result.sendToTarget();
+                handleRadioProxyExceptionForRR(rr, "enableNRDualConnectivity", e);
             }
         }
     }
 
     @Override
-    public void setCdmaSubscriptionSource(int cdmaSubscription, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+    public void setCdmaSubscriptionSource(int cdmaSubscription , Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " cdmaSubscription = " + cdmaSubscription);
             }
 
             try {
-                simProxy.setCdmaSubscriptionSource(rr.mSerial, cdmaSubscription);
+                radioProxy.setCdmaSubscriptionSource(rr.mSerial, cdmaSubscription);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "setCdmaSubscriptionSource", e);
+                handleRadioProxyExceptionForRR(rr, "setCdmaSubscriptionSource", e);
             }
         }
     }
 
     @Override
     public void queryCdmaRoamingPreference(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                networkProxy.getCdmaRoamingPreference(rr.mSerial);
+                radioProxy.getCdmaRoamingPreference(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "queryCdmaRoamingPreference", e);
+                handleRadioProxyExceptionForRR(rr, "queryCdmaRoamingPreference", e);
             }
         }
     }
 
     @Override
     public void setCdmaRoamingPreference(int cdmaRoamingType, Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " cdmaRoamingType = " + cdmaRoamingType);
             }
 
             try {
-                networkProxy.setCdmaRoamingPreference(rr.mSerial, cdmaRoamingType);
+                radioProxy.setCdmaRoamingPreference(rr.mSerial, cdmaRoamingType);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setCdmaRoamingPreference", e);
+                handleRadioProxyExceptionForRR(rr, "setCdmaRoamingPreference", e);
             }
         }
     }
 
     @Override
     public void queryTTYMode(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_QUERY_TTY_MODE, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.getTtyMode(rr.mSerial);
+                radioProxy.getTTYMode(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getTtyMode", e);
+                handleRadioProxyExceptionForRR(rr, "queryTTYMode", e);
             }
         }
     }
 
     @Override
     public void setTTYMode(int ttyMode, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SET_TTY_MODE, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SET_TTY_MODE, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " ttyMode = " + ttyMode);
             }
 
             try {
-                voiceProxy.setTtyMode(rr.mSerial, ttyMode);
+                radioProxy.setTTYMode(rr.mSerial, ttyMode);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "setTtyMode", e);
+                handleRadioProxyExceptionForRR(rr, "setTTYMode", e);
             }
         }
     }
 
     @Override
     public void setPreferredVoicePrivacy(boolean enable, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " enable = " + enable);
             }
 
             try {
-                voiceProxy.setPreferredVoicePrivacy(rr.mSerial, enable);
+                radioProxy.setPreferredVoicePrivacy(rr.mSerial, enable);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "setPreferredVoicePrivacy", e);
+                handleRadioProxyExceptionForRR(rr, "setPreferredVoicePrivacy", e);
             }
         }
     }
 
     @Override
     public void getPreferredVoicePrivacy(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE,
                     result, mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.getPreferredVoicePrivacy(rr.mSerial);
+                radioProxy.getPreferredVoicePrivacy(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "getPreferredVoicePrivacy", e);
+                handleRadioProxyExceptionForRR(rr, "getPreferredVoicePrivacy", e);
             }
         }
     }
 
     @Override
     public void sendCDMAFeatureCode(String featureCode, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_FLASH, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_FLASH, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " featureCode = " + Rlog.pii(RILJ_LOG_TAG, featureCode));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                        + " featureCode = " + featureCode);
             }
 
             try {
-                voiceProxy.sendCdmaFeatureCode(rr.mSerial,
-                        RILUtils.convertNullToEmptyString(featureCode));
+                radioProxy.sendCDMAFeatureCode(rr.mSerial, convertNullToEmptyString(featureCode));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "sendCdmaFeatureCode", e);
+                handleRadioProxyExceptionForRR(rr, "sendCDMAFeatureCode", e);
             }
         }
     }
 
     @Override
     public void sendBurstDtmf(String dtmfString, int on, int off, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_BURST_DTMF, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " dtmfString = " + dtmfString + " on = " + on + " off = " + off);
             }
 
             try {
-                voiceProxy.sendBurstDtmf(rr.mSerial, RILUtils.convertNullToEmptyString(dtmfString),
-                        on, off);
+                radioProxy.sendBurstDtmf(rr.mSerial, convertNullToEmptyString(dtmfString), on, off);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "sendBurstDtmf", e);
+                handleRadioProxyExceptionForRR(rr, "sendBurstDtmf", e);
+            }
+        }
+    }
+
+    private void constructCdmaSendSmsRilRequest(CdmaSmsMessage msg, byte[] pdu) {
+        int addrNbrOfDigits;
+        int subaddrNbrOfDigits;
+        int bearerDataLength;
+        ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
+        DataInputStream dis = new DataInputStream(bais);
+
+        try {
+            msg.teleserviceId = dis.readInt(); // teleServiceId
+            msg.isServicePresent = (byte) dis.readInt() == 1 ? true : false; // servicePresent
+            msg.serviceCategory = dis.readInt(); // serviceCategory
+            msg.address.digitMode = dis.read();  // address digit mode
+            msg.address.numberMode = dis.read(); // address number mode
+            msg.address.numberType = dis.read(); // address number type
+            msg.address.numberPlan = dis.read(); // address number plan
+            addrNbrOfDigits = (byte) dis.read();
+            for (int i = 0; i < addrNbrOfDigits; i++) {
+                msg.address.digits.add(dis.readByte()); // address_orig_bytes[i]
+            }
+            msg.subAddress.subaddressType = dis.read(); //subaddressType
+            msg.subAddress.odd = (byte) dis.read() == 1 ? true : false; //subaddr odd
+            subaddrNbrOfDigits = (byte) dis.read();
+            for (int i = 0; i < subaddrNbrOfDigits; i++) {
+                msg.subAddress.digits.add(dis.readByte()); //subaddr_orig_bytes[i]
+            }
+
+            bearerDataLength = dis.read();
+            for (int i = 0; i < bearerDataLength; i++) {
+                msg.bearerData.add(dis.readByte()); //bearerData[i]
+            }
+        } catch (IOException ex) {
+            if (RILJ_LOGD) {
+                riljLog("sendSmsCdma: conversion from input stream to object failed: "
+                        + ex);
             }
         }
     }
 
     @Override
     public void sendCdmaSMSExpectMore(byte[] pdu, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE, result,
                     mRILDefaultWorkSource);
 
             // Do not log function arg for privacy
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
-            try {
-                messagingProxy.sendCdmaSmsExpectMore(rr.mSerial, pdu);
-                if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+            CdmaSmsMessage msg = new CdmaSmsMessage();
+            constructCdmaSendSmsRilRequest(msg, pdu);
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                android.hardware.radio.V1_6.IRadio radioProxy16 =
+                        (android.hardware.radio.V1_6.IRadio) radioProxy;
+                try {
+                    radioProxy16.sendCdmaSmsExpectMore_1_6(rr.mSerial, msg);
                     mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_CDMA,
                             SmsSession.Event.Format.SMS_FORMAT_3GPP2,
                             getOutgoingSmsMessageId(result));
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "sendCdmaSMSExpectMore", e);
                 }
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "sendCdmaSMSExpectMore", e);
+            } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+                android.hardware.radio.V1_5.IRadio radioProxy15 =
+                        (android.hardware.radio.V1_5.IRadio) radioProxy;
+                try {
+                    radioProxy15.sendCdmaSmsExpectMore(rr.mSerial, msg);
+                    mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_CDMA,
+                            SmsSession.Event.Format.SMS_FORMAT_3GPP2,
+                            getOutgoingSmsMessageId(result));
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "sendCdmaSMSExpectMore", e);
+                }
+            } else {
+                sendCdmaSms(pdu, result);
             }
         }
     }
 
     @Override
     public void sendCdmaSms(byte[] pdu, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SEND_SMS, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SEND_SMS, result,
+                    mRILDefaultWorkSource);
 
             // Do not log function arg for privacy
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
-            try {
-                messagingProxy.sendCdmaSms(rr.mSerial, pdu);
-                mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_CDMA,
-                        SmsSession.Event.Format.SMS_FORMAT_3GPP2, getOutgoingSmsMessageId(result));
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "sendCdmaSms", e);
+            CdmaSmsMessage msg = new CdmaSmsMessage();
+            constructCdmaSendSmsRilRequest(msg, pdu);
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                try {
+                    android.hardware.radio.V1_6.IRadio radioProxy16 =
+                            (android.hardware.radio.V1_6.IRadio) radioProxy;
+                    radioProxy16.sendCdmaSms_1_6(rr.mSerial, msg);
+                    mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_CDMA,
+                            SmsSession.Event.Format.SMS_FORMAT_3GPP2,
+                            getOutgoingSmsMessageId(result));
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "sendCdmaSms", e);
+                }
+            } else {
+                try {
+                    radioProxy.sendCdmaSms(rr.mSerial, msg);
+                    mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_CDMA,
+                            SmsSession.Event.Format.SMS_FORMAT_3GPP2,
+                            getOutgoingSmsMessageId(result));
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "sendCdmaSms", e);
+                }
             }
         }
     }
 
     @Override
     public void acknowledgeLastIncomingCdmaSms(boolean success, int cause, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " success = " + success + " cause = " + cause);
             }
 
+            CdmaSmsAck msg = new CdmaSmsAck();
+            msg.errorClass = success ? 0 : 1;
+            msg.smsCauseCode = cause;
+
             try {
-                messagingProxy.acknowledgeLastIncomingCdmaSms(rr.mSerial, success, cause);
+                radioProxy.acknowledgeLastIncomingCdmaSms(rr.mSerial, msg);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE,
-                        "acknowledgeLastIncomingCdmaSms", e);
+                handleRadioProxyExceptionForRR(rr, "acknowledgeLastIncomingCdmaSms", e);
             }
         }
     }
 
     @Override
     public void getGsmBroadcastConfig(Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GSM_GET_BROADCAST_CONFIG, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                messagingProxy.getGsmBroadcastConfig(rr.mSerial);
+                radioProxy.getGsmBroadcastConfig(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "getGsmBroadcastConfig", e);
+                handleRadioProxyExceptionForRR(rr, "getGsmBroadcastConfig", e);
             }
         }
     }
 
     @Override
     public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GSM_SET_BROADCAST_CONFIG, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " with " + config.length + " configs : ");
                 for (int i = 0; i < config.length; i++) {
                     riljLog(config[i].toString());
                 }
             }
 
+            ArrayList<GsmBroadcastSmsConfigInfo> configs = new ArrayList<>();
+
+            int numOfConfig = config.length;
+            GsmBroadcastSmsConfigInfo info;
+
+            for (int i = 0; i < numOfConfig; i++) {
+                info = new GsmBroadcastSmsConfigInfo();
+                info.fromServiceId = config[i].getFromServiceId();
+                info.toServiceId = config[i].getToServiceId();
+                info.fromCodeScheme = config[i].getFromCodeScheme();
+                info.toCodeScheme = config[i].getToCodeScheme();
+                info.selected = config[i].isSelected();
+                configs.add(info);
+            }
+
             try {
-                messagingProxy.setGsmBroadcastConfig(rr.mSerial, config);
+                radioProxy.setGsmBroadcastConfig(rr.mSerial, configs);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "setGsmBroadcastConfig", e);
+                handleRadioProxyExceptionForRR(rr, "setGsmBroadcastConfig", e);
             }
         }
     }
 
     @Override
     public void setGsmBroadcastActivation(boolean activate, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GSM_BROADCAST_ACTIVATION, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " activate = " + activate);
             }
 
             try {
-                messagingProxy.setGsmBroadcastActivation(rr.mSerial, activate);
+                radioProxy.setGsmBroadcastActivation(rr.mSerial, activate);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "setGsmBroadcastActivation", e);
+                handleRadioProxyExceptionForRR(rr, "setGsmBroadcastActivation", e);
             }
         }
     }
 
     @Override
     public void getCdmaBroadcastConfig(Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                messagingProxy.getCdmaBroadcastConfig(rr.mSerial);
+                radioProxy.getCdmaBroadcastConfig(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "getCdmaBroadcastConfig", e);
+                handleRadioProxyExceptionForRR(rr, "getCdmaBroadcastConfig", e);
             }
         }
     }
 
     @Override
     public void setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG, result,
                     mRILDefaultWorkSource);
 
+            ArrayList<CdmaBroadcastSmsConfigInfo> halConfigs = new ArrayList<>();
+
+            for (CdmaSmsBroadcastConfigInfo config: configs) {
+                for (int i = config.getFromServiceCategory();
+                        i <= config.getToServiceCategory();
+                        i++) {
+                    CdmaBroadcastSmsConfigInfo info = new CdmaBroadcastSmsConfigInfo();
+                    info.serviceCategory = i;
+                    info.language = config.getLanguage();
+                    info.selected = config.isSelected();
+                    halConfigs.add(info);
+                }
+            }
+
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " with " + configs.length + " configs : ");
-                for (CdmaSmsBroadcastConfigInfo config : configs) {
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                        + " with " + halConfigs.size() + " configs : ");
+                for (CdmaBroadcastSmsConfigInfo config : halConfigs) {
                     riljLog(config.toString());
                 }
             }
 
             try {
-                messagingProxy.setCdmaBroadcastConfig(rr.mSerial, configs);
+                radioProxy.setCdmaBroadcastConfig(rr.mSerial, halConfigs);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "setCdmaBroadcastConfig", e);
+                handleRadioProxyExceptionForRR(rr, "setCdmaBroadcastConfig", e);
             }
         }
     }
 
     @Override
     public void setCdmaBroadcastActivation(boolean activate, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_BROADCAST_ACTIVATION, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " activate = " + activate);
             }
 
             try {
-                messagingProxy.setCdmaBroadcastActivation(rr.mSerial, activate);
+                radioProxy.setCdmaBroadcastActivation(rr.mSerial, activate);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "setCdmaBroadcastActivation", e);
+                handleRadioProxyExceptionForRR(rr, "setCdmaBroadcastActivation", e);
             }
         }
     }
 
     @Override
     public void getCDMASubscription(Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_SUBSCRIPTION, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                simProxy.getCdmaSubscription(rr.mSerial);
+                radioProxy.getCDMASubscription(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getCdmaSubscription", e);
+                handleRadioProxyExceptionForRR(rr, "getCDMASubscription", e);
             }
         }
     }
 
     @Override
     public void writeSmsToRuim(int status, byte[] pdu, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        status = translateStatus(status);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGV) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> "
+                        + requestToString(rr.mRequest)
                         + " status = " + status);
             }
 
+            CdmaSmsWriteArgs args = new CdmaSmsWriteArgs();
+            args.status = status;
+            constructCdmaSendSmsRilRequest(args.message, pdu);
+
             try {
-                messagingProxy.writeSmsToRuim(rr.mSerial, status, pdu);
+                radioProxy.writeSmsToRuim(rr.mSerial, args);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "writeSmsToRuim", e);
+                handleRadioProxyExceptionForRR(rr, "writeSmsToRuim", e);
             }
         }
     }
 
     @Override
     public void deleteSmsOnRuim(int index, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGV) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> "
+                        + requestToString(rr.mRequest)
                         + " index = " + index);
             }
 
             try {
-                messagingProxy.deleteSmsOnRuim(rr.mSerial, index);
+                radioProxy.deleteSmsOnRuim(rr.mSerial, index);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "deleteSmsOnRuim", e);
+                handleRadioProxyExceptionForRR(rr, "deleteSmsOnRuim", e);
             }
         }
     }
 
     @Override
     public void getDeviceIdentity(Message result) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (!modemProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_DEVICE_IDENTITY, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                modemProxy.getDeviceIdentity(rr.mSerial);
+                radioProxy.getDeviceIdentity(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getDeviceIdentity", e);
+                handleRadioProxyExceptionForRR(rr, "getDeviceIdentity", e);
             }
         }
     }
 
     @Override
     public void exitEmergencyCallbackMode(Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                voiceProxy.exitEmergencyCallbackMode(rr.mSerial);
+                radioProxy.exitEmergencyCallbackMode(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(VOICE_SERVICE, "exitEmergencyCallbackMode", e);
+                handleRadioProxyExceptionForRR(rr, "exitEmergencyCallbackMode", e);
             }
         }
     }
 
     @Override
     public void getSmscAddress(Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SMSC_ADDRESS, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                messagingProxy.getSmscAddress(rr.mSerial);
+                radioProxy.getSmscAddress(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "getSmscAddress", e);
+                handleRadioProxyExceptionForRR(rr, "getSmscAddress", e);
             }
         }
     }
 
     @Override
     public void setSmscAddress(String address, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_SMSC_ADDRESS, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " address = " + address);
             }
 
             try {
-                messagingProxy.setSmscAddress(rr.mSerial,
-                        RILUtils.convertNullToEmptyString(address));
+                radioProxy.setSmscAddress(rr.mSerial, convertNullToEmptyString(address));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "setSmscAddress", e);
+                handleRadioProxyExceptionForRR(rr, "setSmscAddress", e);
             }
         }
     }
 
     @Override
     public void reportSmsMemoryStatus(boolean available, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_REPORT_SMS_MEMORY_STATUS, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " available = " + available);
+                riljLog(rr.serialString() + "> "
+                        + requestToString(rr.mRequest) + " available = " + available);
             }
 
             try {
-                messagingProxy.reportSmsMemoryStatus(rr.mSerial, available);
+                radioProxy.reportSmsMemoryStatus(rr.mSerial, available);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "reportSmsMemoryStatus", e);
+                handleRadioProxyExceptionForRR(rr, "reportSmsMemoryStatus", e);
             }
         }
     }
 
     @Override
     public void reportStkServiceIsRunning(Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                simProxy.reportStkServiceIsRunning(rr.mSerial);
+                radioProxy.reportStkServiceIsRunning(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "reportStkServiceIsRunning", e);
+                handleRadioProxyExceptionForRR(rr, "reportStkServiceIsRunning", e);
             }
         }
     }
 
     @Override
     public void getCdmaSubscriptionSource(Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                simProxy.getCdmaSubscriptionSource(rr.mSerial);
+                radioProxy.getCdmaSubscriptionSource(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getCdmaSubscriptionSource", e);
+                handleRadioProxyExceptionForRR(rr, "getCdmaSubscriptionSource", e);
             }
         }
     }
 
     @Override
     public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " success = " + success);
             }
 
             try {
-                messagingProxy.acknowledgeIncomingGsmSmsWithPdu(rr.mSerial, success,
-                        RILUtils.convertNullToEmptyString(ackPdu));
+                radioProxy.acknowledgeIncomingGsmSmsWithPdu(rr.mSerial, success,
+                        convertNullToEmptyString(ackPdu));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE,
-                        "acknowledgeIncomingGsmSmsWithPdu", e);
+                handleRadioProxyExceptionForRR(rr, "acknowledgeIncomingGsmSmsWithPdu", e);
             }
         }
     }
 
     @Override
     public void getVoiceRadioTechnology(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_VOICE_RADIO_TECH, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                networkProxy.getVoiceRadioTechnology(rr.mSerial);
+                radioProxy.getVoiceRadioTechnology(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getVoiceRadioTechnology", e);
+                handleRadioProxyExceptionForRR(rr, "getVoiceRadioTechnology", e);
             }
         }
     }
 
     @Override
     public void getCellInfoList(Message result, WorkSource workSource) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        workSource = getDefaultWorkSourceIfInvalid(workSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_CELL_INFO_LIST, result,
-                    getDefaultWorkSourceIfInvalid(workSource));
+                    workSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
             try {
-                networkProxy.getCellInfoList(rr.mSerial);
+                if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                    android.hardware.radio.V1_6.IRadio radioProxy16 =
+                            (android.hardware.radio.V1_6.IRadio) radioProxy;
+                    radioProxy16.getCellInfoList_1_6(rr.mSerial);
+
+                } else {
+                    radioProxy.getCellInfoList(rr.mSerial);
+                }
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getCellInfoList", e);
+                handleRadioProxyExceptionForRR(rr, "getCellInfoList", e);
             }
         }
     }
 
     @Override
     public void setCellInfoListRate(int rateInMillis, Message result, WorkSource workSource) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        workSource = getDefaultWorkSourceIfInvalid(workSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE, result,
-                    getDefaultWorkSourceIfInvalid(workSource));
+                    workSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " rateInMillis = " + rateInMillis);
             }
 
             try {
-                networkProxy.setCellInfoListRate(rr.mSerial, rateInMillis);
+                radioProxy.setCellInfoListRate(rr.mSerial, rateInMillis);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setCellInfoListRate", e);
+                handleRadioProxyExceptionForRR(rr, "setCellInfoListRate", e);
             }
         }
     }
 
     @Override
     public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming, Message result) {
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (!dataProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_INITIAL_ATTACH_APN, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + dataProfile);
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + dataProfile);
             }
 
             try {
-                dataProxy.setInitialAttachApn(rr.mSerial, dataProfile, isRoaming);
+                if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+                    // v1.5
+                    android.hardware.radio.V1_5.IRadio radioProxy15 =
+                            (android.hardware.radio.V1_5.IRadio) radioProxy;
+                    radioProxy15.setInitialAttachApn_1_5(rr.mSerial,
+                            convertToHalDataProfile15(dataProfile));
+                } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
+                    // v1.4
+                    android.hardware.radio.V1_4.IRadio radioProxy14 =
+                            (android.hardware.radio.V1_4.IRadio) radioProxy;
+                    radioProxy14.setInitialAttachApn_1_4(rr.mSerial,
+                            convertToHalDataProfile14(dataProfile));
+                } else {
+                    // v1.3, v1.2, v1.1, and v1.0
+                    radioProxy.setInitialAttachApn(rr.mSerial,
+                            convertToHalDataProfile10(dataProfile), dataProfile.isPersistent(),
+                            isRoaming);
+                }
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "setInitialAttachApn", e);
+                handleRadioProxyExceptionForRR(rr, "setInitialAttachApn", e);
             }
         }
     }
 
     @Override
     public void getImsRegistrationState(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_IMS_REGISTRATION_STATE, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
             try {
-                networkProxy.getImsRegistrationState(rr.mSerial);
+                radioProxy.getImsRegistrationState(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getImsRegistrationState", e);
+                handleRadioProxyExceptionForRR(rr, "getImsRegistrationState", e);
             }
         }
     }
 
     @Override
     public void sendImsGsmSms(String smscPdu, String pdu, int retry, int messageRef,
-            Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_IMS_SEND_SMS, result, mRILDefaultWorkSource);
+                   Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_IMS_SEND_SMS, result,
+                    mRILDefaultWorkSource);
 
             // Do not log function args for privacy
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
+            ImsSmsMessage msg = new ImsSmsMessage();
+            msg.tech = RadioTechnologyFamily.THREE_GPP;
+            msg.retry = (byte) retry >= 1 ? true : false;
+            msg.messageRef = messageRef;
+
+            GsmSmsMessage gsmMsg = constructGsmSendSmsRilRequest(smscPdu, pdu);
+            msg.gsmMessage.add(gsmMsg);
             try {
-                messagingProxy.sendImsSms(rr.mSerial, smscPdu, pdu, null, retry, messageRef);
+                radioProxy.sendImsSms(rr.mSerial, msg);
                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_IMS,
                         SmsSession.Event.Format.SMS_FORMAT_3GPP, getOutgoingSmsMessageId(result));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "sendImsGsmSms", e);
+                handleRadioProxyExceptionForRR(rr, "sendImsGsmSms", e);
             }
         }
     }
 
     @Override
     public void sendImsCdmaSms(byte[] pdu, int retry, int messageRef, Message result) {
-        RadioMessagingProxy messagingProxy =
-                getRadioServiceProxy(RadioMessagingProxy.class, result);
-        if (!messagingProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_IMS_SEND_SMS, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_IMS_SEND_SMS, result,
+                    mRILDefaultWorkSource);
 
             // Do not log function args for privacy
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+            ImsSmsMessage msg = new ImsSmsMessage();
+            msg.tech = RadioTechnologyFamily.THREE_GPP2;
+            msg.retry = (byte) retry >= 1 ? true : false;
+            msg.messageRef = messageRef;
+
+            CdmaSmsMessage cdmaMsg = new CdmaSmsMessage();
+            constructCdmaSendSmsRilRequest(cdmaMsg, pdu);
+            msg.cdmaMessage.add(cdmaMsg);
 
             try {
-                messagingProxy.sendImsSms(rr.mSerial, null, null, pdu, retry, messageRef);
+                radioProxy.sendImsSms(rr.mSerial, msg);
                 mMetrics.writeRilSendSms(mPhoneId, rr.mSerial, SmsSession.Event.Tech.SMS_IMS,
                         SmsSession.Event.Format.SMS_FORMAT_3GPP2, getOutgoingSmsMessageId(result));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MESSAGING_SERVICE, "sendImsCdmaSms", e);
+                handleRadioProxyExceptionForRR(rr, "sendImsCdmaSms", e);
             }
         }
     }
 
+    private SimApdu createSimApdu(int channel, int cla, int instruction, int p1, int p2, int p3,
+                                  String data) {
+        SimApdu msg = new SimApdu();
+        msg.sessionId = channel;
+        msg.cla = cla;
+        msg.instruction = instruction;
+        msg.p1 = p1;
+        msg.p2 = p2;
+        msg.p3 = p3;
+        msg.data = convertNullToEmptyString(data);
+        return msg;
+    }
+
     @Override
-    public void iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2, int p3,
-            String data, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+    public void iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2,
+                                            int p3, String data, Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
                 if (TelephonyUtils.IS_DEBUGGABLE) {
-                    riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                             + String.format(" cla = 0x%02X ins = 0x%02X", cla, instruction)
                             + String.format(" p1 = 0x%02X p2 = 0x%02X p3 = 0x%02X", p1, p2, p3)
                             + " data = " + data);
                 } else {
-                    riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
                 }
             }
 
+            SimApdu msg = createSimApdu(0, cla, instruction, p1, p2, p3, data);
             try {
-                simProxy.iccTransmitApduBasicChannel(
-                        rr.mSerial, cla, instruction, p1, p2, p3, data);
+                radioProxy.iccTransmitApduBasicChannel(rr.mSerial, msg);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "iccTransmitApduBasicChannel", e);
+                handleRadioProxyExceptionForRR(rr, "iccTransmitApduBasicChannel", e);
             }
         }
     }
 
     @Override
     public void iccOpenLogicalChannel(String aid, int p2, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_OPEN_CHANNEL, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
                 if (TelephonyUtils.IS_DEBUGGABLE) {
-                    riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                            + " aid = " + aid + " p2 = " + p2);
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " aid = " + aid
+                            + " p2 = " + p2);
                 } else {
-                    riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
                 }
             }
 
             try {
-                simProxy.iccOpenLogicalChannel(rr.mSerial, RILUtils.convertNullToEmptyString(aid),
-                        p2);
+                radioProxy.iccOpenLogicalChannel(rr.mSerial, convertNullToEmptyString(aid), p2);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "iccOpenLogicalChannel", e);
+                handleRadioProxyExceptionForRR(rr, "iccOpenLogicalChannel", e);
             }
         }
     }
 
     @Override
     public void iccCloseLogicalChannel(int channel, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_CLOSE_CHANNEL, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " channel = " + channel);
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " channel = "
+                        + channel);
             }
 
             try {
-                simProxy.iccCloseLogicalChannel(rr.mSerial, channel);
+                radioProxy.iccCloseLogicalChannel(rr.mSerial, channel);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "iccCloseLogicalChannel", e);
+                handleRadioProxyExceptionForRR(rr, "iccCloseLogicalChannel", e);
             }
         }
     }
 
     @Override
-    public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction, int p1, int p2,
-            int p3, String data, Message result) {
+    public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
+                                              int p1, int p2, int p3, String data,
+                                              Message result) {
         if (channel <= 0) {
             throw new RuntimeException(
                     "Invalid channel in iccTransmitApduLogicalChannel: " + channel);
         }
 
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
                 if (TelephonyUtils.IS_DEBUGGABLE) {
-                    riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                             + String.format(" channel = %d", channel)
                             + String.format(" cla = 0x%02X ins = 0x%02X", cla, instruction)
                             + String.format(" p1 = 0x%02X p2 = 0x%02X p3 = 0x%02X", p1, p2, p3)
                             + " data = " + data);
                 } else {
-                    riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
                 }
             }
 
+            SimApdu msg = createSimApdu(channel, cla, instruction, p1, p2, p3, data);
+
             try {
-                simProxy.iccTransmitApduLogicalChannel(
-                        rr.mSerial, channel, cla, instruction, p1, p2, p3, data);
+                radioProxy.iccTransmitApduLogicalChannel(rr.mSerial, msg);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "iccTransmitApduLogicalChannel", e);
+                handleRadioProxyExceptionForRR(rr, "iccTransmitApduLogicalChannel", e);
             }
         }
     }
 
     @Override
     public void nvReadItem(int itemID, Message result, WorkSource workSource) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (!modemProxy.isEmpty()) {
+        workSource = getDefaultWorkSourceIfInvalid(workSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_NV_READ_ITEM, result,
-                    getDefaultWorkSourceIfInvalid(workSource));
+                    workSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " itemId = " + itemID);
             }
 
             try {
-                modemProxy.nvReadItem(rr.mSerial, itemID);
+                radioProxy.nvReadItem(rr.mSerial, itemID);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "nvReadItem", e);
+                handleRadioProxyExceptionForRR(rr, "nvReadItem", e);
             }
         }
     }
 
     @Override
     public void nvWriteItem(int itemId, String itemValue, Message result, WorkSource workSource) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (!modemProxy.isEmpty()) {
+        workSource = getDefaultWorkSourceIfInvalid(workSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_NV_WRITE_ITEM, result,
-                    getDefaultWorkSourceIfInvalid(workSource));
+                    workSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " itemId = " + itemId + " itemValue = " + itemValue);
             }
 
+            NvWriteItem item = new NvWriteItem();
+            item.itemId = itemId;
+            item.value = convertNullToEmptyString(itemValue);
+
             try {
-                modemProxy.nvWriteItem(rr.mSerial, itemId,
-                        RILUtils.convertNullToEmptyString(itemValue));
+                radioProxy.nvWriteItem(rr.mSerial, item);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "nvWriteItem", e);
+                handleRadioProxyExceptionForRR(rr, "nvWriteItem", e);
             }
         }
     }
 
     @Override
     public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message result) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (!modemProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_NV_WRITE_CDMA_PRL, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " PreferredRoamingList = 0x"
                         + IccUtils.bytesToHexString(preferredRoamingList));
             }
 
+            ArrayList<Byte> arrList = new ArrayList<>();
+            for (int i = 0; i < preferredRoamingList.length; i++) {
+                arrList.add(preferredRoamingList[i]);
+            }
+
             try {
-                modemProxy.nvWriteCdmaPrl(rr.mSerial, preferredRoamingList);
+                radioProxy.nvWriteCdmaPrl(rr.mSerial, arrList);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "nvWriteCdmaPrl", e);
+                handleRadioProxyExceptionForRR(rr, "nvWriteCdmaPrl", e);
             }
         }
     }
 
     @Override
     public void nvResetConfig(int resetType, Message result) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (!modemProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_NV_RESET_CONFIG, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " resetType = " + resetType);
             }
 
             try {
-                modemProxy.nvResetConfig(rr.mSerial, resetType);
+                radioProxy.nvResetConfig(rr.mSerial, convertToHalResetNvType(resetType));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "nvResetConfig", e);
+                handleRadioProxyExceptionForRR(rr, "nvResetConfig", e);
             }
         }
     }
 
     @Override
-    public void setUiccSubscription(int slotId, int appIndex, int subId, int subStatus,
-            Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+    public void setUiccSubscription(int slotId, int appIndex, int subId,
+                                    int subStatus, Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_UICC_SUBSCRIPTION, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " slot = " + slotId + " appIndex = " + appIndex
                         + " subId = " + subId + " subStatus = " + subStatus);
             }
 
+            SelectUiccSub info = new SelectUiccSub();
+            info.slot = slotId;
+            info.appIndex = appIndex;
+            info.subType = subId;
+            info.actStatus = subStatus;
+
             try {
-                simProxy.setUiccSubscription(rr.mSerial, slotId, appIndex, subId, subStatus);
+                radioProxy.setUiccSubscription(rr.mSerial, info);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "setUiccSubscription", e);
+                handleRadioProxyExceptionForRR(rr, "setUiccSubscription", e);
             }
         }
     }
 
-    /**
-     * Whether the device modem supports reporting the EID in either the slot or card status or
-     * through ATR.
-     * @return true if the modem supports EID.
-     */
-    @Override
-    public boolean supportsEid() {
-        // EID should be supported as long as HAL >= 1.2.
-        //  - in HAL 1.2 we have EID through ATR
-        //  - in later HAL versions we also have EID through slot / card status.
-        return mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2);
-    }
-
     @Override
     public void setDataAllowed(boolean allowed, Message result) {
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (!dataProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_ALLOW_DATA, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_ALLOW_DATA, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " allowed = " + allowed);
             }
 
             try {
-                dataProxy.setDataAllowed(rr.mSerial, allowed);
+                radioProxy.setDataAllowed(rr.mSerial, allowed);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "setDataAllowed", e);
+                handleRadioProxyExceptionForRR(rr, "setDataAllowed", e);
             }
         }
     }
 
     @Override
     public void getHardwareConfig(Message result) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (!modemProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_HARDWARE_CONFIG, result,
                     mRILDefaultWorkSource);
 
             // Do not log function args for privacy
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                modemProxy.getHardwareConfig(rr.mSerial);
+                radioProxy.getHardwareConfig(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getHardwareConfig", e);
+                handleRadioProxyExceptionForRR(rr, "getHardwareConfig", e);
             }
         }
     }
 
     @Override
     public void requestIccSimAuthentication(int authContext, String data, String aid,
-            Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
+                                            Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SIM_AUTHENTICATION, result,
                     mRILDefaultWorkSource);
 
             // Do not log function args for privacy
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                simProxy.requestIccSimAuthentication(rr.mSerial, authContext,
-                        RILUtils.convertNullToEmptyString(data),
-                        RILUtils.convertNullToEmptyString(aid));
+                radioProxy.requestIccSimAuthentication(rr.mSerial,
+                        authContext,
+                        convertNullToEmptyString(data),
+                        convertNullToEmptyString(aid));
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "requestIccSimAuthentication", e);
+                handleRadioProxyExceptionForRR(rr, "requestIccSimAuthentication", e);
             }
         }
     }
 
     @Override
     public void setDataProfile(DataProfile[] dps, boolean isRoaming, Message result) {
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (!dataProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_DATA_PROFILE, result,
                     mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " with data profiles : ");
-                for (DataProfile profile : dps) {
-                    riljLog(profile.toString());
-                }
-            }
-
             try {
-                dataProxy.setDataProfile(rr.mSerial, dps, isRoaming);
+                if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+                    // V1.5
+                    android.hardware.radio.V1_5.IRadio radioProxy15 =
+                            (android.hardware.radio.V1_5.IRadio) radioProxy;
+
+                    ArrayList<android.hardware.radio.V1_5.DataProfileInfo> dpis = new ArrayList<>();
+                    for (DataProfile dp : dps) {
+                        dpis.add(convertToHalDataProfile15(dp));
+                    }
+
+                    if (RILJ_LOGD) {
+                        riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                                + " with data profiles : ");
+                        for (DataProfile profile : dps) {
+                            riljLog(profile.toString());
+                        }
+                    }
+
+                    radioProxy15.setDataProfile_1_5(rr.mSerial, dpis);
+                } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
+                    // V1.4
+                    android.hardware.radio.V1_4.IRadio radioProxy14 =
+                            (android.hardware.radio.V1_4.IRadio) radioProxy;
+
+                    ArrayList<android.hardware.radio.V1_4.DataProfileInfo> dpis = new ArrayList<>();
+                    for (DataProfile dp : dps) {
+                        dpis.add(convertToHalDataProfile14(dp));
+                    }
+
+                    if (RILJ_LOGD) {
+                        riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                                + " with data profiles : ");
+                        for (DataProfile profile : dps) {
+                            riljLog(profile.toString());
+                        }
+                    }
+
+                    radioProxy14.setDataProfile_1_4(rr.mSerial, dpis);
+                } else {
+                    // V1.0, 1.1, 1,2 and 1.3
+                    ArrayList<android.hardware.radio.V1_0.DataProfileInfo> dpis = new ArrayList<>();
+                    for (DataProfile dp : dps) {
+                        // For v1.0 to v1.2, we only send data profiles that has the persistent
+                        // (a.k.a modem cognitive) bit set to true.
+                        if (dp.isPersistent()) {
+                            dpis.add(convertToHalDataProfile10(dp));
+                        }
+                    }
+
+                    if (!dpis.isEmpty()) {
+                        if (RILJ_LOGD) {
+                            riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
+                                    + " with data profiles : ");
+                            for (DataProfile profile : dps) {
+                                riljLog(profile.toString());
+                            }
+                        }
+
+                        radioProxy.setDataProfile(rr.mSerial, dpis, isRoaming);
+                    }
+                }
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "setDataProfile", e);
+                handleRadioProxyExceptionForRR(rr, "setDataProfile", e);
             }
         }
     }
 
     @Override
     public void requestShutdown(Message result) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (!modemProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SHUTDOWN, result, mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SHUTDOWN, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
             try {
-                modemProxy.requestShutdown(rr.mSerial);
+                radioProxy.requestShutdown(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "requestShutdown", e);
+                handleRadioProxyExceptionForRR(rr, "requestShutdown", e);
             }
         }
     }
 
     @Override
-    public void getRadioCapability(Message result) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (!modemProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_GET_RADIO_CAPABILITY, result,
+    public void getRadioCapability(Message response) {
+        IRadio radioProxy = getRadioProxy(response);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_GET_RADIO_CAPABILITY, response,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
             try {
-                modemProxy.getRadioCapability(rr.mSerial);
+                radioProxy.getRadioCapability(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getRadioCapability", e);
+                handleRadioProxyExceptionForRR(rr, "getRadioCapability", e);
             }
         }
     }
 
     @Override
-    public void setRadioCapability(RadioCapability rc, Message result) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (!modemProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SET_RADIO_CAPABILITY, result,
+    public void setRadioCapability(RadioCapability rc, Message response) {
+        IRadio radioProxy = getRadioProxy(response);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SET_RADIO_CAPABILITY, response,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " RadioCapability = " + rc.toString());
             }
 
+            android.hardware.radio.V1_0.RadioCapability halRc =
+                    new android.hardware.radio.V1_0.RadioCapability();
+
+            halRc.session = rc.getSession();
+            halRc.phase = rc.getPhase();
+            halRc.raf = rc.getRadioAccessFamily();
+            halRc.logicalModemUuid = convertNullToEmptyString(rc.getLogicalModemUuid());
+            halRc.status = rc.getStatus();
+
             try {
-                modemProxy.setRadioCapability(rr.mSerial, rc);
+                radioProxy.setRadioCapability(rr.mSerial, halRc);
             } catch (Exception e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "setRadioCapability", e);
+                handleRadioProxyExceptionForRR(rr, "setRadioCapability", e);
             }
         }
     }
 
     @Override
     public void startLceService(int reportIntervalMs, boolean pullMode, Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+
         if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
             // We have a 1.2 or later radio, so the LCE 1.0 LCE service control path is unused.
             // Instead the LCE functionality is always-on and provides unsolicited indications.
-            if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "startLceService: REQUEST_NOT_SUPPORTED");
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
-            }
             return;
         }
 
-        IRadio radioProxy = getRadioProxy(result);
         if (radioProxy != null) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_START_LCE, result, mRILDefaultWorkSource);
+            RILRequest rr = obtainRequest(RIL_REQUEST_START_LCE, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " reportIntervalMs = " + reportIntervalMs + " pullMode = " + pullMode);
             }
 
             try {
                 radioProxy.startLceService(rr.mSerial, reportIntervalMs, pullMode);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(RADIO_SERVICE, "startLceService", e);
+                handleRadioProxyExceptionForRR(rr, "startLceService", e);
             }
         }
     }
 
     @Override
     public void stopLceService(Message result) {
+        IRadio radioProxy = getRadioProxy(result);
         if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
             // We have a 1.2 or later radio, so the LCE 1.0 LCE service control is unused.
             // Instead the LCE functionality is always-on and provides unsolicited indications.
-            if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "stopLceService: REQUEST_NOT_SUPPORTED");
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
-            }
             return;
         }
 
-        IRadio radioProxy = getRadioProxy(result);
         if (radioProxy != null) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_STOP_LCE, result, mRILDefaultWorkSource);
+            RILRequest rr = obtainRequest(RIL_REQUEST_STOP_LCE, result,
+                    mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
             try {
                 radioProxy.stopLceService(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(RADIO_SERVICE, "stopLceService", e);
+                handleRadioProxyExceptionForRR(rr, "stopLceService", e);
             }
         }
     }
@@ -4298,31 +4927,34 @@
     @Override
     public void setDataThrottling(Message result, WorkSource workSource, int dataThrottlingAction,
             long completionWindowMillis) {
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (dataProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            if (mRadioVersion.less(RADIO_HAL_VERSION_1_6)) {
+                if (result != null) {
+                    AsyncResult.forMessage(result, null,
+                            CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                    result.sendToTarget();
+                }
+                return;
+            }
+
+            android.hardware.radio.V1_6.IRadio radioProxy16 =
+                    (android.hardware.radio.V1_6.IRadio) radioProxy;
             RILRequest rr = obtainRequest(RIL_REQUEST_SET_DATA_THROTTLING, result,
-                    getDefaultWorkSourceIfInvalid(workSource));
+                    workSource == null ? mRILDefaultWorkSource : workSource);
 
             if (RILJ_LOGD) {
                 riljLog(rr.serialString() + "> "
-                        + RILUtils.requestToString(rr.mRequest)
+                        + requestToString(rr.mRequest)
                         + " dataThrottlingAction = " + dataThrottlingAction
                         + " completionWindowMillis " + completionWindowMillis);
             }
 
             try {
-                dataProxy.setDataThrottling(rr.mSerial, (byte) dataThrottlingAction,
+                radioProxy16.setDataThrottling(rr.mSerial, (byte) dataThrottlingAction,
                         completionWindowMillis);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "setDataThrottling", e);
-            }
-        } else {
-            if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "setDataThrottling: REQUEST_NOT_SUPPORTED");
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
+                handleRadioProxyExceptionForRR(rr, "setDataThrottling", e);
             }
         }
     }
@@ -4339,11 +4971,541 @@
      */
     @Deprecated
     @Override
-    public void pullLceData(Message result) {
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
-            // We have a 1.2 or later radio, so the LCE 1.0 LCE service control path is unused.
-            // Instead the LCE functionality is always-on and provides unsolicited indications.
-            if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "pullLceData: REQUEST_NOT_SUPPORTED");
+    public void pullLceData(Message response) {
+        IRadio radioProxy = getRadioProxy(response);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_PULL_LCEDATA, response,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+            }
+
+            try {
+                radioProxy.pullLceData(rr.mSerial);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "pullLceData", e);
+            }
+        }
+    }
+
+    @Override
+    public void getModemActivityInfo(Message result, WorkSource workSource) {
+        workSource = getDefaultWorkSourceIfInvalid(workSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_GET_ACTIVITY_INFO, result,
+                    workSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+            }
+
+            try {
+                radioProxy.getModemActivityInfo(rr.mSerial);
+
+                Message msg = mRilHandler.obtainMessage(EVENT_BLOCKING_RESPONSE_TIMEOUT);
+                msg.obj = null;
+                msg.arg1 = rr.mSerial;
+                mRilHandler.sendMessageDelayed(msg, DEFAULT_BLOCKING_MESSAGE_RESPONSE_TIMEOUT_MS);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "getModemActivityInfo", e);
+            }
+        }
+
+
+    }
+
+    /**
+     * Convert a list of CarrierIdentifier into a list of Carrier defined in 1.0/types.hal.
+     * @param carriers List of CarrierIdentifier
+     * @return List of converted objects
+     */
+    @VisibleForTesting
+    public static ArrayList<Carrier> createCarrierRestrictionList(
+            List<CarrierIdentifier> carriers) {
+        ArrayList<Carrier> result = new ArrayList<>();
+        for (CarrierIdentifier ci : carriers) {
+            Carrier c = new Carrier();
+            c.mcc = convertNullToEmptyString(ci.getMcc());
+            c.mnc = convertNullToEmptyString(ci.getMnc());
+            int matchType = CarrierIdentifier.MatchType.ALL;
+            String matchData = null;
+            if (!TextUtils.isEmpty(ci.getSpn())) {
+                matchType = CarrierIdentifier.MatchType.SPN;
+                matchData = ci.getSpn();
+            } else if (!TextUtils.isEmpty(ci.getImsi())) {
+                matchType = CarrierIdentifier.MatchType.IMSI_PREFIX;
+                matchData = ci.getImsi();
+            } else if (!TextUtils.isEmpty(ci.getGid1())) {
+                matchType = CarrierIdentifier.MatchType.GID1;
+                matchData = ci.getGid1();
+            } else if (!TextUtils.isEmpty(ci.getGid2())) {
+                matchType = CarrierIdentifier.MatchType.GID2;
+                matchData = ci.getGid2();
+            }
+            c.matchType = matchType;
+            c.matchData = convertNullToEmptyString(matchData);
+            result.add(c);
+        }
+        return result;
+    }
+
+    @Override
+    public void setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules,
+            Message result, WorkSource workSource) {
+        riljLog("RIL.java - setAllowedCarriers");
+
+        checkNotNull(carrierRestrictionRules, "Carrier restriction cannot be null.");
+        workSource = getDefaultWorkSourceIfInvalid(workSource);
+
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy == null) return;
+
+        RILRequest rr = obtainRequest(RIL_REQUEST_SET_ALLOWED_CARRIERS, result, workSource);
+
+        if (RILJ_LOGD) {
+            riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " params: "
+                    + carrierRestrictionRules);
+        }
+
+        // Extract multisim policy
+        int policy = SimLockMultiSimPolicy.NO_MULTISIM_POLICY;
+        switch (carrierRestrictionRules.getMultiSimPolicy()) {
+            case CarrierRestrictionRules.MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT:
+                policy = SimLockMultiSimPolicy.ONE_VALID_SIM_MUST_BE_PRESENT;
+                break;
+        }
+
+        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
+            riljLog("RIL.java - Using IRadio 1.4 or greater");
+
+            android.hardware.radio.V1_4.IRadio radioProxy14 =
+                    (android.hardware.radio.V1_4.IRadio) radioProxy;
+
+            // Prepare structure with allowed list, excluded list and priority
+            CarrierRestrictionsWithPriority carrierRestrictions =
+                    new CarrierRestrictionsWithPriority();
+            carrierRestrictions.allowedCarriers =
+                    createCarrierRestrictionList(carrierRestrictionRules.getAllowedCarriers());
+            carrierRestrictions.excludedCarriers =
+                    createCarrierRestrictionList(carrierRestrictionRules.getExcludedCarriers());
+            carrierRestrictions.allowedCarriersPrioritized =
+                    (carrierRestrictionRules.getDefaultCarrierRestriction()
+                        == CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED);
+
+            try {
+                radioProxy14.setAllowedCarriers_1_4(rr.mSerial, carrierRestrictions, policy);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "setAllowedCarriers_1_4", e);
+            }
+        } else {
+            boolean isAllCarriersAllowed = carrierRestrictionRules.isAllCarriersAllowed();
+
+            boolean supported = (isAllCarriersAllowed
+                    || (carrierRestrictionRules.getExcludedCarriers().isEmpty()
+                        && (carrierRestrictionRules.getDefaultCarrierRestriction()
+                            == CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED)));
+            supported = supported && (policy == SimLockMultiSimPolicy.NO_MULTISIM_POLICY);
+
+            if (!supported) {
+                // Feature is not supported by IRadio interface
+                riljLoge("setAllowedCarriers does not support excluded list on IRadio version"
+                        + " less than 1.4");
+                if (result != null) {
+                    AsyncResult.forMessage(result, null,
+                            CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                    result.sendToTarget();
+                }
+                return;
+            }
+            riljLog("RIL.java - Using IRadio 1.3 or lower");
+
+            // Prepare structure with allowed list
+            CarrierRestrictions carrierRestrictions = new CarrierRestrictions();
+            carrierRestrictions.allowedCarriers =
+                    createCarrierRestrictionList(carrierRestrictionRules.getAllowedCarriers());
+
+            try {
+                radioProxy.setAllowedCarriers(rr.mSerial, isAllCarriersAllowed,
+                        carrierRestrictions);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "setAllowedCarriers", e);
+            }
+        }
+    }
+
+    @Override
+    public void getAllowedCarriers(Message result, WorkSource workSource) {
+        workSource = getDefaultWorkSourceIfInvalid(workSource);
+
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy == null) return;
+
+        RILRequest rr = obtainRequest(RIL_REQUEST_GET_ALLOWED_CARRIERS, result,
+                workSource);
+
+        if (RILJ_LOGD) {
+            riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+        }
+
+        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_4)) {
+            riljLog("RIL.java - Using IRadio 1.4 or greater");
+
+            android.hardware.radio.V1_4.IRadio radioProxy14 =
+                    (android.hardware.radio.V1_4.IRadio) radioProxy;
+
+            try {
+                radioProxy14.getAllowedCarriers_1_4(rr.mSerial);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "getAllowedCarriers_1_4", e);
+            }
+        } else {
+            riljLog("RIL.java - Using IRadio 1.3 or lower");
+
+            try {
+                radioProxy.getAllowedCarriers(rr.mSerial);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "getAllowedCarriers", e);
+            }
+        }
+    }
+
+    @Override
+    public void sendDeviceState(int stateType, boolean state,
+                                Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SEND_DEVICE_STATE, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " "
+                        + stateType + ":" + state);
+            }
+
+            try {
+                radioProxy.sendDeviceState(rr.mSerial, stateType, state);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "sendDeviceState", e);
+            }
+        }
+    }
+
+    @Override
+    public void setUnsolResponseFilter(int filter, Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + filter);
+            }
+
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+                try {
+                    android.hardware.radio.V1_5.IRadio radioProxy15 =
+                            (android.hardware.radio.V1_5.IRadio) radioProxy;
+
+                    filter &= INDICATION_FILTERS_ALL_V1_5;
+                    radioProxy15.setIndicationFilter_1_5(rr.mSerial, filter);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setIndicationFilter_1_5", e);
+                }
+            } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
+                try {
+                    android.hardware.radio.V1_2.IRadio radioProxy12 =
+                            (android.hardware.radio.V1_2.IRadio) radioProxy;
+
+                    filter &= INDICATION_FILTERS_ALL_V1_2;
+                    radioProxy12.setIndicationFilter_1_2(rr.mSerial, filter);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setIndicationFilter_1_2", e);
+                }
+            } else {
+                try {
+                    filter &= INDICATION_FILTERS_ALL_V1_0;
+                    radioProxy.setIndicationFilter(rr.mSerial, filter);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setIndicationFilter", e);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setSignalStrengthReportingCriteria(SignalThresholdInfo signalThresholdInfo,
+            int ran, Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            if (mRadioVersion.less(RADIO_HAL_VERSION_1_2)) {
+                riljLoge("setSignalStrengthReportingCriteria ignored on IRadio version less "
+                        + "than 1.2");
+                return;
+            }
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)
+                    && mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
+                RILRequest rr = obtainRequest(RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA,
+                        result, mRILDefaultWorkSource);
+                if (RILJ_LOGD) {
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+                }
+                try {
+                    android.hardware.radio.V1_2.IRadio radioProxy12 =
+                        (android.hardware.radio.V1_2.IRadio) radioProxy;
+                    radioProxy12.setSignalStrengthReportingCriteria(rr.mSerial,
+                            signalThresholdInfo.getHysteresisMs(),
+                            signalThresholdInfo.getHysteresisDb(),
+                            primitiveArrayToArrayList(signalThresholdInfo.getThresholds()),
+                            convertAntToHalAnt(ran));
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setSignalStrengthReportingCriteria", e);
+                }
+            }
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+                RILRequest rr = obtainRequest(RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA,
+                        result, mRILDefaultWorkSource);
+                if (RILJ_LOGD) {
+                    riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+                }
+                try {
+                    android.hardware.radio.V1_5.IRadio radioProxy15 =
+                            (android.hardware.radio.V1_5.IRadio) radioProxy;
+                    radioProxy15.setSignalStrengthReportingCriteria_1_5(rr.mSerial,
+                            convertToHalSignalThresholdInfo(signalThresholdInfo),
+                            convertAntToHalAnt(ran));
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(
+                            rr, "setSignalStrengthReportingCriteria_1_5", e);
+                }
+            }
+        }
+    }
+
+    private static android.hardware.radio.V1_5.SignalThresholdInfo convertToHalSignalThresholdInfo(
+            SignalThresholdInfo signalThresholdInfo) {
+        android.hardware.radio.V1_5.SignalThresholdInfo signalThresholdInfoHal =
+                new android.hardware.radio.V1_5.SignalThresholdInfo();
+        signalThresholdInfoHal.signalMeasurement = signalThresholdInfo.getSignalMeasurementType();
+        signalThresholdInfoHal.hysteresisMs = signalThresholdInfo.getHysteresisMs();
+        signalThresholdInfoHal.hysteresisDb = signalThresholdInfo.getHysteresisDb();
+        signalThresholdInfoHal.thresholds = primitiveArrayToArrayList(
+                signalThresholdInfo.getThresholds());
+        signalThresholdInfoHal.isEnabled = signalThresholdInfo.isEnabled();
+        return signalThresholdInfoHal;
+    }
+
+    @Override
+    public void setLinkCapacityReportingCriteria(int hysteresisMs, int hysteresisDlKbps,
+            int hysteresisUlKbps, int[] thresholdsDlKbps, int[] thresholdsUlKbps, int ran,
+            Message result) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA, result,
+                    mRILDefaultWorkSource);
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+            }
+            try {
+                if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
+                    android.hardware.radio.V1_5.IRadio radioProxy15 =
+                            (android.hardware.radio.V1_5.IRadio) radioProxy;
+                    radioProxy15.setLinkCapacityReportingCriteria_1_5(rr.mSerial, hysteresisMs,
+                            hysteresisDlKbps, hysteresisUlKbps,
+                            primitiveArrayToArrayList(thresholdsDlKbps),
+                            primitiveArrayToArrayList(thresholdsUlKbps), convertAntToHalAnt(ran));
+                } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
+                    android.hardware.radio.V1_2.IRadio radioProxy12 =
+                            (android.hardware.radio.V1_2.IRadio) radioProxy;
+                    if (ran == AccessNetworkType.NGRAN) {
+                        throw new RuntimeException("NGRAN unsupported on IRadio version 1.2.");
+                    }
+                    radioProxy12.setLinkCapacityReportingCriteria(rr.mSerial, hysteresisMs,
+                            hysteresisDlKbps, hysteresisUlKbps,
+                            primitiveArrayToArrayList(thresholdsDlKbps),
+                            primitiveArrayToArrayList(thresholdsUlKbps), convertAntToHalAnt(ran));
+                } else {
+                    riljLoge("setLinkCapacityReportingCriteria ignored on IRadio version less "
+                            + "than 1.2");
+                }
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "setLinkCapacityReportingCriteria", e);
+            }
+        }
+    }
+
+    /** Converts from AccessNetworkType in frameworks to AccessNetwork in HAL. */
+    private static int convertAntToHalAnt(int radioAccessNetwork) {
+        switch (radioAccessNetwork) {
+            case AccessNetworkType.GERAN:
+                return AccessNetwork.GERAN;
+            case AccessNetworkType.UTRAN:
+                return AccessNetwork.UTRAN;
+            case AccessNetworkType.EUTRAN:
+                return AccessNetwork.EUTRAN;
+            case AccessNetworkType.CDMA2000:
+                return AccessNetwork.CDMA2000;
+            case AccessNetworkType.IWLAN:
+                return AccessNetwork.IWLAN;
+            case AccessNetworkType.NGRAN:
+                return AccessNetwork.NGRAN;
+            case AccessNetworkType.UNKNOWN:
+            default:
+                return AccessNetwork.UNKNOWN;
+        }
+    }
+
+    /** Converts from AccessNetworkType in frameworks to RadioAccessNetworks in HAL. */
+    private static int convertAntToRan(int accessNetworkType) {
+        switch (accessNetworkType) {
+            case AccessNetworkType.GERAN:
+                return RadioAccessNetworks.GERAN;
+            case AccessNetworkType.UTRAN:
+                return RadioAccessNetworks.UTRAN;
+            case AccessNetworkType.EUTRAN:
+                return RadioAccessNetworks.EUTRAN;
+            case AccessNetworkType.NGRAN:
+                return RadioAccessNetworks.NGRAN;
+            case AccessNetworkType.CDMA2000:
+                return RadioAccessNetworks.CDMA2000;
+            case AccessNetworkType.UNKNOWN:
+            default:
+                return RadioAccessNetworks.UNKNOWN;
+        }
+    }
+
+    @Override
+    public void setSimCardPower(int state, Message result, WorkSource workSource) {
+        workSource = getDefaultWorkSourceIfInvalid(workSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SET_SIM_CARD_POWER, result,
+                    workSource);
+
+            if (RILJ_LOGD) {
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + state);
+            }
+
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                try {
+                    android.hardware.radio.V1_6.IRadio radioProxy16 =
+                            (android.hardware.radio.V1_6.IRadio) radioProxy;
+                    radioProxy16.setSimCardPower_1_6(rr.mSerial, state);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setSimCardPower", e);
+                }
+            } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
+                try {
+                    android.hardware.radio.V1_1.IRadio radioProxy11 =
+                            (android.hardware.radio.V1_1.IRadio) radioProxy;
+                    radioProxy11.setSimCardPower_1_1(rr.mSerial, state);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setSimCardPower", e);
+                }
+            } else {
+                try {
+                    switch (state) {
+                        case TelephonyManager.CARD_POWER_DOWN: {
+                            radioProxy.setSimCardPower(rr.mSerial, false);
+                            break;
+                        }
+                        case TelephonyManager.CARD_POWER_UP: {
+                            radioProxy.setSimCardPower(rr.mSerial, true);
+                            break;
+                        }
+                        default: {
+                            if (result != null) {
+                                AsyncResult.forMessage(result, null,
+                                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                                result.sendToTarget();
+                            }
+                        }
+                    }
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setSimCardPower", e);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo,
+                                                Message result) {
+        checkNotNull(imsiEncryptionInfo, "ImsiEncryptionInfo cannot be null.");
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                android.hardware.radio.V1_6.IRadio radioProxy16 =
+                        (android.hardware.radio.V1_6.IRadio ) radioProxy;
+
+                RILRequest rr = obtainRequest(RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, result,
+                        mRILDefaultWorkSource);
+                if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+                try {
+                    android.hardware.radio.V1_6.ImsiEncryptionInfo halImsiInfo =
+                            new android.hardware.radio.V1_6.ImsiEncryptionInfo();
+                    halImsiInfo.base.mnc = imsiEncryptionInfo.getMnc();
+                    halImsiInfo.base.mcc = imsiEncryptionInfo.getMcc();
+                    halImsiInfo.base.keyIdentifier = imsiEncryptionInfo.getKeyIdentifier();
+                    if (imsiEncryptionInfo.getExpirationTime() != null) {
+                        halImsiInfo.base.expirationTime =
+                                imsiEncryptionInfo.getExpirationTime().getTime();
+                    }
+                    for (byte b : imsiEncryptionInfo.getPublicKey().getEncoded()) {
+                        halImsiInfo.base.carrierKey.add(new Byte(b));
+                    }
+                    halImsiInfo.keyType = (byte) imsiEncryptionInfo.getKeyType();
+
+                    radioProxy16.setCarrierInfoForImsiEncryption_1_6(
+                            rr.mSerial, halImsiInfo);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setCarrierInfoForImsiEncryption", e);
+                }
+            } else if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
+                android.hardware.radio.V1_1.IRadio radioProxy11 =
+                        (android.hardware.radio.V1_1.IRadio ) radioProxy;
+
+                RILRequest rr = obtainRequest(RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, result,
+                        mRILDefaultWorkSource);
+                if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+                try {
+                    android.hardware.radio.V1_1.ImsiEncryptionInfo halImsiInfo =
+                            new android.hardware.radio.V1_1.ImsiEncryptionInfo();
+                    halImsiInfo.mnc = imsiEncryptionInfo.getMnc();
+                    halImsiInfo.mcc = imsiEncryptionInfo.getMcc();
+                    halImsiInfo.keyIdentifier = imsiEncryptionInfo.getKeyIdentifier();
+                    if (imsiEncryptionInfo.getExpirationTime() != null) {
+                        halImsiInfo.expirationTime =
+                                imsiEncryptionInfo.getExpirationTime().getTime();
+                    }
+                    for (byte b : imsiEncryptionInfo.getPublicKey().getEncoded()) {
+                        halImsiInfo.carrierKey.add(new Byte(b));
+                    }
+
+                    radioProxy11.setCarrierInfoForImsiEncryption(
+                            rr.mSerial, halImsiInfo);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "setCarrierInfoForImsiEncryption", e);
+                }
+            } else if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                result.sendToTarget();
+            }
+        }
+    }
+
+    @Override
+    public void startNattKeepalive(
+            int contextId, KeepalivePacketData packetData, int intervalMillis, Message result) {
+        checkNotNull(packetData, "KeepaliveRequest cannot be null.");
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy == null) return;
+
+        if (mRadioVersion.less(RADIO_HAL_VERSION_1_1)) {
             if (result != null) {
                 AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
@@ -4352,280 +5514,73 @@
             return;
         }
 
-        IRadio radioProxy = getRadioProxy(result);
-        if (radioProxy != null) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_PULL_LCEDATA, result, mRILDefaultWorkSource);
+        android.hardware.radio.V1_1.IRadio radioProxy11 =
+                (android.hardware.radio.V1_1.IRadio) radioProxy;
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+        RILRequest rr = obtainRequest(
+                RIL_REQUEST_START_KEEPALIVE, result, mRILDefaultWorkSource);
 
-            try {
-                radioProxy.pullLceData(rr.mSerial);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(RADIO_SERVICE, "pullLceData", e);
-            }
-        }
-    }
+        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
-    @Override
-    public void getModemActivityInfo(Message result, WorkSource workSource) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (!modemProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_GET_ACTIVITY_INFO, result,
-                    getDefaultWorkSourceIfInvalid(workSource));
+        try {
+            android.hardware.radio.V1_1.KeepaliveRequest req =
+                    new android.hardware.radio.V1_1.KeepaliveRequest();
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            req.cid = contextId;
 
-            try {
-                modemProxy.getModemActivityInfo(rr.mSerial);
-                Message msg =
-                        mRilHandler.obtainMessage(EVENT_BLOCKING_RESPONSE_TIMEOUT, rr.mSerial);
-                mRilHandler.sendMessageDelayed(msg, DEFAULT_BLOCKING_MESSAGE_RESPONSE_TIMEOUT_MS);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "getModemActivityInfo", e);
-            }
-        }
-    }
-
-    @Override
-    public void setAllowedCarriers(CarrierRestrictionRules carrierRestrictionRules,
-            Message result, WorkSource workSource) {
-        Objects.requireNonNull(carrierRestrictionRules, "Carrier restriction cannot be null.");
-
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SET_ALLOWED_CARRIERS, result,
-                    getDefaultWorkSourceIfInvalid(workSource));
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " params: " + carrierRestrictionRules);
-            }
-
-            try {
-                simProxy.setAllowedCarriers(rr.mSerial, carrierRestrictionRules, result);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "setAllowedCarriers", e);
-            }
-        }
-    }
-
-    @Override
-    public void getAllowedCarriers(Message result, WorkSource workSource) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_GET_ALLOWED_CARRIERS, result,
-                    getDefaultWorkSourceIfInvalid(workSource));
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
-
-            try {
-                simProxy.getAllowedCarriers(rr.mSerial);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getAllowedCarriers", e);
-            }
-        }
-    }
-
-    @Override
-    public void sendDeviceState(int stateType, boolean state, Message result) {
-        RadioModemProxy modemProxy = getRadioServiceProxy(RadioModemProxy.class, result);
-        if (!modemProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SEND_DEVICE_STATE, result,
-                    mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest) + " "
-                        + stateType + ":" + state);
-            }
-
-            try {
-                modemProxy.sendDeviceState(rr.mSerial, stateType, state);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(MODEM_SERVICE, "sendDeviceState", e);
-            }
-        }
-    }
-
-    @Override
-    public void setUnsolResponseFilter(int filter, Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (!networkProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER, result,
-                    mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " " + filter);
-            }
-
-            try {
-                networkProxy.setIndicationFilter(rr.mSerial, filter);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setIndicationFilter", e);
-            }
-        }
-    }
-
-    @Override
-    public void setSignalStrengthReportingCriteria(
-            @NonNull List<SignalThresholdInfo> signalThresholdInfos, @Nullable Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA,
-                    result, mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
-
-            try {
-                networkProxy.setSignalStrengthReportingCriteria(rr.mSerial, signalThresholdInfos);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE,
-                        "setSignalStrengthReportingCriteria", e);
-            }
-        } else {
-            riljLoge("setSignalStrengthReportingCriteria ignored on IRadio version less than 1.2");
-        }
-    }
-
-    @Override
-    public void setLinkCapacityReportingCriteria(int hysteresisMs, int hysteresisDlKbps,
-            int hysteresisUlKbps, int[] thresholdsDlKbps, int[] thresholdsUlKbps, int ran,
-            Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_2)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA, result,
-                    mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
-
-            try {
-                networkProxy.setLinkCapacityReportingCriteria(rr.mSerial, hysteresisMs,
-                        hysteresisDlKbps, hysteresisUlKbps, thresholdsDlKbps, thresholdsUlKbps,
-                        ran);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(
-                        NETWORK_SERVICE, "setLinkCapacityReportingCriteria", e);
-            }
-        } else {
-            riljLoge("setLinkCapacityReportingCriteria ignored on IRadio version less than 1.2");
-        }
-    }
-
-    @Override
-    public void setSimCardPower(int state, Message result, WorkSource workSource) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (!simProxy.isEmpty()) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SET_SIM_CARD_POWER, result,
-                    getDefaultWorkSourceIfInvalid(workSource));
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                        + " " + state);
-            }
-
-            try {
-                simProxy.setSimCardPower(rr.mSerial, state, result);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "setSimCardPower", e);
-            }
-        }
-    }
-
-    @Override
-    public void setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo,
-            Message result) {
-        Objects.requireNonNull(imsiEncryptionInfo, "ImsiEncryptionInfo cannot be null.");
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (simProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION, result,
-                    mRILDefaultWorkSource);
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
-
-            try {
-                simProxy.setCarrierInfoForImsiEncryption(rr.mSerial, imsiEncryptionInfo);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "setCarrierInfoForImsiEncryption", e);
-            }
-        } else {
-            if (RILJ_LOGD) {
-                Rlog.d(RILJ_LOG_TAG, "setCarrierInfoForImsiEncryption: REQUEST_NOT_SUPPORTED");
-            }
-            if (result != null) {
+            if (packetData.getDstAddress() instanceof Inet4Address) {
+                req.type = android.hardware.radio.V1_1.KeepaliveType.NATT_IPV4;
+            } else if (packetData.getDstAddress() instanceof Inet6Address) {
+                req.type = android.hardware.radio.V1_1.KeepaliveType.NATT_IPV6;
+            } else {
                 AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                        CommandException.fromRilErrno(INVALID_ARGUMENTS));
                 result.sendToTarget();
-            }
-        }
-    }
-
-    @Override
-    public void startNattKeepalive(int contextId, KeepalivePacketData packetData,
-            int intervalMillis, Message result) {
-        Objects.requireNonNull(packetData, "KeepaliveRequest cannot be null.");
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (dataProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_START_KEEPALIVE, result,
-                    mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                return;
             }
 
-            try {
-                dataProxy.startKeepalive(rr.mSerial, contextId, packetData, intervalMillis, result);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "startNattKeepalive", e);
-            }
-        } else {
-            if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "startNattKeepalive: REQUEST_NOT_SUPPORTED");
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
-            }
+            final InetAddress srcAddress = packetData.getSrcAddress();
+            final InetAddress dstAddress = packetData.getDstAddress();
+            appendPrimitiveArrayToArrayList(
+                    srcAddress.getAddress(), req.sourceAddress);
+            req.sourcePort = packetData.getSrcPort();
+            appendPrimitiveArrayToArrayList(
+                    dstAddress.getAddress(), req.destinationAddress);
+            req.destinationPort = packetData.getDstPort();
+            req.maxKeepaliveIntervalMillis = intervalMillis;
+
+            radioProxy11.startKeepalive(rr.mSerial, req);
+        } catch (RemoteException | RuntimeException e) {
+            handleRadioProxyExceptionForRR(rr, "startNattKeepalive", e);
         }
     }
 
     @Override
     public void stopNattKeepalive(int sessionHandle, Message result) {
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (dataProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_1)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_STOP_KEEPALIVE, result,
-                    mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy == null) return;
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
-
-            try {
-                dataProxy.stopKeepalive(rr.mSerial, sessionHandle);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "stopNattKeepalive", e);
-            }
-        } else {
-            if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "stopNattKeepalive: REQUEST_NOT_SUPPORTED");
+        if (mRadioVersion.less(RADIO_HAL_VERSION_1_1)) {
             if (result != null) {
                 AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
                 result.sendToTarget();
             }
+            return;
+        }
+
+        android.hardware.radio.V1_1.IRadio radioProxy11 =
+                (android.hardware.radio.V1_1.IRadio) radioProxy;
+
+        RILRequest rr = obtainRequest(
+                RIL_REQUEST_STOP_KEEPALIVE, result, mRILDefaultWorkSource);
+
+        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+        try {
+            radioProxy11.stopKeepalive(rr.mSerial, sessionHandle);
+        } catch (RemoteException | RuntimeException e) {
+            handleRadioProxyExceptionForRR(rr, "stopNattKeepalive", e);
         }
     }
 
@@ -4660,66 +5615,68 @@
      * Enable or disable uicc applications on the SIM.
      *
      * @param enable whether to enable or disable uicc applications.
-     * @param result a Message to return to the requester
+     * @param onCompleteMessage a Message to return to the requester
      */
     @Override
-    public void enableUiccApplications(boolean enable, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (simProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_UICC_APPLICATIONS, result,
-                    mRILDefaultWorkSource);
+    public void enableUiccApplications(boolean enable, Message onCompleteMessage) {
+        IRadio radioProxy = getRadioProxy(onCompleteMessage);
+        if (radioProxy == null) return;
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
-
-            try {
-                simProxy.enableUiccApplications(rr.mSerial, enable);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "enableUiccApplications", e);
-            }
-        } else {
-            if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "enableUiccApplications: REQUEST_NOT_SUPPORTED");
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
+        if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
+            if (onCompleteMessage != null) {
+                AsyncResult.forMessage(onCompleteMessage, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
+                onCompleteMessage.sendToTarget();
             }
+            return;
+        }
+
+        android.hardware.radio.V1_5.IRadio radioProxy15 =
+                (android.hardware.radio.V1_5.IRadio) radioProxy;
+
+        RILRequest rr = obtainRequest(RIL_REQUEST_ENABLE_UICC_APPLICATIONS,
+                onCompleteMessage, mRILDefaultWorkSource);
+
+        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+        try {
+            radioProxy15.enableUiccApplications(rr.mSerial, enable);
+        } catch (RemoteException | RuntimeException e) {
+            handleRadioProxyExceptionForRR(rr, "enableUiccApplications", e);
         }
     }
 
     /**
      * Whether uicc applications are enabled or not.
      *
-     * @param result a Message to return to the requester
+     * @param onCompleteMessage a Message to return to the requester
      */
     @Override
-    public void areUiccApplicationsEnabled(Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (simProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT, result,
-                    mRILDefaultWorkSource);
+    public void areUiccApplicationsEnabled(Message onCompleteMessage) {
+        IRadio radioProxy = getRadioProxy(onCompleteMessage);
+        if (radioProxy == null) return;
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
-
-            try {
-                simProxy.areUiccApplicationsEnabled(rr.mSerial);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "areUiccApplicationsEnabled", e);
-            }
-        } else {
-            if (RILJ_LOGD) {
-                Rlog.d(RILJ_LOG_TAG, "areUiccApplicationsEnabled: REQUEST_NOT_SUPPORTED");
-            }
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
+        if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
+            if (onCompleteMessage != null) {
+                AsyncResult.forMessage(onCompleteMessage, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
+                onCompleteMessage.sendToTarget();
             }
+            return;
+        }
+
+        android.hardware.radio.V1_5.IRadio radioProxy15 =
+                (android.hardware.radio.V1_5.IRadio) radioProxy;
+
+        RILRequest rr = obtainRequest(RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT,
+                onCompleteMessage, mRILDefaultWorkSource);
+
+        if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+        try {
+            radioProxy15.areUiccApplicationsEnabled(rr.mSerial);
+        } catch (RemoteException | RuntimeException e) {
+            handleRadioProxyExceptionForRR(rr, "areUiccApplicationsEnabled", e);
         }
     }
 
@@ -4728,8 +5685,28 @@
      */
     @Override
     public boolean canToggleUiccApplicationsEnablement() {
-        return !getRadioServiceProxy(RadioSimProxy.class, null).isEmpty()
-                && mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5);
+        return getRadioProxy(null) != null && mRadioVersion
+                .greaterOrEqual(RADIO_HAL_VERSION_1_5);
+    }
+
+    /**
+     *  Translates EF_SMS status bits to a status value compatible with
+     *  SMS AT commands.  See TS 27.005 3.1.
+     */
+    private int translateStatus(int status) {
+        switch(status & 0x7) {
+            case SmsManager.STATUS_ON_ICC_READ:
+                return 1;
+            case SmsManager.STATUS_ON_ICC_UNREAD:
+                return 0;
+            case SmsManager.STATUS_ON_ICC_SENT:
+                return 3;
+            case SmsManager.STATUS_ON_ICC_UNSENT:
+                return 2;
+        }
+
+        // Default to READ.
+        return 1;
     }
 
     @Override
@@ -4742,20 +5719,19 @@
      */
     @Override
     public void handleCallSetupRequestFromSim(boolean accept, Message result) {
-        RadioVoiceProxy voiceProxy = getRadioServiceProxy(RadioVoiceProxy.class, result);
-        if (!voiceProxy.isEmpty()) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM,
                     result, mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
             try {
-                voiceProxy.handleStkCallSetupRequestFromSim(rr.mSerial, accept);
+                radioProxy.handleStkCallSetupRequestFromSim(rr.mSerial, accept);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(
-                        VOICE_SERVICE, "handleStkCallSetupRequestFromSim", e);
+                handleRadioProxyExceptionForRR(rr, "getAllowedCarriers", e);
             }
         }
     }
@@ -4765,28 +5741,31 @@
      */
     @Override
     public void getBarringInfo(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_5)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_GET_BARRING_INFO, result,
-                    mRILDefaultWorkSource);
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy == null) return;
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
-
-            try {
-                networkProxy.getBarringInfo(rr.mSerial);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getBarringInfo", e);
-            }
-        } else {
-            if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "getBarringInfo: REQUEST_NOT_SUPPORTED");
+        if (mRadioVersion.less(RADIO_HAL_VERSION_1_5)) {
             if (result != null) {
                 AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
                 result.sendToTarget();
             }
+            return;
+        }
+
+        android.hardware.radio.V1_5.IRadio radioProxy15 =
+                (android.hardware.radio.V1_5.IRadio) radioProxy;
+        if (radioProxy15 != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_GET_BARRING_INFO, result,
+                    mRILDefaultWorkSource);
+
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
+
+            try {
+                radioProxy15.getBarringInfo(rr.mSerial);
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "getBarringInfo", e);
+            }
         }
     }
 
@@ -4795,19 +5774,17 @@
      */
     @Override
     public void allocatePduSessionId(Message result) {
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (dataProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        android.hardware.radio.V1_6.IRadio radioProxy16 = getRadioV16(result);
+
+        if (radioProxy16 != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_ALLOCATE_PDU_SESSION_ID, result,
                     mRILDefaultWorkSource);
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                dataProxy.allocatePduSessionId(rr.mSerial);
+                radioProxy16.allocatePduSessionId(rr.mSerial);
             } catch (RemoteException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "allocatePduSessionId", e);
+                handleRadioProxyExceptionForRR(rr, "allocatePduSessionId", e);
             }
         } else {
             AsyncResult.forMessage(result, null,
@@ -4821,19 +5798,17 @@
      */
     @Override
     public void releasePduSessionId(Message result, int pduSessionId) {
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (dataProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        android.hardware.radio.V1_6.IRadio radioProxy16 = getRadioV16(result);
+
+        if (radioProxy16 != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_RELEASE_PDU_SESSION_ID, result,
                     mRILDefaultWorkSource);
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                dataProxy.releasePduSessionId(rr.mSerial, pduSessionId);
+                radioProxy16.releasePduSessionId(rr.mSerial, pduSessionId);
             } catch (RemoteException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "releasePduSessionId", e);
+                handleRadioProxyExceptionForRR(rr, "releasePduSessionId", e);
             }
         } else {
             AsyncResult.forMessage(result, null,
@@ -4847,27 +5822,23 @@
      */
     @Override
     public void startHandover(Message result, int callId) {
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (dataProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        android.hardware.radio.V1_6.IRadio radioProxy16 = getRadioV16(result);
+
+        if (radioProxy16 != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_START_HANDOVER, result,
                     mRILDefaultWorkSource);
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                dataProxy.startHandover(rr.mSerial, callId);
+                radioProxy16.startHandover(rr.mSerial, callId);
             } catch (RemoteException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "startHandover", e);
+                handleRadioProxyExceptionForRR(rr, "startHandover", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "startHandover: REQUEST_NOT_SUPPORTED");
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
-            }
+            AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+            result.sendToTarget();
         }
     }
 
@@ -4876,19 +5847,17 @@
      */
     @Override
     public void cancelHandover(Message result, int callId) {
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (dataProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        android.hardware.radio.V1_6.IRadio radioProxy16 = getRadioV16(result);
+
+        if (radioProxy16 != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_CANCEL_HANDOVER, result,
                     mRILDefaultWorkSource);
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                dataProxy.cancelHandover(rr.mSerial, callId);
+                radioProxy16.cancelHandover(rr.mSerial, callId);
             } catch (RemoteException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "cancelHandover", e);
+                handleRadioProxyExceptionForRR(rr, "cancelHandover", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "cancelHandover: REQUEST_NOT_SUPPORTED");
@@ -4903,20 +5872,18 @@
      */
     @Override
     public void getSlicingConfig(Message result) {
-        RadioDataProxy dataProxy = getRadioServiceProxy(RadioDataProxy.class, result);
-        if (dataProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        android.hardware.radio.V1_6.IRadio radioProxy16 = getRadioV16(result);
+
+        if (radioProxy16 != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SLICING_CONFIG, result,
                     mRILDefaultWorkSource);
 
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
+            if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
 
             try {
-                dataProxy.getSlicingConfig(rr.mSerial);
+                radioProxy16.getSlicingConfig(rr.mSerial);
             } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(DATA_SERVICE, "getSlicingConfig", e);
+                handleRadioProxyExceptionForRR(rr, "getSlicingConfig", e);
             }
         } else {
             if (RILJ_LOGD) Rlog.d(RILJ_LOG_TAG, "getSlicingConfig: REQUEST_NOT_SUPPORTED");
@@ -4928,172 +5895,118 @@
 
     @Override
     public void getSimPhonebookRecords(Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (simProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SIM_PHONEBOOK_RECORDS, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
-            try {
-                simProxy.getSimPhonebookRecords(rr.mSerial);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getSimPhonebookRecords", e);
-            }
-        } else {
-            if (RILJ_LOGD) {
-                Rlog.d(RILJ_LOG_TAG, "getSimPhonebookRecords: REQUEST_NOT_SUPPORTED");
-            }
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                android.hardware.radio.V1_6.IRadio radioProxy16 =
+                            android.hardware.radio.V1_6.IRadio.castFrom(radioProxy);
+                try {
+                    radioProxy16.getSimPhonebookRecords(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "getPhonebookRecords", e);
+                }
+            } else {
+                riljLog("Unsupported API in lower than version 1.6 radio HAL" );
+                if (result != null) {
+                    AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                    result.sendToTarget();
+                }
             }
         }
     }
 
     @Override
     public void getSimPhonebookCapacity(Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (simProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_GET_SIM_PHONEBOOK_CAPACITY, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
             }
 
-            try {
-                simProxy.getSimPhonebookCapacity(rr.mSerial);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "getSimPhonebookCapacity", e);
-            }
-        } else {
-            if (RILJ_LOGD) {
-                Rlog.d(RILJ_LOG_TAG, "getSimPhonebookCapacity: REQUEST_NOT_SUPPORTED");
-            }
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                android.hardware.radio.V1_6.IRadio radioProxy16 =
+                            android.hardware.radio.V1_6.IRadio.castFrom(radioProxy);
+                try {
+                    radioProxy16.getSimPhonebookCapacity(rr.mSerial);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "getPhonebookRecords", e);
+                }
+            } else {
+                riljLog("Unsupported API in lower than version 1.6 radio HAL" );
+                if (result != null) {
+                    AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                    result.sendToTarget();
+                }
             }
         }
     }
 
     @Override
     public void updateSimPhonebookRecord(SimPhonebookRecord phonebookRecord, Message result) {
-        RadioSimProxy simProxy = getRadioServiceProxy(RadioSimProxy.class, result);
-        if (simProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+        IRadio radioProxy = getRadioProxy(result);
+        if (radioProxy != null) {
             RILRequest rr = obtainRequest(RIL_REQUEST_UPDATE_SIM_PHONEBOOK_RECORD, result,
                     mRILDefaultWorkSource);
 
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest)
                         + " with " + phonebookRecord.toString());
             }
 
-            try {
-                simProxy.updateSimPhonebookRecords(rr.mSerial, phonebookRecord);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(SIM_SERVICE, "updateSimPhonebookRecords", e);
-            }
-        } else {
-            if (RILJ_LOGD) {
-                Rlog.d(RILJ_LOG_TAG, "updateSimPhonebookRecords: REQUEST_NOT_SUPPORTED");
-            }
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
-            }
-        }
-    }
+            if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+                android.hardware.radio.V1_6.IRadio radioProxy16 =
+                        android.hardware.radio.V1_6.IRadio.castFrom(radioProxy);
 
-    /**
-     * Set the UE's usage setting.
-     *
-     * @param result Callback message containing the success or failure status.
-     * @param usageSetting the UE's usage setting, either VOICE_CENTRIC or DATA_CENTRIC.
-     */
-    @Override
-    public void setUsageSetting(Message result,
-            /* @TelephonyManager.UsageSetting */ int usageSetting) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_SET_USAGE_SETTING, result,
-                    mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
-
-            try {
-                networkProxy.setUsageSetting(rr.mSerial, usageSetting);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "setUsageSetting", e);
-            }
-        } else {
-            if (RILJ_LOGD) {
-                Rlog.d(RILJ_LOG_TAG, "setUsageSetting: REQUEST_NOT_SUPPORTED");
-            }
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
-            }
-        }
-    }
-
-    /**
-     * Get the UE's usage setting.
-     *
-     * @param result Callback message containing the usage setting (or a failure status).
-     */
-    @Override
-    public void getUsageSetting(Message result) {
-        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class, result);
-        if (networkProxy.isEmpty()) return;
-        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_2_0)) {
-            RILRequest rr = obtainRequest(RIL_REQUEST_GET_USAGE_SETTING, result,
-                    mRILDefaultWorkSource);
-
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-            }
-
-            try {
-                networkProxy.getUsageSetting(rr.mSerial);
-            } catch (RemoteException | RuntimeException e) {
-                handleRadioProxyExceptionForRR(NETWORK_SERVICE, "getUsageSetting", e);
-            }
-        } else {
-            if (RILJ_LOGD) {
-                Rlog.d(RILJ_LOG_TAG, "getUsageSetting: REQUEST_NOT_SUPPORTED");
-            }
-            if (result != null) {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
+                android.hardware.radio.V1_6.PhonebookRecordInfo pbRecordInfo =
+                        phonebookRecord.toPhonebookRecordInfo();
+                try {
+                     radioProxy16.updateSimPhonebookRecords(rr.mSerial, pbRecordInfo);
+                } catch (RemoteException | RuntimeException e) {
+                    handleRadioProxyExceptionForRR(rr, "updatePhonebookRecord", e);
+                }
+            } else {
+                riljLog("Unsupported API in lower than version 1.6 radio HAL" );
+                if (result != null) {
+                    AsyncResult.forMessage(result, null,
+                    CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
+                    result.sendToTarget();
+                }
             }
         }
     }
 
     //***** Private Methods
+    /** Helper that gets V1.6 of the radio interface OR sends back REQUEST_NOT_SUPPORTED */
+    @Nullable private android.hardware.radio.V1_6.IRadio getRadioV16(Message msg) {
+        IRadio radioProxy = getRadioProxy(msg);
+        if (mRadioVersion.greaterOrEqual(RADIO_HAL_VERSION_1_6)) {
+            return (android.hardware.radio.V1_6.IRadio) radioProxy;
+        } else {
+            return (android.hardware.radio.V1_6.IRadio) null;
+        }
+    }
+
+
     /**
-     * This is a helper function to be called when an indication callback is called for any radio
-     * service. It takes care of acquiring wakelock and sending ack if needed.
-     * @param service radio service the indication is for
-     * @param indicationType indication type received
+     * This is a helper function to be called when a RadioIndication callback is called.
+     * It takes care of acquiring wakelock and sending ack if needed.
+     * @param indicationType RadioIndicationType received
      */
-    void processIndication(int service, int indicationType) {
+    void processIndication(int indicationType) {
         if (indicationType == RadioIndicationType.UNSOLICITED_ACK_EXP) {
-            sendAck(service);
+            sendAck();
             if (RILJ_LOGD) riljLog("Unsol response received; Sending ack to ril.cpp");
         } else {
             // ack is not expected to be sent back. Nothing is required to be done here.
@@ -5106,12 +6019,12 @@
             rr = mRequestList.get(serial);
         }
         if (rr == null) {
-            Rlog.w(RILJ_LOG_TAG, "processRequestAck: Unexpected solicited ack response! "
+            Rlog.w(RIL.RILJ_LOG_TAG, "processRequestAck: Unexpected solicited ack response! "
                     + "serial: " + serial);
         } else {
             decrementWakeLock(rr);
-            if (RILJ_LOGD) {
-                riljLog(rr.serialString() + " Ack < " + RILUtils.requestToString(rr.mRequest));
+            if (RIL.RILJ_LOGD) {
+                riljLog(rr.serialString() + " Ack < " + RIL.requestToString(rr.mRequest));
             }
         }
     }
@@ -5125,41 +6038,25 @@
      */
     @VisibleForTesting
     public RILRequest processResponse(RadioResponseInfo responseInfo) {
-        return processResponseInternal(RADIO_SERVICE, responseInfo.serial, responseInfo.error,
-                responseInfo.type);
+        return processResponseInternal(responseInfo.serial, responseInfo.error, responseInfo.type);
     }
 
     /**
      * This is a helper function for V1_6.RadioResponseInfo to be called when a RadioResponse
-     * callback is called. It takes care of acks, wakelocks, and finds and returns RILRequest
-     * corresponding to the response if one is found.
+     * callback is called.
+     * It takes care of acks, wakelocks, and finds and returns RILRequest corresponding to the
+     * response if one is found.
      * @param responseInfo RadioResponseInfo received in response callback
      * @return RILRequest corresponding to the response
      */
     @VisibleForTesting
     public RILRequest processResponse_1_6(
-            android.hardware.radio.V1_6.RadioResponseInfo responseInfo) {
-        return processResponseInternal(RADIO_SERVICE, responseInfo.serial, responseInfo.error,
-                responseInfo.type);
+                    android.hardware.radio.V1_6.RadioResponseInfo responseInfo) {
+        return processResponseInternal(responseInfo.serial, responseInfo.error, responseInfo.type);
     }
 
-    /**
-     * This is a helper function for an AIDL RadioResponseInfo to be called when a RadioResponse
-     * callback is called. It takes care of acks, wakelocks, and finds and returns RILRequest
-     * corresponding to the response if one is found.
-     * @param service Radio service that received the response
-     * @param responseInfo RadioResponseInfo received in response callback
-     * @return RILRequest corresponding to the response
-     */
-    @VisibleForTesting
-    public RILRequest processResponse(int service,
-            android.hardware.radio.RadioResponseInfo responseInfo) {
-        return processResponseInternal(service, responseInfo.serial, responseInfo.error,
-                responseInfo.type);
-    }
-
-    private RILRequest processResponseInternal(int service, int serial, int error, int type) {
-        RILRequest rr;
+    private RILRequest processResponseInternal(int serial, int error, int type) {
+        RILRequest rr = null;
 
         if (type == RadioResponseType.SOLICITED_ACK) {
             synchronized (mRequestList) {
@@ -5173,8 +6070,7 @@
                     mRadioBugDetector.detectRadioBug(rr.mRequest, error);
                 }
                 if (RILJ_LOGD) {
-                    riljLog(rr.serialString() + " Ack from " + serviceToString(service)
-                            + " < " + RILUtils.requestToString(rr.mRequest));
+                    riljLog(rr.serialString() + " Ack < " + requestToString(rr.mRequest));
                 }
             }
             return rr;
@@ -5182,8 +6078,8 @@
 
         rr = findAndRemoveRequestFromList(serial);
         if (rr == null) {
-            Rlog.e(RILJ_LOG_TAG, "processResponse: Unexpected response! serial: " + serial
-                    + " ,error: " + error);
+            Rlog.e(RIL.RILJ_LOG_TAG, "processResponse: Unexpected response! serial: " + serial
+                    + " error: " + error);
             return null;
         }
 
@@ -5193,11 +6089,10 @@
             mRadioBugDetector.detectRadioBug(rr.mRequest, error);
         }
         if (type == RadioResponseType.SOLICITED_ACK_EXP) {
-            sendAck(service);
-            if (RILJ_LOGD) {
-                riljLog("Response received from " + serviceToString(service) + " for "
-                        + rr.serialString() + " " + RILUtils.requestToString(rr.mRequest)
-                        + " Sending ack to ril.cpp");
+            sendAck();
+            if (RIL.RILJ_LOGD) {
+                riljLog("Response received for " + rr.serialString() + " "
+                        + RIL.requestToString(rr.mRequest) + " Sending ack to ril.cpp");
             }
         } else {
             // ack sent for SOLICITED_ACK_EXP above; nothing to do for SOLICITED response
@@ -5277,36 +6172,22 @@
      * @param ret object to be returned to request sender
      */
     @VisibleForTesting
-    public void processResponseDone_1_6(RILRequest rr,
-            android.hardware.radio.V1_6.RadioResponseInfo responseInfo, Object ret) {
+    public void processResponseDone_1_6(
+                    RILRequest rr, android.hardware.radio.V1_6.RadioResponseInfo responseInfo,
+                    Object ret) {
         processResponseDoneInternal(rr, responseInfo.error, responseInfo.type, ret);
     }
 
-    /**
-     * This is a helper function to be called at the end of the RadioResponse callbacks using for
-     * RadioResponseInfo AIDL.
-     * It takes care of sending error response, logging, decrementing wakelock if needed, and
-     * releases the request from memory pool.
-     * @param rr RILRequest for which response callback was called
-     * @param responseInfo RadioResponseInfo received in the callback
-     * @param ret object to be returned to request sender
-     */
-    @VisibleForTesting
-    public void processResponseDone(RILRequest rr,
-            android.hardware.radio.RadioResponseInfo responseInfo, Object ret) {
-        processResponseDoneInternal(rr, responseInfo.error, responseInfo.type, ret);
-    }
-
-    private void processResponseDoneInternal(RILRequest rr, int rilError, int responseType,
-            Object ret) {
+    private void processResponseDoneInternal(
+            RILRequest rr, int rilError, int responseType, Object ret) {
         if (rilError == 0) {
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "< " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
                         + " " + retToString(rr.mRequest, ret));
             }
         } else {
             if (RILJ_LOGD) {
-                riljLog(rr.serialString() + "< " + RILUtils.requestToString(rr.mRequest)
+                riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
                         + " error " + rilError);
             }
             rr.onError(rilError, ret);
@@ -5326,7 +6207,7 @@
     @VisibleForTesting
     public void processResponseFallback(RILRequest rr, RadioResponseInfo responseInfo, Object ret) {
         if (responseInfo.error == REQUEST_NOT_SUPPORTED && RILJ_LOGD) {
-            riljLog(rr.serialString() + "< " + RILUtils.requestToString(rr.mRequest)
+            riljLog(rr.serialString() + "< " + requestToString(rr.mRequest)
                     + " request not supported, falling back");
         }
         processResponseCleanUp(rr, responseInfo.error, responseInfo.type, ret);
@@ -5345,35 +6226,21 @@
     /**
      * Function to send ack and acquire related wakelock
      */
-    private void sendAck(int service) {
+    private void sendAck() {
         // TODO: Remove rr and clean up acquireWakelock for response and ack
         RILRequest rr = RILRequest.obtain(RIL_RESPONSE_ACKNOWLEDGEMENT, null,
                 mRILDefaultWorkSource);
-        acquireWakeLock(rr, FOR_ACK_WAKELOCK);
-        if (service == RADIO_SERVICE) {
-            IRadio radioProxy = getRadioProxy(null);
-            if (radioProxy != null) {
-                try {
-                    radioProxy.responseAcknowledgement();
-                } catch (RemoteException | RuntimeException e) {
-                    handleRadioProxyExceptionForRR(RADIO_SERVICE, "sendAck", e);
-                    riljLoge("sendAck: " + e);
-                }
-            } else {
-                Rlog.e(RILJ_LOG_TAG, "Error trying to send ack, radioProxy = null");
+        acquireWakeLock(rr, RIL.FOR_ACK_WAKELOCK);
+        IRadio radioProxy = getRadioProxy(null);
+        if (radioProxy != null) {
+            try {
+                radioProxy.responseAcknowledgement();
+            } catch (RemoteException | RuntimeException e) {
+                handleRadioProxyExceptionForRR(rr, "sendAck", e);
+                riljLoge("sendAck: " + e);
             }
         } else {
-            RadioServiceProxy serviceProxy = getRadioServiceProxy(service, null);
-            if (!serviceProxy.isEmpty()) {
-                try {
-                    serviceProxy.responseAcknowledgement();
-                } catch (RemoteException | RuntimeException e) {
-                    handleRadioProxyExceptionForRR(service, "sendAck", e);
-                    riljLoge("sendAck: " + e);
-                }
-            } else {
-                Rlog.e(RILJ_LOG_TAG, "Error trying to send ack, serviceProxy is empty");
-            }
+            Rlog.e(RILJ_LOG_TAG, "Error trying to send ack, radioProxy = null");
         }
         rr.release();
     }
@@ -5536,7 +6403,7 @@
                 rr = mRequestList.valueAt(i);
                 if (RILJ_LOGD && loggable) {
                     Rlog.d(RILJ_LOG_TAG, i + ": [" + rr.mSerial + "] "
-                            + RILUtils.requestToString(rr.mRequest));
+                            + requestToString(rr.mRequest));
                 }
                 rr.onError(error, null);
                 decrementWakeLock(rr);
@@ -5548,7 +6415,7 @@
 
     @UnsupportedAppUsage
     private RILRequest findAndRemoveRequestFromList(int serial) {
-        RILRequest rr;
+        RILRequest rr = null;
         synchronized (mRequestList) {
             rr = mRequestList.get(serial);
             if (rr != null) {
@@ -5563,13 +6430,13 @@
         long endTime = SystemClock.elapsedRealtime();
         int totalTime = (int) (endTime - rr.mStartTimeMs);
 
-        synchronized (sRilTimeHistograms) {
-            TelephonyHistogram entry = sRilTimeHistograms.get(rr.mRequest);
+        synchronized (mRilTimeHistograms) {
+            TelephonyHistogram entry = mRilTimeHistograms.get(rr.mRequest);
             if (entry == null) {
                 // We would have total #RIL_HISTOGRAM_BUCKET_COUNT range buckets for RIL commands
                 entry = new TelephonyHistogram(TelephonyHistogram.TELEPHONY_CATEGORY_RIL,
                         rr.mRequest, RIL_HISTOGRAM_BUCKET_COUNT);
-                sRilTimeHistograms.put(rr.mRequest, entry);
+                mRilTimeHistograms.put(rr.mRequest, entry);
             }
             entry.addTimeTaken(totalTime);
         }
@@ -5675,22 +6542,7 @@
             }
             s = sb.toString();
         } else {
-            // Check if toString() was overridden. Java classes created from HIDL have a built-in
-            // toString() method, but AIDL classes only have it if the parcelable contains a
-            // @JavaDerive annotation. Manually convert to String as a backup for AIDL parcelables
-            // missing the annotation.
-            boolean toStringExists = false;
-            try {
-                toStringExists = ret.getClass().getMethod("toString").getDeclaringClass()
-                        != Object.class;
-            } catch (NoSuchMethodException e) {
-                Rlog.e(RILJ_LOG_TAG, e.getMessage());
-            }
-            if (toStringExists) {
-                s = ret.toString();
-            } else {
-                s = RILUtils.convertToString(ret) + " [convertToString]";
-            }
+            s = ret.toString();
         }
         return s;
     }
@@ -5728,7 +6580,8 @@
     }
 
     @UnsupportedAppUsage
-    void notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
+    void
+    notifyRegistrantsCdmaInfoRec(CdmaInformationRecords infoRec) {
         int response = RIL_UNSOL_CDMA_INFO_REC;
         if (infoRec.record instanceof CdmaInformationRecords.CdmaDisplayInfoRec) {
             if (mDisplayInfoRegistrants != null) {
@@ -5778,6 +6631,493 @@
     }
 
     @UnsupportedAppUsage
+    static String requestToString(int request) {
+        switch(request) {
+            case RIL_REQUEST_GET_SIM_STATUS:
+                return "GET_SIM_STATUS";
+            case RIL_REQUEST_ENTER_SIM_PIN:
+                return "ENTER_SIM_PIN";
+            case RIL_REQUEST_ENTER_SIM_PUK:
+                return "ENTER_SIM_PUK";
+            case RIL_REQUEST_ENTER_SIM_PIN2:
+                return "ENTER_SIM_PIN2";
+            case RIL_REQUEST_ENTER_SIM_PUK2:
+                return "ENTER_SIM_PUK2";
+            case RIL_REQUEST_CHANGE_SIM_PIN:
+                return "CHANGE_SIM_PIN";
+            case RIL_REQUEST_CHANGE_SIM_PIN2:
+                return "CHANGE_SIM_PIN2";
+            case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION:
+                return "ENTER_NETWORK_DEPERSONALIZATION";
+            case RIL_REQUEST_GET_CURRENT_CALLS:
+                return "GET_CURRENT_CALLS";
+            case RIL_REQUEST_DIAL:
+                return "DIAL";
+            case RIL_REQUEST_GET_IMSI:
+                return "GET_IMSI";
+            case RIL_REQUEST_HANGUP:
+                return "HANGUP";
+            case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
+                return "HANGUP_WAITING_OR_BACKGROUND";
+            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
+                return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
+            case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
+                return "REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
+            case RIL_REQUEST_CONFERENCE:
+                return "CONFERENCE";
+            case RIL_REQUEST_UDUB:
+                return "UDUB";
+            case RIL_REQUEST_LAST_CALL_FAIL_CAUSE:
+                return "LAST_CALL_FAIL_CAUSE";
+            case RIL_REQUEST_SIGNAL_STRENGTH:
+                return "SIGNAL_STRENGTH";
+            case RIL_REQUEST_VOICE_REGISTRATION_STATE:
+                return "VOICE_REGISTRATION_STATE";
+            case RIL_REQUEST_DATA_REGISTRATION_STATE:
+                return "DATA_REGISTRATION_STATE";
+            case RIL_REQUEST_OPERATOR:
+                return "OPERATOR";
+            case RIL_REQUEST_RADIO_POWER:
+                return "RADIO_POWER";
+            case RIL_REQUEST_DTMF:
+                return "DTMF";
+            case RIL_REQUEST_SEND_SMS:
+                return "SEND_SMS";
+            case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
+                return "SEND_SMS_EXPECT_MORE";
+            case RIL_REQUEST_SETUP_DATA_CALL:
+                return "SETUP_DATA_CALL";
+            case RIL_REQUEST_SIM_IO:
+                return "SIM_IO";
+            case RIL_REQUEST_SEND_USSD:
+                return "SEND_USSD";
+            case RIL_REQUEST_CANCEL_USSD:
+                return "CANCEL_USSD";
+            case RIL_REQUEST_GET_CLIR:
+                return "GET_CLIR";
+            case RIL_REQUEST_SET_CLIR:
+                return "SET_CLIR";
+            case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS:
+                return "QUERY_CALL_FORWARD_STATUS";
+            case RIL_REQUEST_SET_CALL_FORWARD:
+                return "SET_CALL_FORWARD";
+            case RIL_REQUEST_QUERY_CALL_WAITING:
+                return "QUERY_CALL_WAITING";
+            case RIL_REQUEST_SET_CALL_WAITING:
+                return "SET_CALL_WAITING";
+            case RIL_REQUEST_SMS_ACKNOWLEDGE:
+                return "SMS_ACKNOWLEDGE";
+            case RIL_REQUEST_GET_IMEI:
+                return "GET_IMEI";
+            case RIL_REQUEST_GET_IMEISV:
+                return "GET_IMEISV";
+            case RIL_REQUEST_ANSWER:
+                return "ANSWER";
+            case RIL_REQUEST_DEACTIVATE_DATA_CALL:
+                return "DEACTIVATE_DATA_CALL";
+            case RIL_REQUEST_QUERY_FACILITY_LOCK:
+                return "QUERY_FACILITY_LOCK";
+            case RIL_REQUEST_SET_FACILITY_LOCK:
+                return "SET_FACILITY_LOCK";
+            case RIL_REQUEST_CHANGE_BARRING_PASSWORD:
+                return "CHANGE_BARRING_PASSWORD";
+            case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
+                return "QUERY_NETWORK_SELECTION_MODE";
+            case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
+                return "SET_NETWORK_SELECTION_AUTOMATIC";
+            case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
+                return "SET_NETWORK_SELECTION_MANUAL";
+            case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS :
+                return "QUERY_AVAILABLE_NETWORKS ";
+            case RIL_REQUEST_DTMF_START:
+                return "DTMF_START";
+            case RIL_REQUEST_DTMF_STOP:
+                return "DTMF_STOP";
+            case RIL_REQUEST_BASEBAND_VERSION:
+                return "BASEBAND_VERSION";
+            case RIL_REQUEST_SEPARATE_CONNECTION:
+                return "SEPARATE_CONNECTION";
+            case RIL_REQUEST_SET_MUTE:
+                return "SET_MUTE";
+            case RIL_REQUEST_GET_MUTE:
+                return "GET_MUTE";
+            case RIL_REQUEST_QUERY_CLIP:
+                return "QUERY_CLIP";
+            case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE:
+                return "LAST_DATA_CALL_FAIL_CAUSE";
+            case RIL_REQUEST_DATA_CALL_LIST:
+                return "DATA_CALL_LIST";
+            case RIL_REQUEST_RESET_RADIO:
+                return "RESET_RADIO";
+            case RIL_REQUEST_OEM_HOOK_RAW:
+                return "OEM_HOOK_RAW";
+            case RIL_REQUEST_OEM_HOOK_STRINGS:
+                return "OEM_HOOK_STRINGS";
+            case RIL_REQUEST_SCREEN_STATE:
+                return "SCREEN_STATE";
+            case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION:
+                return "SET_SUPP_SVC_NOTIFICATION";
+            case RIL_REQUEST_WRITE_SMS_TO_SIM:
+                return "WRITE_SMS_TO_SIM";
+            case RIL_REQUEST_DELETE_SMS_ON_SIM:
+                return "DELETE_SMS_ON_SIM";
+            case RIL_REQUEST_SET_BAND_MODE:
+                return "SET_BAND_MODE";
+            case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
+                return "QUERY_AVAILABLE_BAND_MODE";
+            case RIL_REQUEST_STK_GET_PROFILE:
+                return "STK_GET_PROFILE";
+            case RIL_REQUEST_STK_SET_PROFILE:
+                return "STK_SET_PROFILE";
+            case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND:
+                return "STK_SEND_ENVELOPE_COMMAND";
+            case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE:
+                return "STK_SEND_TERMINAL_RESPONSE";
+            case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM:
+                return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
+            case RIL_REQUEST_EXPLICIT_CALL_TRANSFER:
+                return "EXPLICIT_CALL_TRANSFER";
+            case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
+                return "SET_PREFERRED_NETWORK_TYPE";
+            case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
+                return "GET_PREFERRED_NETWORK_TYPE";
+            case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
+                return "GET_NEIGHBORING_CELL_IDS";
+            case RIL_REQUEST_SET_LOCATION_UPDATES:
+                return "SET_LOCATION_UPDATES";
+            case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
+                return "CDMA_SET_SUBSCRIPTION_SOURCE";
+            case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
+                return "CDMA_SET_ROAMING_PREFERENCE";
+            case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
+                return "CDMA_QUERY_ROAMING_PREFERENCE";
+            case RIL_REQUEST_SET_TTY_MODE:
+                return "SET_TTY_MODE";
+            case RIL_REQUEST_QUERY_TTY_MODE:
+                return "QUERY_TTY_MODE";
+            case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
+                return "CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
+            case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:
+                return "CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
+            case RIL_REQUEST_CDMA_FLASH:
+                return "CDMA_FLASH";
+            case RIL_REQUEST_CDMA_BURST_DTMF:
+                return "CDMA_BURST_DTMF";
+            case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY:
+                return "CDMA_VALIDATE_AND_WRITE_AKEY";
+            case RIL_REQUEST_CDMA_SEND_SMS:
+                return "CDMA_SEND_SMS";
+            case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:
+                return "CDMA_SMS_ACKNOWLEDGE";
+            case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG:
+                return "GSM_GET_BROADCAST_CONFIG";
+            case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG:
+                return "GSM_SET_BROADCAST_CONFIG";
+            case RIL_REQUEST_GSM_BROADCAST_ACTIVATION:
+                return "GSM_BROADCAST_ACTIVATION";
+            case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG:
+                return "CDMA_GET_BROADCAST_CONFIG";
+            case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG:
+                return "CDMA_SET_BROADCAST_CONFIG";
+            case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION:
+                return "CDMA_BROADCAST_ACTIVATION";
+            case RIL_REQUEST_CDMA_SUBSCRIPTION:
+                return "CDMA_SUBSCRIPTION";
+            case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM:
+                return "CDMA_WRITE_SMS_TO_RUIM";
+            case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM:
+                return "CDMA_DELETE_SMS_ON_RUIM";
+            case RIL_REQUEST_DEVICE_IDENTITY:
+                return "DEVICE_IDENTITY";
+            case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
+                return "EXIT_EMERGENCY_CALLBACK_MODE";
+            case RIL_REQUEST_GET_SMSC_ADDRESS:
+                return "GET_SMSC_ADDRESS";
+            case RIL_REQUEST_SET_SMSC_ADDRESS:
+                return "SET_SMSC_ADDRESS";
+            case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS:
+                return "REPORT_SMS_MEMORY_STATUS";
+            case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING:
+                return "REPORT_STK_SERVICE_IS_RUNNING";
+            case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
+                return "CDMA_GET_SUBSCRIPTION_SOURCE";
+            case RIL_REQUEST_ISIM_AUTHENTICATION:
+                return "ISIM_AUTHENTICATION";
+            case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU:
+                return "ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
+            case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS:
+                return "STK_SEND_ENVELOPE_WITH_STATUS";
+            case RIL_REQUEST_VOICE_RADIO_TECH:
+                return "VOICE_RADIO_TECH";
+            case RIL_REQUEST_GET_CELL_INFO_LIST:
+                return "GET_CELL_INFO_LIST";
+            case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
+                return "SET_CELL_INFO_LIST_RATE";
+            case RIL_REQUEST_SET_INITIAL_ATTACH_APN:
+                return "SET_INITIAL_ATTACH_APN";
+            case RIL_REQUEST_IMS_REGISTRATION_STATE:
+                return "IMS_REGISTRATION_STATE";
+            case RIL_REQUEST_IMS_SEND_SMS:
+                return "IMS_SEND_SMS";
+            case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC:
+                return "SIM_TRANSMIT_APDU_BASIC";
+            case RIL_REQUEST_SIM_OPEN_CHANNEL:
+                return "SIM_OPEN_CHANNEL";
+            case RIL_REQUEST_SIM_CLOSE_CHANNEL:
+                return "SIM_CLOSE_CHANNEL";
+            case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
+                return "SIM_TRANSMIT_APDU_CHANNEL";
+            case RIL_REQUEST_NV_READ_ITEM:
+                return "NV_READ_ITEM";
+            case RIL_REQUEST_NV_WRITE_ITEM:
+                return "NV_WRITE_ITEM";
+            case RIL_REQUEST_NV_WRITE_CDMA_PRL:
+                return "NV_WRITE_CDMA_PRL";
+            case RIL_REQUEST_NV_RESET_CONFIG:
+                return "NV_RESET_CONFIG";
+            case RIL_REQUEST_SET_UICC_SUBSCRIPTION:
+                return "SET_UICC_SUBSCRIPTION";
+            case RIL_REQUEST_ALLOW_DATA:
+                return "ALLOW_DATA";
+            case RIL_REQUEST_GET_HARDWARE_CONFIG:
+                return "GET_HARDWARE_CONFIG";
+            case RIL_REQUEST_SIM_AUTHENTICATION:
+                return "SIM_AUTHENTICATION";
+            case RIL_REQUEST_GET_DC_RT_INFO:
+                return "GET_DC_RT_INFO";
+            case RIL_REQUEST_SET_DC_RT_INFO_RATE:
+                return "SET_DC_RT_INFO_RATE";
+            case RIL_REQUEST_SET_DATA_PROFILE:
+                return "SET_DATA_PROFILE";
+            case RIL_REQUEST_SHUTDOWN:
+                return "SHUTDOWN";
+            case RIL_REQUEST_GET_RADIO_CAPABILITY:
+                return "GET_RADIO_CAPABILITY";
+            case RIL_REQUEST_SET_RADIO_CAPABILITY:
+                return "SET_RADIO_CAPABILITY";
+            case RIL_REQUEST_START_LCE:
+                return "START_LCE";
+            case RIL_REQUEST_STOP_LCE:
+                return "STOP_LCE";
+            case RIL_REQUEST_PULL_LCEDATA:
+                return "PULL_LCEDATA";
+            case RIL_REQUEST_GET_ACTIVITY_INFO:
+                return "GET_ACTIVITY_INFO";
+            case RIL_REQUEST_SET_ALLOWED_CARRIERS:
+                return "SET_ALLOWED_CARRIERS";
+            case RIL_REQUEST_GET_ALLOWED_CARRIERS:
+                return "GET_ALLOWED_CARRIERS";
+            case RIL_REQUEST_SEND_DEVICE_STATE:
+                return "SEND_DEVICE_STATE";
+            case RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER:
+                return "SET_UNSOLICITED_RESPONSE_FILTER";
+            case RIL_REQUEST_SET_SIM_CARD_POWER:
+                return "SET_SIM_CARD_POWER";
+            case RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION:
+                return "SET_CARRIER_INFO_IMSI_ENCRYPTION";
+            case RIL_REQUEST_START_NETWORK_SCAN:
+                return "START_NETWORK_SCAN";
+            case RIL_REQUEST_STOP_NETWORK_SCAN:
+                return "STOP_NETWORK_SCAN";
+            case RIL_REQUEST_START_KEEPALIVE:
+                return "START_KEEPALIVE";
+            case RIL_REQUEST_STOP_KEEPALIVE:
+                return "STOP_KEEPALIVE";
+            case RIL_REQUEST_ENABLE_MODEM:
+                return "ENABLE_MODEM";
+            case RIL_REQUEST_GET_MODEM_STATUS:
+                return "GET_MODEM_STATUS";
+            case RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE:
+                return "CDMA_SEND_SMS_EXPECT_MORE";
+            case RIL_REQUEST_GET_SLOT_STATUS:
+                return "GET_SLOT_STATUS";
+            case RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING:
+                return "SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING";
+            case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA:
+                return "SET_SIGNAL_STRENGTH_REPORTING_CRITERIA";
+            case RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA:
+                return "SET_LINK_CAPACITY_REPORTING_CRITERIA";
+            case RIL_REQUEST_SET_PREFERRED_DATA_MODEM:
+                return "SET_PREFERRED_DATA_MODEM";
+            case RIL_REQUEST_EMERGENCY_DIAL:
+                return "EMERGENCY_DIAL";
+            case RIL_REQUEST_GET_PHONE_CAPABILITY:
+                return "GET_PHONE_CAPABILITY";
+            case RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG:
+                return "SWITCH_DUAL_SIM_CONFIG";
+            case RIL_REQUEST_ENABLE_UICC_APPLICATIONS:
+                return "ENABLE_UICC_APPLICATIONS";
+            case RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT:
+                return "GET_UICC_APPLICATIONS_ENABLEMENT";
+            case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS:
+                return "SET_SYSTEM_SELECTION_CHANNELS";
+            case RIL_REQUEST_GET_BARRING_INFO:
+                return "GET_BARRING_INFO";
+            case RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION:
+                return "ENTER_SIM_DEPERSONALIZATION";
+            case RIL_REQUEST_ENABLE_NR_DUAL_CONNECTIVITY:
+                return "ENABLE_NR_DUAL_CONNECTIVITY";
+            case RIL_REQUEST_IS_NR_DUAL_CONNECTIVITY_ENABLED:
+                return "IS_NR_DUAL_CONNECTIVITY_ENABLED";
+            case RIL_REQUEST_ALLOCATE_PDU_SESSION_ID:
+                return "ALLOCATE_PDU_SESSION_ID";
+            case RIL_REQUEST_RELEASE_PDU_SESSION_ID:
+                return "RELEASE_PDU_SESSION_ID";
+            case RIL_REQUEST_START_HANDOVER:
+                return "START_HANDOVER";
+            case RIL_REQUEST_CANCEL_HANDOVER:
+                return "CANCEL_HANDOVER";
+            case RIL_REQUEST_GET_SYSTEM_SELECTION_CHANNELS:
+                return "GET_SYSTEM_SELECTION_CHANNELS";
+            case RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES:
+                return "GET_HAL_DEVICE_CAPABILITIES";
+            case RIL_REQUEST_SET_DATA_THROTTLING:
+                return "SET_DATA_THROTTLING";
+            case RIL_REQUEST_SET_ALLOWED_NETWORK_TYPES_BITMAP:
+                return "SET_ALLOWED_NETWORK_TYPES_BITMAP";
+            case RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP:
+                return "GET_ALLOWED_NETWORK_TYPES_BITMAP";
+            case RIL_REQUEST_GET_SLICING_CONFIG:
+                return "GET_SLICING_CONFIG";
+            case RIL_REQUEST_GET_SIM_PHONEBOOK_RECORDS:
+                return "GET_SIM_PHONEBOOK_RECORDS";
+            case RIL_REQUEST_UPDATE_SIM_PHONEBOOK_RECORD:
+                return "UPDATE_SIM_PHONEBOOK_RECORD";
+            case RIL_REQUEST_GET_SIM_PHONEBOOK_CAPACITY:
+                return "GET_SIM_PHONEBOOK_CAPACITY";
+            default: return "<unknown request>";
+        }
+    }
+
+    @UnsupportedAppUsage
+    static String responseToString(int request) {
+        switch(request) {
+            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
+                return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
+            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
+                return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
+            case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED:
+                return "UNSOL_RESPONSE_NETWORK_STATE_CHANGED";
+            case RIL_UNSOL_RESPONSE_NEW_SMS:
+                return "UNSOL_RESPONSE_NEW_SMS";
+            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
+                return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
+            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
+                return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
+            case RIL_UNSOL_ON_USSD:
+                return "UNSOL_ON_USSD";
+            case RIL_UNSOL_ON_USSD_REQUEST:
+                return "UNSOL_ON_USSD_REQUEST";
+            case RIL_UNSOL_NITZ_TIME_RECEIVED:
+                return "UNSOL_NITZ_TIME_RECEIVED";
+            case RIL_UNSOL_SIGNAL_STRENGTH:
+                return "UNSOL_SIGNAL_STRENGTH";
+            case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
+                return "UNSOL_DATA_CALL_LIST_CHANGED";
+            case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
+                return "UNSOL_SUPP_SVC_NOTIFICATION";
+            case RIL_UNSOL_STK_SESSION_END:
+                return "UNSOL_STK_SESSION_END";
+            case RIL_UNSOL_STK_PROACTIVE_COMMAND:
+                return "UNSOL_STK_PROACTIVE_COMMAND";
+            case RIL_UNSOL_STK_EVENT_NOTIFY:
+                return "UNSOL_STK_EVENT_NOTIFY";
+            case RIL_UNSOL_STK_CALL_SETUP:
+                return "UNSOL_STK_CALL_SETUP";
+            case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
+                return "UNSOL_SIM_SMS_STORAGE_FULL";
+            case RIL_UNSOL_SIM_REFRESH:
+                return "UNSOL_SIM_REFRESH";
+            case RIL_UNSOL_CALL_RING:
+                return "UNSOL_CALL_RING";
+            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
+                return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
+            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
+                return "UNSOL_RESPONSE_CDMA_NEW_SMS";
+            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
+                return "UNSOL_RESPONSE_NEW_BROADCAST_SMS";
+            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
+                return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
+            case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
+                return "UNSOL_RESTRICTED_STATE_CHANGED";
+            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
+                return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
+            case RIL_UNSOL_CDMA_CALL_WAITING:
+                return "UNSOL_CDMA_CALL_WAITING";
+            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
+                return "UNSOL_CDMA_OTA_PROVISION_STATUS";
+            case RIL_UNSOL_CDMA_INFO_REC:
+                return "UNSOL_CDMA_INFO_REC";
+            case RIL_UNSOL_OEM_HOOK_RAW:
+                return "UNSOL_OEM_HOOK_RAW";
+            case RIL_UNSOL_RINGBACK_TONE:
+                return "UNSOL_RINGBACK_TONE";
+            case RIL_UNSOL_RESEND_INCALL_MUTE:
+                return "UNSOL_RESEND_INCALL_MUTE";
+            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
+                return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
+            case RIL_UNSOl_CDMA_PRL_CHANGED:
+                return "UNSOL_CDMA_PRL_CHANGED";
+            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
+                return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
+            case RIL_UNSOL_RIL_CONNECTED:
+                return "UNSOL_RIL_CONNECTED";
+            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED:
+                return "UNSOL_VOICE_RADIO_TECH_CHANGED";
+            case RIL_UNSOL_CELL_INFO_LIST:
+                return "UNSOL_CELL_INFO_LIST";
+            case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED:
+                return "UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED";
+            case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED:
+                return "UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED";
+            case RIL_UNSOL_SRVCC_STATE_NOTIFY:
+                return "UNSOL_SRVCC_STATE_NOTIFY";
+            case RIL_UNSOL_HARDWARE_CONFIG_CHANGED:
+                return "UNSOL_HARDWARE_CONFIG_CHANGED";
+            case RIL_UNSOL_DC_RT_INFO_CHANGED:
+                return "UNSOL_DC_RT_INFO_CHANGED";
+            case RIL_UNSOL_RADIO_CAPABILITY:
+                return "UNSOL_RADIO_CAPABILITY";
+            case RIL_UNSOL_ON_SS:
+                return "UNSOL_ON_SS";
+            case RIL_UNSOL_STK_CC_ALPHA_NOTIFY:
+                return "UNSOL_STK_CC_ALPHA_NOTIFY";
+            case RIL_UNSOL_LCEDATA_RECV:
+                return "UNSOL_LCE_INFO_RECV";
+            case RIL_UNSOL_PCO_DATA:
+                return "UNSOL_PCO_DATA";
+            case RIL_UNSOL_MODEM_RESTART:
+                return "UNSOL_MODEM_RESTART";
+            case RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION:
+                return "UNSOL_CARRIER_INFO_IMSI_ENCRYPTION";
+            case RIL_UNSOL_NETWORK_SCAN_RESULT:
+                return "UNSOL_NETWORK_SCAN_RESULT";
+            case RIL_UNSOL_KEEPALIVE_STATUS:
+                return "UNSOL_KEEPALIVE_STATUS";
+            case RIL_UNSOL_UNTHROTTLE_APN:
+                return "UNSOL_UNTHROTTLE_APN";
+            case RIL_UNSOL_ICC_SLOT_STATUS:
+                return "UNSOL_ICC_SLOT_STATUS";
+            case RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG:
+                return "UNSOL_PHYSICAL_CHANNEL_CONFIG";
+            case RIL_UNSOL_EMERGENCY_NUMBER_LIST:
+                return "UNSOL_EMERGENCY_NUMBER_LIST";
+            case RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED:
+                return "UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED";
+            case RIL_UNSOL_REGISTRATION_FAILED:
+                return "UNSOL_REGISTRATION_FAILED";
+            case RIL_UNSOL_BARRING_INFO_CHANGED:
+                return "UNSOL_BARRING_INFO_CHANGED";
+            case RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_CHANGED:
+                return "UNSOL_RESPONSE_SIM_PHONEBOOK_CHANGED";
+            case RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_RECORDS_RECEIVED:
+                return "UNSOL_RESPONSE_SIM_PHONEBOOK_RECORDS_RECEIVED";
+            default:
+                return "<unknown response>";
+        }
+    }
+
+    @UnsupportedAppUsage
     void riljLog(String msg) {
         Rlog.d(RILJ_LOG_TAG, msg + (" [PHONE" + mPhoneId + "]"));
     }
@@ -5786,30 +7126,32 @@
         Rlog.e(RILJ_LOG_TAG, msg + (" [PHONE" + mPhoneId + "]"));
     }
 
+    void riljLoge(String msg, Exception e) {
+        Rlog.e(RILJ_LOG_TAG, msg + (" [PHONE" + mPhoneId + "]"), e);
+    }
+
     void riljLogv(String msg) {
         Rlog.v(RILJ_LOG_TAG, msg + (" [PHONE" + mPhoneId + "]"));
     }
 
     @UnsupportedAppUsage
     void unsljLog(int response) {
-        riljLog("[UNSL]< " + RILUtils.responseToString(response));
+        riljLog("[UNSL]< " + responseToString(response));
     }
 
     @UnsupportedAppUsage
     void unsljLogMore(int response, String more) {
-        riljLog("[UNSL]< " + RILUtils.responseToString(response) + " " + more);
+        riljLog("[UNSL]< " + responseToString(response) + " " + more);
     }
 
     @UnsupportedAppUsage
     void unsljLogRet(int response, Object ret) {
-        riljLog("[UNSL]< " + RILUtils.responseToString(response) + " "
-                + retToString(response, ret));
+        riljLog("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
     }
 
     @UnsupportedAppUsage
     void unsljLogvRet(int response, Object ret) {
-        riljLogv("[UNSL]< " + RILUtils.responseToString(response) + " "
-                + retToString(response, ret));
+        riljLogv("[UNSL]< " + responseToString(response) + " " + retToString(response, ret));
     }
 
     @Override
@@ -5839,7 +7181,7 @@
             pw.println(" mRequestList count=" + count);
             for (int i = 0; i < count; i++) {
                 RILRequest rr = mRequestList.valueAt(i);
-                pw.println("  [" + rr.mSerial + "] " + RILUtils.requestToString(rr.mRequest));
+                pw.println("  [" + rr.mSerial + "] " + requestToString(rr.mRequest));
             }
         }
         pw.println(" mLastNITZTimeInfo=" + Arrays.toString(mLastNITZTimeInfo));
@@ -5852,6 +7194,180 @@
         return mClientWakelockTracker.getClientRequestStats();
     }
 
+    /** Append the data to the end of an ArrayList */
+    public static void appendPrimitiveArrayToArrayList(byte[] src, ArrayList<Byte> dst) {
+        for (byte b : src) {
+            dst.add(b);
+        }
+    }
+
+    public static ArrayList<Byte> primitiveArrayToArrayList(byte[] arr) {
+        ArrayList<Byte> arrayList = new ArrayList<>(arr.length);
+        for (byte b : arr) {
+            arrayList.add(b);
+        }
+        return arrayList;
+    }
+
+    /** Convert a primitive int array to an ArrayList<Integer>. */
+    public static ArrayList<Integer> primitiveArrayToArrayList(int[] arr) {
+        ArrayList<Integer> arrayList = new ArrayList<>(arr.length);
+        for (int i : arr) {
+            arrayList.add(i);
+        }
+        return arrayList;
+    }
+
+    /** Convert an ArrayList of Bytes to an exactly-sized primitive array */
+    public static byte[] arrayListToPrimitiveArray(ArrayList<Byte> bytes) {
+        byte[] ret = new byte[bytes.size()];
+        for (int i = 0; i < ret.length; i++) {
+            ret[i] = bytes.get(i);
+        }
+        return ret;
+    }
+
+    static ArrayList<HardwareConfig> convertHalHwConfigList(
+            ArrayList<android.hardware.radio.V1_0.HardwareConfig> hwListRil,
+            RIL ril) {
+        int num;
+        ArrayList<HardwareConfig> response;
+        HardwareConfig hw;
+
+        num = hwListRil.size();
+        response = new ArrayList<HardwareConfig>(num);
+
+        if (RILJ_LOGV) {
+            ril.riljLog("convertHalHwConfigList: num=" + num);
+        }
+        for (android.hardware.radio.V1_0.HardwareConfig hwRil : hwListRil) {
+            int type = hwRil.type;
+            switch(type) {
+                case HardwareConfig.DEV_HARDWARE_TYPE_MODEM: {
+                    hw = new HardwareConfig(type);
+                    HardwareConfigModem hwModem = hwRil.modem.get(0);
+                    hw.assignModem(hwRil.uuid, hwRil.state, hwModem.rilModel, hwModem.rat,
+                            hwModem.maxVoice, hwModem.maxData, hwModem.maxStandby);
+                    break;
+                }
+                case HardwareConfig.DEV_HARDWARE_TYPE_SIM: {
+                    hw = new HardwareConfig(type);
+                    hw.assignSim(hwRil.uuid, hwRil.state, hwRil.sim.get(0).modemUuid);
+                    break;
+                }
+                default: {
+                    throw new RuntimeException(
+                            "RIL_REQUEST_GET_HARDWARE_CONFIG invalid hardward type:" + type);
+                }
+            }
+
+            response.add(hw);
+        }
+
+        return response;
+    }
+
+    static RadioCapability convertHalRadioCapability(
+            android.hardware.radio.V1_0.RadioCapability rcRil, RIL ril) {
+        int session = rcRil.session;
+        int phase = rcRil.phase;
+        // convert to public bitmask {@link TelephonyManager.NetworkTypeBitMask}
+        int rat = convertToNetworkTypeBitMask(rcRil.raf);
+        String logicModemUuid = rcRil.logicalModemUuid;
+        int status = rcRil.status;
+
+        ril.riljLog("convertHalRadioCapability: session=" + session +
+                ", phase=" + phase +
+                ", rat=" + rat +
+                ", logicModemUuid=" + logicModemUuid +
+                ", status=" + status + ", rcRil.raf=" + rcRil.raf);
+        RadioCapability rc = new RadioCapability(
+                ril.mPhoneId, session, phase, rat, logicModemUuid, status);
+        return rc;
+    }
+
+    static List<LinkCapacityEstimate> convertHalLceData(LceDataInfo halData, RIL ril) {
+        final List<LinkCapacityEstimate> lceList = new ArrayList<>();
+        lceList.add(new LinkCapacityEstimate(LinkCapacityEstimate.LCE_TYPE_COMBINED,
+                halData.lastHopCapacityKbps,
+                LinkCapacityEstimate.INVALID));
+        ril.riljLog("LCE capacity information received:" + lceList);
+        return lceList;
+    }
+
+    static List<LinkCapacityEstimate> convertHalLceData(
+            android.hardware.radio.V1_2.LinkCapacityEstimate halData, RIL ril) {
+        final List<LinkCapacityEstimate> lceList = new ArrayList<>();
+        lceList.add(new LinkCapacityEstimate(LinkCapacityEstimate.LCE_TYPE_COMBINED,
+                halData.downlinkCapacityKbps,
+                halData.uplinkCapacityKbps));
+        ril.riljLog("LCE capacity information received:" + lceList);
+        return lceList;
+    }
+
+    static List<LinkCapacityEstimate> convertHalLceData(
+            android.hardware.radio.V1_6.LinkCapacityEstimate halData, RIL ril) {
+        final List<LinkCapacityEstimate> lceList = new ArrayList<>();
+        int primaryDownlinkCapacityKbps = halData.downlinkCapacityKbps;
+        int primaryUplinkCapacityKbps = halData.uplinkCapacityKbps;
+        if (primaryDownlinkCapacityKbps != LinkCapacityEstimate.INVALID
+                && halData.secondaryDownlinkCapacityKbps != LinkCapacityEstimate.INVALID) {
+            primaryDownlinkCapacityKbps =
+                    halData.downlinkCapacityKbps - halData.secondaryDownlinkCapacityKbps;
+        }
+        if (primaryUplinkCapacityKbps != LinkCapacityEstimate.INVALID
+                && halData.secondaryUplinkCapacityKbps != LinkCapacityEstimate.INVALID) {
+            primaryUplinkCapacityKbps =
+                    halData.uplinkCapacityKbps - halData.secondaryUplinkCapacityKbps;
+        }
+
+        lceList.add(new LinkCapacityEstimate(LinkCapacityEstimate.LCE_TYPE_PRIMARY,
+                primaryDownlinkCapacityKbps,
+                primaryUplinkCapacityKbps));
+        lceList.add(new LinkCapacityEstimate(LinkCapacityEstimate.LCE_TYPE_SECONDARY,
+                halData.secondaryDownlinkCapacityKbps,
+                halData.secondaryUplinkCapacityKbps));
+        ril.riljLog("LCE capacity information received:" + lceList);
+        return lceList;
+    }
+
+    /**
+     * Convert CellInfo defined in 1.0/types.hal to CellInfo type.
+     * @param records List of CellInfo defined in 1.0/types.hal
+     * @return List of converted CellInfo object
+     */
+    @VisibleForTesting
+    public static ArrayList<CellInfo> convertHalCellInfoList(
+            ArrayList<android.hardware.radio.V1_0.CellInfo> records) {
+        ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
+
+        final long nanotime = SystemClock.elapsedRealtimeNanos();
+        for (android.hardware.radio.V1_0.CellInfo record : records) {
+            record.timeStamp = nanotime;
+            response.add(CellInfo.create(record));
+        }
+
+        return response;
+    }
+
+    /**
+     * Convert CellInfo defined in 1.2/types.hal to CellInfo type.
+     * @param records List of CellInfo defined in 1.2/types.hal
+     * @return List of converted CellInfo object
+     */
+    @VisibleForTesting
+    public static ArrayList<CellInfo> convertHalCellInfoList_1_2(
+            ArrayList<android.hardware.radio.V1_2.CellInfo> records) {
+        ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
+
+        final long nanotime = SystemClock.elapsedRealtimeNanos();
+        for (android.hardware.radio.V1_2.CellInfo record : records) {
+            record.timeStamp = nanotime;
+            response.add(CellInfo.create(record));
+        }
+        return response;
+    }
+
     /**
      * Fixup for SignalStrength 1.0 to Assume GSM to WCDMA when
      * The current RAT type is one of the UMTS RATs.
@@ -5905,6 +7421,333 @@
     }
 
     /**
+     * Convert CellInfo defined in 1.4/types.hal to CellInfo type.
+     * @param records List of CellInfo defined in 1.4/types.hal.
+     * @return List of converted CellInfo object.
+     */
+    @VisibleForTesting
+    public static ArrayList<CellInfo> convertHalCellInfoList_1_4(
+            ArrayList<android.hardware.radio.V1_4.CellInfo> records) {
+        ArrayList<CellInfo> response = new ArrayList<CellInfo>(records.size());
+
+        final long nanotime = SystemClock.elapsedRealtimeNanos();
+        for (android.hardware.radio.V1_4.CellInfo record : records) {
+            response.add(CellInfo.create(record, nanotime));
+        }
+        return response;
+    }
+
+    /**
+     * Convert CellInfo defined in 1.5/types.hal to CellInfo type.
+     * @param records List of CellInfo defined in 1.5/types.hal.
+     * @return List of converted CellInfo object.
+     */
+    @VisibleForTesting
+    public static ArrayList<CellInfo> convertHalCellInfoList_1_5(
+            ArrayList<android.hardware.radio.V1_5.CellInfo> records) {
+        ArrayList<CellInfo> response = new ArrayList<>(records.size());
+
+        final long nanotime = SystemClock.elapsedRealtimeNanos();
+        for (android.hardware.radio.V1_5.CellInfo record : records) {
+            response.add(CellInfo.create(record, nanotime));
+        }
+        return response;
+    }
+
+    /**
+     * Convert CellInfo defined in 1.6/types.hal to CellInfo type.
+     * @param records List of CellInfo defined in 1.6/types.hal.
+     * @return List of converted CellInfo object.
+     */
+    @VisibleForTesting
+    public static ArrayList<CellInfo> convertHalCellInfoList_1_6(
+            ArrayList<android.hardware.radio.V1_6.CellInfo> records) {
+        ArrayList<CellInfo> response = new ArrayList<>(records.size());
+
+        final long nanotime = SystemClock.elapsedRealtimeNanos();
+        for (android.hardware.radio.V1_6.CellInfo record : records) {
+            response.add(CellInfo.create(record, nanotime));
+        }
+        return response;
+    }
+
+    private static LinkAddress createLinkAddressFromString(String addressString) {
+        return createLinkAddressFromString(addressString, 0, LinkAddress.LIFETIME_UNKNOWN,
+                LinkAddress.LIFETIME_UNKNOWN);
+    }
+
+    private static LinkAddress createLinkAddressFromString(String addressString, int properties,
+            long deprecationTime, long expirationTime) {
+        addressString = addressString.trim();
+        InetAddress address = null;
+        int prefixLength = -1;
+        try {
+            String[] pieces = addressString.split("/", 2);
+            address = InetAddresses.parseNumericAddress(pieces[0]);
+            if (pieces.length == 1) {
+                prefixLength = (address instanceof Inet4Address) ? 32 : 128;
+            } else if (pieces.length == 2) {
+                prefixLength = Integer.parseInt(pieces[1]);
+            }
+        } catch (NullPointerException e) {            // Null string.
+        } catch (ArrayIndexOutOfBoundsException e) {  // No prefix length.
+        } catch (NumberFormatException e) {           // Non-numeric prefix.
+        } catch (IllegalArgumentException e) {        // Invalid IP address.
+        }
+
+        if (address == null || prefixLength == -1) {
+            throw new IllegalArgumentException("Invalid link address " + addressString);
+        }
+
+        return new LinkAddress(address, prefixLength, properties, 0,
+                deprecationTime, expirationTime);
+    }
+
+    /**
+     * Convert SetupDataCallResult defined in 1.0, 1.4, 1.5 or 1.6 types.hal into DataCallResponse
+     * @param dcResult setup data call result
+     * @return converted DataCallResponse object
+     */
+    @VisibleForTesting
+    public static DataCallResponse convertDataCallResult(Object dcResult) {
+        if (dcResult == null) return null;
+
+        int cause, cid, active, mtu, mtuV4, mtuV6;
+        long suggestedRetryTime;
+        String ifname;
+        int protocolType;
+        String[] addresses = null;
+        String[] dnses = null;
+        String[] gateways = null;
+        String[] pcscfs = null;
+        Qos defaultQos = null;
+
+        @HandoverFailureMode
+        int handoverFailureMode = DataCallResponse.HANDOVER_FAILURE_MODE_LEGACY;
+
+        int pduSessionId = DataCallResponse.PDU_SESSION_ID_NOT_SET;
+
+        List<LinkAddress> laList = new ArrayList<>();
+        List<QosBearerSession> qosSessions = new ArrayList<>();
+        NetworkSliceInfo sliceInfo = null;
+        List<TrafficDescriptor> trafficDescriptors = new ArrayList<>();
+
+        if (dcResult instanceof android.hardware.radio.V1_0.SetupDataCallResult) {
+            final android.hardware.radio.V1_0.SetupDataCallResult result =
+                    (android.hardware.radio.V1_0.SetupDataCallResult) dcResult;
+            cause = result.status;
+            suggestedRetryTime = result.suggestedRetryTime;
+            cid = result.cid;
+            active = result.active;
+            protocolType = ApnSetting.getProtocolIntFromString(result.type);
+            ifname = result.ifname;
+            if (!TextUtils.isEmpty(result.addresses)) {
+                addresses = result.addresses.split("\\s+");
+            }
+            if (!TextUtils.isEmpty(result.dnses)) {
+                dnses = result.dnses.split("\\s+");
+            }
+            if (!TextUtils.isEmpty(result.gateways)) {
+                gateways = result.gateways.split("\\s+");
+            }
+            if (!TextUtils.isEmpty(result.pcscf)) {
+                pcscfs = result.pcscf.split("\\s+");
+            }
+            mtu = mtuV4 = mtuV6 = result.mtu;
+            if (addresses != null) {
+                for (String address : addresses) {
+                    laList.add(createLinkAddressFromString(address));
+                }
+            }
+        } else if (dcResult instanceof android.hardware.radio.V1_4.SetupDataCallResult) {
+            final android.hardware.radio.V1_4.SetupDataCallResult result =
+                    (android.hardware.radio.V1_4.SetupDataCallResult) dcResult;
+            cause = result.cause;
+            suggestedRetryTime = result.suggestedRetryTime;
+            cid = result.cid;
+            active = result.active;
+            protocolType = result.type;
+            ifname = result.ifname;
+            addresses = result.addresses.stream().toArray(String[]::new);
+            dnses = result.dnses.stream().toArray(String[]::new);
+            gateways = result.gateways.stream().toArray(String[]::new);
+            pcscfs = result.pcscf.stream().toArray(String[]::new);
+            mtu = mtuV4 = mtuV6 = result.mtu;
+            if (addresses != null) {
+                for (String address : addresses) {
+                    laList.add(createLinkAddressFromString(address));
+                }
+            }
+        } else if (dcResult instanceof android.hardware.radio.V1_5.SetupDataCallResult) {
+            final android.hardware.radio.V1_5.SetupDataCallResult result =
+                    (android.hardware.radio.V1_5.SetupDataCallResult) dcResult;
+            cause = result.cause;
+            suggestedRetryTime = result.suggestedRetryTime;
+            cid = result.cid;
+            active = result.active;
+            protocolType = result.type;
+            ifname = result.ifname;
+            laList = result.addresses.stream().map(la -> createLinkAddressFromString(
+                    la.address, la.properties, la.deprecationTime, la.expirationTime))
+                    .collect(Collectors.toList());
+
+            dnses = result.dnses.stream().toArray(String[]::new);
+            gateways = result.gateways.stream().toArray(String[]::new);
+            pcscfs = result.pcscf.stream().toArray(String[]::new);
+            mtu = Math.max(result.mtuV4, result.mtuV6);
+            mtuV4 = result.mtuV4;
+            mtuV6 = result.mtuV6;
+        } else if (dcResult instanceof android.hardware.radio.V1_6.SetupDataCallResult) {
+            final android.hardware.radio.V1_6.SetupDataCallResult result =
+                    (android.hardware.radio.V1_6.SetupDataCallResult) dcResult;
+            cause = result.cause;
+            suggestedRetryTime = result.suggestedRetryTime;
+            cid = result.cid;
+            active = result.active;
+            protocolType = result.type;
+            ifname = result.ifname;
+            laList = result.addresses.stream().map(la -> createLinkAddressFromString(
+                    la.address, la.properties, la.deprecationTime, la.expirationTime))
+                    .collect(Collectors.toList());
+            dnses = result.dnses.stream().toArray(String[]::new);
+            gateways = result.gateways.stream().toArray(String[]::new);
+            pcscfs = result.pcscf.stream().toArray(String[]::new);
+            mtu = Math.max(result.mtuV4, result.mtuV6);
+            mtuV4 = result.mtuV4;
+            mtuV6 = result.mtuV6;
+            handoverFailureMode = result.handoverFailureMode;
+            pduSessionId = result.pduSessionId;
+            defaultQos = Qos.create(result.defaultQos);
+            qosSessions = result.qosSessions.stream().map(session ->
+                    QosBearerSession.create(session)).collect(Collectors.toList());
+            sliceInfo = convertToSliceInfo(result.sliceInfo);
+            trafficDescriptors = result.trafficDescriptors.stream().map(td ->
+                    convertToTrafficDescriptor(td)).collect(Collectors.toList());
+        } else {
+            Rlog.e(RILJ_LOG_TAG, "Unsupported SetupDataCallResult " + dcResult);
+            return null;
+        }
+
+        // Process dns
+        List<InetAddress> dnsList = new ArrayList<>();
+        if (dnses != null) {
+            for (String dns : dnses) {
+                dns = dns.trim();
+                InetAddress ia;
+                try {
+                    ia = InetAddresses.parseNumericAddress(dns);
+                    dnsList.add(ia);
+                } catch (IllegalArgumentException e) {
+                    Rlog.e(RILJ_LOG_TAG, "Unknown dns: " + dns, e);
+                }
+            }
+        }
+
+        // Process gateway
+        List<InetAddress> gatewayList = new ArrayList<>();
+        if (gateways != null) {
+            for (String gateway : gateways) {
+                gateway = gateway.trim();
+                InetAddress ia;
+                try {
+                    ia = InetAddresses.parseNumericAddress(gateway);
+                    gatewayList.add(ia);
+                } catch (IllegalArgumentException e) {
+                    Rlog.e(RILJ_LOG_TAG, "Unknown gateway: " + gateway, e);
+                }
+            }
+        }
+
+        // Process gateway
+        List<InetAddress> pcscfList = new ArrayList<>();
+        if (pcscfs != null) {
+            for (String pcscf : pcscfs) {
+                pcscf = pcscf.trim();
+                InetAddress ia;
+                try {
+                    ia = InetAddresses.parseNumericAddress(pcscf);
+                    pcscfList.add(ia);
+                } catch (IllegalArgumentException e) {
+                    Rlog.e(RILJ_LOG_TAG, "Unknown pcscf: " + pcscf, e);
+                }
+            }
+        }
+
+        return new DataCallResponse.Builder()
+                .setCause(cause)
+                .setRetryDurationMillis(suggestedRetryTime)
+                .setId(cid)
+                .setLinkStatus(active)
+                .setProtocolType(protocolType)
+                .setInterfaceName(ifname)
+                .setAddresses(laList)
+                .setDnsAddresses(dnsList)
+                .setGatewayAddresses(gatewayList)
+                .setPcscfAddresses(pcscfList)
+                .setMtu(mtu)
+                .setMtuV4(mtuV4)
+                .setMtuV6(mtuV6)
+                .setHandoverFailureMode(handoverFailureMode)
+                .setPduSessionId(pduSessionId)
+                .setDefaultQos(defaultQos)
+                .setQosBearerSessions(qosSessions)
+                .setSliceInfo(sliceInfo)
+                .setTrafficDescriptors(trafficDescriptors)
+                .build();
+    }
+
+    private static NetworkSliceInfo convertToSliceInfo(OptionalSliceInfo optionalSliceInfo) {
+        if (optionalSliceInfo.getDiscriminator() == OptionalSliceInfo.hidl_discriminator.noinit) {
+            return null;
+        }
+
+        android.hardware.radio.V1_6.SliceInfo si = optionalSliceInfo.value();
+        NetworkSliceInfo.Builder builder =
+                new NetworkSliceInfo.Builder()
+                .setSliceServiceType(si.sst)
+                .setMappedHplmnSliceServiceType(si.mappedHplmnSst);
+        if (si.sliceDifferentiator != NetworkSliceInfo.SLICE_DIFFERENTIATOR_NO_SLICE) {
+            builder
+                .setSliceDifferentiator(si.sliceDifferentiator)
+                .setMappedHplmnSliceDifferentiator(si.mappedHplmnSD);
+        }
+        return builder.build();
+    }
+
+    private static TrafficDescriptor convertToTrafficDescriptor(
+            android.hardware.radio.V1_6.TrafficDescriptor td) {
+        String dnn = td.dnn.getDiscriminator() == OptionalDnn.hidl_discriminator.noinit
+                ? null : td.dnn.value();
+        byte[] osAppId = td.osAppId.getDiscriminator() == OptionalOsAppId.hidl_discriminator.noinit
+                ? null : arrayListToPrimitiveArray(td.osAppId.value().osAppId);
+        TrafficDescriptor.Builder builder = new TrafficDescriptor.Builder();
+        if (dnn != null) {
+            builder.setDataNetworkName(dnn);
+        }
+        if (osAppId != null) {
+            builder.setOsAppId(osAppId);
+        }
+        return builder.build();
+    }
+
+    /**
+     * Convert SetupDataCallResult defined in 1.0 or 1.4/types.hal into DataCallResponse
+     * @param dataCallResultList List of SetupDataCallResult defined in 1.0 or 1.4/types.hal
+     * @return List of converted DataCallResponse object
+     */
+    @VisibleForTesting
+    public static ArrayList<DataCallResponse> convertDataCallResultList(
+            List<? extends Object> dataCallResultList) {
+        ArrayList<DataCallResponse> response =
+                new ArrayList<DataCallResponse>(dataCallResultList.size());
+
+        for (Object obj : dataCallResultList) {
+            response.add(convertDataCallResult(obj));
+        }
+        return response;
+    }
+
+    /**
      * Get the HAL version.
      *
      * @return the current HalVersion
@@ -5912,25 +7755,4 @@
     public HalVersion getHalVersion() {
         return mRadioVersion;
     }
-
-    private static String serviceToString(int service) {
-        switch (service) {
-            case RADIO_SERVICE:
-                return "RADIO";
-            case DATA_SERVICE:
-                return "DATA";
-            case MESSAGING_SERVICE:
-                return "MESSAGING";
-            case MODEM_SERVICE:
-                return "MODEM";
-            case NETWORK_SERVICE:
-                return "NETWORK";
-            case SIM_SERVICE:
-                return "SIM";
-            case VOICE_SERVICE:
-                return "VOICE";
-            default:
-                return "UNKNOWN:" + service;
-        }
-    }
 }
diff --git a/src/java/com/android/internal/telephony/RILRequest.java b/src/java/com/android/internal/telephony/RILRequest.java
index 654b8cf..fff8de6 100644
--- a/src/java/com/android/internal/telephony/RILRequest.java
+++ b/src/java/com/android/internal/telephony/RILRequest.java
@@ -238,7 +238,7 @@
         final Message result = mResult;
         if (RIL.RILJ_LOGD) {
             Rlog.d(LOG_TAG, serialString() + "< "
-                    + RILUtils.requestToString(mRequest)
+                    + RIL.requestToString(mRequest)
                     + " error: " + ex + " ret=" + RIL.retToString(mRequest, ret)
                     + " result=" + result);
         }
@@ -248,9 +248,4 @@
             result.sendToTarget();
         }
     }
-
-    @Override
-    public String toString() {
-        return serialString() + ": " + RILUtils.requestToString(mRequest);
-    }
 }
diff --git a/src/java/com/android/internal/telephony/RILUtils.java b/src/java/com/android/internal/telephony/RILUtils.java
deleted file mode 100644
index 61f1e82..0000000
--- a/src/java/com/android/internal/telephony/RILUtils.java
+++ /dev/null
@@ -1,5331 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static android.telephony.TelephonyManager.CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE;
-import static android.telephony.TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED;
-import static android.telephony.TelephonyManager.CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE;
-import static android.telephony.TelephonyManager.CAPABILITY_SIM_PHONEBOOK_IN_MODEM;
-import static android.telephony.TelephonyManager.CAPABILITY_SLICING_CONFIG_SUPPORTED;
-import static android.telephony.TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING;
-import static android.telephony.TelephonyManager.CAPABILITY_USES_ALLOWED_NETWORK_TYPES_BITMASK;
-
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ALLOCATE_PDU_SESSION_ID;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ALLOW_DATA;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ANSWER;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_BASEBAND_VERSION;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CANCEL_HANDOVER;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CANCEL_USSD;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_BROADCAST_ACTIVATION;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_BURST_DTMF;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_FLASH;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_SEND_SMS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_SUBSCRIPTION;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CHANGE_BARRING_PASSWORD;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CHANGE_SIM_PIN;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CHANGE_SIM_PIN2;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_CONFERENCE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DATA_CALL_LIST;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DATA_REGISTRATION_STATE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DEACTIVATE_DATA_CALL;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DELETE_SMS_ON_SIM;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DEVICE_IDENTITY;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DIAL;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DTMF;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DTMF_START;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DTMF_STOP;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_EMERGENCY_DIAL;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENABLE_MODEM;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENABLE_NR_DUAL_CONNECTIVITY;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENABLE_UICC_APPLICATIONS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENABLE_VONR;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_SIM_PIN;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_SIM_PIN2;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_SIM_PUK;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_SIM_PUK2;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_EXPLICIT_CALL_TRANSFER;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_ACTIVITY_INFO;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_ALLOWED_CARRIERS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_BARRING_INFO;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_CELL_INFO_LIST;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_CLIR;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_CURRENT_CALLS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_DC_RT_INFO;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_HARDWARE_CONFIG;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_IMEI;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_IMEISV;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_IMSI;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_MODEM_STATUS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_MUTE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_NEIGHBORING_CELL_IDS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PHONE_CAPABILITY;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_RADIO_CAPABILITY;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_PHONEBOOK_CAPACITY;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_PHONEBOOK_RECORDS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SIM_STATUS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SLICING_CONFIG;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SLOT_STATUS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SMSC_ADDRESS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_SYSTEM_SELECTION_CHANNELS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GET_USAGE_SETTING;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GSM_BROADCAST_ACTIVATION;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GSM_GET_BROADCAST_CONFIG;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_GSM_SET_BROADCAST_CONFIG;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_HANGUP;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_IMS_REGISTRATION_STATE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_IMS_SEND_SMS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ISIM_AUTHENTICATION;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_IS_NR_DUAL_CONNECTIVITY_ENABLED;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_IS_VONR_ENABLED;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_LAST_CALL_FAIL_CAUSE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_NV_READ_ITEM;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_NV_RESET_CONFIG;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_NV_WRITE_CDMA_PRL;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_NV_WRITE_ITEM;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_OEM_HOOK_RAW;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_OEM_HOOK_STRINGS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_OPERATOR;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_PULL_LCEDATA;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_QUERY_AVAILABLE_NETWORKS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_QUERY_CALL_FORWARD_STATUS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_QUERY_CALL_WAITING;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_QUERY_CLIP;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_QUERY_FACILITY_LOCK;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_QUERY_TTY_MODE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_RADIO_POWER;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_RELEASE_PDU_SESSION_ID;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_REPORT_SMS_MEMORY_STATUS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_RESET_RADIO;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SCREEN_STATE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SEND_DEVICE_STATE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SEND_SMS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SEND_SMS_EXPECT_MORE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SEND_USSD;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SEPARATE_CONNECTION;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SETUP_DATA_CALL;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_ALLOWED_CARRIERS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_ALLOWED_NETWORK_TYPES_BITMAP;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_BAND_MODE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_CALL_FORWARD;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_CALL_WAITING;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_CLIR;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_DATA_PROFILE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_DATA_THROTTLING;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_DC_RT_INFO_RATE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_FACILITY_LOCK;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_INITIAL_ATTACH_APN;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_LOCATION_UPDATES;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_MUTE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_PREFERRED_DATA_MODEM;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_RADIO_CAPABILITY;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_SIM_CARD_POWER;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_SMSC_ADDRESS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_TTY_MODE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_UICC_SUBSCRIPTION;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SET_USAGE_SETTING;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SHUTDOWN;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SIGNAL_STRENGTH;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SIM_AUTHENTICATION;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SIM_CLOSE_CHANNEL;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SIM_IO;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SIM_OPEN_CHANNEL;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SMS_ACKNOWLEDGE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_START_HANDOVER;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_START_KEEPALIVE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_START_LCE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_START_NETWORK_SCAN;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_STK_GET_PROFILE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_STK_SET_PROFILE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_STOP_KEEPALIVE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_STOP_LCE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_STOP_NETWORK_SCAN;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_UDUB;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_UPDATE_SIM_PHONEBOOK_RECORD;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_VOICE_RADIO_TECH;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_VOICE_REGISTRATION_STATE;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_WRITE_SMS_TO_SIM;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_BARRING_INFO_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CALL_RING;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_CALL_WAITING;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_INFO_REC;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_OTA_PROVISION_STATUS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_PRL_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CELL_INFO_LIST;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_DATA_CALL_LIST_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_DC_RT_INFO_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_EMERGENCY_NUMBER_LIST;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_HARDWARE_CONFIG_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ICC_SLOT_STATUS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_KEEPALIVE_STATUS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_LCEDATA_RECV;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_MODEM_RESTART;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_NETWORK_SCAN_RESULT;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_NITZ_TIME_RECEIVED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_OEM_HOOK_RAW;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ON_SS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ON_USSD;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ON_USSD_REQUEST;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_PCO_DATA;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RADIO_CAPABILITY;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_REGISTRATION_FAILED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESEND_INCALL_MUTE;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_CDMA_NEW_SMS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NEW_SMS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_RECORDS_RECEIVED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESTRICTED_STATE_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RIL_CONNECTED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RINGBACK_TONE;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIGNAL_STRENGTH;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_REFRESH;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_SMS_STORAGE_FULL;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SRVCC_STATE_NOTIFY;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_CALL_SETUP;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_CC_ALPHA_NOTIFY;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_EVENT_NOTIFY;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_PROACTIVE_COMMAND;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_SESSION_END;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SUPP_SVC_NOTIFICATION;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UNTHROTTLE_APN;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_VOICE_RADIO_TECH_CHANGED;
-
-import android.annotation.Nullable;
-import android.net.InetAddresses;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.os.SystemClock;
-import android.service.carrier.CarrierIdentifier;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.Annotation;
-import android.telephony.BarringInfo;
-import android.telephony.CarrierRestrictionRules;
-import android.telephony.CellConfigLte;
-import android.telephony.CellIdentity;
-import android.telephony.CellIdentityCdma;
-import android.telephony.CellIdentityGsm;
-import android.telephony.CellIdentityLte;
-import android.telephony.CellIdentityNr;
-import android.telephony.CellIdentityTdscdma;
-import android.telephony.CellIdentityWcdma;
-import android.telephony.CellInfo;
-import android.telephony.CellInfoCdma;
-import android.telephony.CellInfoGsm;
-import android.telephony.CellInfoLte;
-import android.telephony.CellInfoNr;
-import android.telephony.CellInfoTdscdma;
-import android.telephony.CellInfoWcdma;
-import android.telephony.CellSignalStrength;
-import android.telephony.CellSignalStrengthCdma;
-import android.telephony.CellSignalStrengthGsm;
-import android.telephony.CellSignalStrengthLte;
-import android.telephony.CellSignalStrengthNr;
-import android.telephony.CellSignalStrengthTdscdma;
-import android.telephony.CellSignalStrengthWcdma;
-import android.telephony.ClosedSubscriberGroupInfo;
-import android.telephony.LinkCapacityEstimate;
-import android.telephony.ModemInfo;
-import android.telephony.PhoneCapability;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.PhysicalChannelConfig;
-import android.telephony.RadioAccessSpecifier;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.SignalThresholdInfo;
-import android.telephony.SmsManager;
-import android.telephony.TelephonyManager;
-import android.telephony.UiccSlotMapping;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataProfile;
-import android.telephony.data.DataService;
-import android.telephony.data.DataService.DeactivateDataReason;
-import android.telephony.data.DataService.SetupDataReason;
-import android.telephony.data.EpsQos;
-import android.telephony.data.NetworkSliceInfo;
-import android.telephony.data.NetworkSlicingConfig;
-import android.telephony.data.NrQos;
-import android.telephony.data.Qos;
-import android.telephony.data.QosBearerFilter;
-import android.telephony.data.QosBearerSession;
-import android.telephony.data.RouteSelectionDescriptor;
-import android.telephony.data.TrafficDescriptor;
-import android.telephony.data.UrspRule;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.cat.ComprehensionTlv;
-import com.android.internal.telephony.cat.ComprehensionTlvTag;
-import com.android.internal.telephony.cdma.SmsMessage;
-import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
-import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
-import com.android.internal.telephony.cdma.sms.SmsEnvelope;
-import com.android.internal.telephony.data.KeepaliveStatus;
-import com.android.internal.telephony.data.KeepaliveStatus.KeepaliveStatusCode;
-import com.android.internal.telephony.uicc.AdnCapacity;
-import com.android.internal.telephony.uicc.IccCardApplicationStatus;
-import com.android.internal.telephony.uicc.IccCardStatus;
-import com.android.internal.telephony.uicc.IccSimPortInfo;
-import com.android.internal.telephony.uicc.IccSlotPortMapping;
-import com.android.internal.telephony.uicc.IccSlotStatus;
-import com.android.internal.telephony.uicc.IccUtils;
-import com.android.internal.telephony.uicc.SimPhonebookRecord;
-import com.android.telephony.Rlog;
-
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.net.Inet4Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Locale;
-import java.util.Objects;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * Utils class for HAL <-> RIL conversions
- */
-public class RILUtils {
-    private static final String TAG = "RILUtils";
-
-    // The number of required config values for broadcast SMS stored in RIL_CdmaBroadcastServiceInfo
-    public static final int CDMA_BSI_NO_OF_INTS_STRUCT = 3;
-    // The number of service categories for broadcast SMS
-    public static final int CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES = 31;
-
-    // Radio power failure UUIDs
-    public static final String RADIO_POWER_FAILURE_BUGREPORT_UUID =
-            "316f3801-fa21-4954-a42f-0041eada3b31";
-    public static final String RADIO_POWER_FAILURE_RF_HARDWARE_ISSUE_UUID =
-            "316f3801-fa21-4954-a42f-0041eada3b32";
-    public static final String RADIO_POWER_FAILURE_NO_RF_CALIBRATION_UUID =
-            "316f3801-fa21-4954-a42f-0041eada3b33";
-
-    private static final Set<Class> WRAPPER_CLASSES = new HashSet(Arrays.asList(
-            Boolean.class, Character.class, Byte.class, Short.class, Integer.class, Long.class,
-            Float.class, Double.class));
-
-    /**
-     * Convert to PersoSubstate defined in radio/1.5/types.hal
-     * @param persoType PersoSubState type
-     * @return The converted PersoSubstate
-     */
-    public static int convertToHalPersoType(
-            IccCardApplicationStatus.PersoSubState persoType) {
-        switch (persoType) {
-            case PERSOSUBSTATE_IN_PROGRESS:
-                return android.hardware.radio.V1_5.PersoSubstate.IN_PROGRESS;
-            case  PERSOSUBSTATE_READY:
-                return android.hardware.radio.V1_5.PersoSubstate.READY;
-            case PERSOSUBSTATE_SIM_NETWORK:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_NETWORK;
-            case PERSOSUBSTATE_SIM_NETWORK_SUBSET:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_NETWORK_SUBSET;
-            case PERSOSUBSTATE_SIM_CORPORATE:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_CORPORATE;
-            case PERSOSUBSTATE_SIM_SERVICE_PROVIDER:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_SERVICE_PROVIDER;
-            case PERSOSUBSTATE_SIM_SIM:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_SIM;
-            case PERSOSUBSTATE_SIM_NETWORK_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_NETWORK_PUK;
-            case PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_NETWORK_SUBSET_PUK;
-            case PERSOSUBSTATE_SIM_CORPORATE_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_CORPORATE_PUK;
-            case PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_SERVICE_PROVIDER_PUK;
-            case PERSOSUBSTATE_SIM_SIM_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_SIM_PUK;
-            case PERSOSUBSTATE_RUIM_NETWORK1:
-                return android.hardware.radio.V1_5.PersoSubstate.RUIM_NETWORK1;
-            case PERSOSUBSTATE_RUIM_NETWORK2:
-                return android.hardware.radio.V1_5.PersoSubstate.RUIM_NETWORK2;
-            case PERSOSUBSTATE_RUIM_HRPD:
-                return android.hardware.radio.V1_5.PersoSubstate.RUIM_HRPD;
-            case PERSOSUBSTATE_RUIM_CORPORATE:
-                return android.hardware.radio.V1_5.PersoSubstate.RUIM_CORPORATE;
-            case PERSOSUBSTATE_RUIM_SERVICE_PROVIDER:
-                return android.hardware.radio.V1_5.PersoSubstate.RUIM_SERVICE_PROVIDER;
-            case PERSOSUBSTATE_RUIM_RUIM:
-                return android.hardware.radio.V1_5.PersoSubstate.RUIM_RUIM;
-            case PERSOSUBSTATE_RUIM_NETWORK1_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.RUIM_NETWORK1_PUK;
-            case PERSOSUBSTATE_RUIM_NETWORK2_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.RUIM_NETWORK2_PUK;
-            case PERSOSUBSTATE_RUIM_HRPD_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.RUIM_HRPD_PUK;
-            case PERSOSUBSTATE_RUIM_CORPORATE_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.RUIM_CORPORATE_PUK;
-            case PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.RUIM_SERVICE_PROVIDER_PUK;
-            case PERSOSUBSTATE_RUIM_RUIM_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.RUIM_RUIM_PUK;
-            case PERSOSUBSTATE_SIM_SPN:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_SPN;
-            case PERSOSUBSTATE_SIM_SPN_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_SPN_PUK;
-            case PERSOSUBSTATE_SIM_SP_EHPLMN:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_SP_EHPLMN;
-            case PERSOSUBSTATE_SIM_SP_EHPLMN_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_SP_EHPLMN_PUK;
-            case PERSOSUBSTATE_SIM_ICCID:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_ICCID;
-            case PERSOSUBSTATE_SIM_ICCID_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_ICCID_PUK;
-            case PERSOSUBSTATE_SIM_IMPI:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_IMPI;
-            case PERSOSUBSTATE_SIM_IMPI_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_IMPI_PUK;
-            case PERSOSUBSTATE_SIM_NS_SP:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_NS_SP;
-            case PERSOSUBSTATE_SIM_NS_SP_PUK:
-                return android.hardware.radio.V1_5.PersoSubstate.SIM_NS_SP_PUK;
-            default:
-                return android.hardware.radio.V1_5.PersoSubstate.UNKNOWN;
-        }
-    }
-
-    /**
-     * Convert to PersoSubstate.aidl
-     * @param persoType PersoSubState type
-     * @return The converted PersoSubstate
-     */
-    public static int convertToHalPersoTypeAidl(
-            IccCardApplicationStatus.PersoSubState persoType) {
-        switch (persoType) {
-            case PERSOSUBSTATE_IN_PROGRESS:
-                return android.hardware.radio.sim.PersoSubstate.IN_PROGRESS;
-            case  PERSOSUBSTATE_READY:
-                return android.hardware.radio.sim.PersoSubstate.READY;
-            case PERSOSUBSTATE_SIM_NETWORK:
-                return android.hardware.radio.sim.PersoSubstate.SIM_NETWORK;
-            case PERSOSUBSTATE_SIM_NETWORK_SUBSET:
-                return android.hardware.radio.sim.PersoSubstate.SIM_NETWORK_SUBSET;
-            case PERSOSUBSTATE_SIM_CORPORATE:
-                return android.hardware.radio.sim.PersoSubstate.SIM_CORPORATE;
-            case PERSOSUBSTATE_SIM_SERVICE_PROVIDER:
-                return android.hardware.radio.sim.PersoSubstate.SIM_SERVICE_PROVIDER;
-            case PERSOSUBSTATE_SIM_SIM:
-                return android.hardware.radio.sim.PersoSubstate.SIM_SIM;
-            case PERSOSUBSTATE_SIM_NETWORK_PUK:
-                return android.hardware.radio.sim.PersoSubstate.SIM_NETWORK_PUK;
-            case PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:
-                return android.hardware.radio.sim.PersoSubstate.SIM_NETWORK_SUBSET_PUK;
-            case PERSOSUBSTATE_SIM_CORPORATE_PUK:
-                return android.hardware.radio.sim.PersoSubstate.SIM_CORPORATE_PUK;
-            case PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:
-                return android.hardware.radio.sim.PersoSubstate.SIM_SERVICE_PROVIDER_PUK;
-            case PERSOSUBSTATE_SIM_SIM_PUK:
-                return android.hardware.radio.sim.PersoSubstate.SIM_SIM_PUK;
-            case PERSOSUBSTATE_RUIM_NETWORK1:
-                return android.hardware.radio.sim.PersoSubstate.RUIM_NETWORK1;
-            case PERSOSUBSTATE_RUIM_NETWORK2:
-                return android.hardware.radio.sim.PersoSubstate.RUIM_NETWORK2;
-            case PERSOSUBSTATE_RUIM_HRPD:
-                return android.hardware.radio.sim.PersoSubstate.RUIM_HRPD;
-            case PERSOSUBSTATE_RUIM_CORPORATE:
-                return android.hardware.radio.sim.PersoSubstate.RUIM_CORPORATE;
-            case PERSOSUBSTATE_RUIM_SERVICE_PROVIDER:
-                return android.hardware.radio.sim.PersoSubstate.RUIM_SERVICE_PROVIDER;
-            case PERSOSUBSTATE_RUIM_RUIM:
-                return android.hardware.radio.sim.PersoSubstate.RUIM_RUIM;
-            case PERSOSUBSTATE_RUIM_NETWORK1_PUK:
-                return android.hardware.radio.sim.PersoSubstate.RUIM_NETWORK1_PUK;
-            case PERSOSUBSTATE_RUIM_NETWORK2_PUK:
-                return android.hardware.radio.sim.PersoSubstate.RUIM_NETWORK2_PUK;
-            case PERSOSUBSTATE_RUIM_HRPD_PUK:
-                return android.hardware.radio.sim.PersoSubstate.RUIM_HRPD_PUK;
-            case PERSOSUBSTATE_RUIM_CORPORATE_PUK:
-                return android.hardware.radio.sim.PersoSubstate.RUIM_CORPORATE_PUK;
-            case PERSOSUBSTATE_RUIM_SERVICE_PROVIDER_PUK:
-                return android.hardware.radio.sim.PersoSubstate.RUIM_SERVICE_PROVIDER_PUK;
-            case PERSOSUBSTATE_RUIM_RUIM_PUK:
-                return android.hardware.radio.sim.PersoSubstate.RUIM_RUIM_PUK;
-            case PERSOSUBSTATE_SIM_SPN:
-                return android.hardware.radio.sim.PersoSubstate.SIM_SPN;
-            case PERSOSUBSTATE_SIM_SPN_PUK:
-                return android.hardware.radio.sim.PersoSubstate.SIM_SPN_PUK;
-            case PERSOSUBSTATE_SIM_SP_EHPLMN:
-                return android.hardware.radio.sim.PersoSubstate.SIM_SP_EHPLMN;
-            case PERSOSUBSTATE_SIM_SP_EHPLMN_PUK:
-                return android.hardware.radio.sim.PersoSubstate.SIM_SP_EHPLMN_PUK;
-            case PERSOSUBSTATE_SIM_ICCID:
-                return android.hardware.radio.sim.PersoSubstate.SIM_ICCID;
-            case PERSOSUBSTATE_SIM_ICCID_PUK:
-                return android.hardware.radio.sim.PersoSubstate.SIM_ICCID_PUK;
-            case PERSOSUBSTATE_SIM_IMPI:
-                return android.hardware.radio.sim.PersoSubstate.SIM_IMPI;
-            case PERSOSUBSTATE_SIM_IMPI_PUK:
-                return android.hardware.radio.sim.PersoSubstate.SIM_IMPI_PUK;
-            case PERSOSUBSTATE_SIM_NS_SP:
-                return android.hardware.radio.sim.PersoSubstate.SIM_NS_SP;
-            case PERSOSUBSTATE_SIM_NS_SP_PUK:
-                return android.hardware.radio.sim.PersoSubstate.SIM_NS_SP_PUK;
-            default:
-                return android.hardware.radio.sim.PersoSubstate.UNKNOWN;
-        }
-    }
-
-    /**
-     * Convert to GsmSmsMessage defined in radio/1.0/types.hal
-     * @param smscPdu SMSC address
-     * @param pdu SMS in PDU format
-     * @return A converted GsmSmsMessage
-     */
-    public static android.hardware.radio.V1_0.GsmSmsMessage convertToHalGsmSmsMessage(
-            String smscPdu, String pdu) {
-        android.hardware.radio.V1_0.GsmSmsMessage msg =
-                new android.hardware.radio.V1_0.GsmSmsMessage();
-        msg.smscPdu = smscPdu == null ? "" : smscPdu;
-        msg.pdu = pdu == null ? "" : pdu;
-        return msg;
-    }
-
-    /**
-     * Convert to GsmSmsMessage.aidl
-     * @param smscPdu SMSC address
-     * @param pdu SMS in PDU format
-     * @return A converted GsmSmsMessage
-     */
-    public static android.hardware.radio.messaging.GsmSmsMessage convertToHalGsmSmsMessageAidl(
-            String smscPdu, String pdu) {
-        android.hardware.radio.messaging.GsmSmsMessage msg =
-                new android.hardware.radio.messaging.GsmSmsMessage();
-        msg.smscPdu = convertNullToEmptyString(smscPdu);
-        msg.pdu = convertNullToEmptyString(pdu);
-        return msg;
-    }
-
-    /**
-     * Convert to CdmaSmsMessage defined in radio/1.0/types.hal
-     * @param pdu SMS in PDU format
-     * @return A converted CdmaSmsMessage
-     */
-    public static android.hardware.radio.V1_0.CdmaSmsMessage convertToHalCdmaSmsMessage(
-            byte[] pdu) {
-        android.hardware.radio.V1_0.CdmaSmsMessage msg =
-                new android.hardware.radio.V1_0.CdmaSmsMessage();
-        int addrNbrOfDigits;
-        int subaddrNbrOfDigits;
-        int bearerDataLength;
-        ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
-        DataInputStream dis = new DataInputStream(bais);
-
-        try {
-            msg.teleserviceId = dis.readInt(); // teleServiceId
-            msg.isServicePresent = (byte) dis.readInt() == 1; // servicePresent
-            msg.serviceCategory = dis.readInt(); // serviceCategory
-            msg.address.digitMode = dis.read();  // address digit mode
-            msg.address.numberMode = dis.read(); // address number mode
-            msg.address.numberType = dis.read(); // address number type
-            msg.address.numberPlan = dis.read(); // address number plan
-            addrNbrOfDigits = (byte) dis.read();
-            for (int i = 0; i < addrNbrOfDigits; i++) {
-                msg.address.digits.add(dis.readByte()); // address_orig_bytes[i]
-            }
-            msg.subAddress.subaddressType = dis.read(); //subaddressType
-            msg.subAddress.odd = (byte) dis.read() == 1; //subaddr odd
-            subaddrNbrOfDigits = (byte) dis.read();
-            for (int i = 0; i < subaddrNbrOfDigits; i++) {
-                msg.subAddress.digits.add(dis.readByte()); //subaddr_orig_bytes[i]
-            }
-
-            bearerDataLength = dis.read();
-            for (int i = 0; i < bearerDataLength; i++) {
-                msg.bearerData.add(dis.readByte()); //bearerData[i]
-            }
-        } catch (IOException ex) {
-        }
-        return msg;
-    }
-
-    /**
-     * Convert to CdmaSmsMessage.aidl
-     * @param pdu SMS in PDU format
-     * @return The converted CdmaSmsMessage
-     */
-    public static android.hardware.radio.messaging.CdmaSmsMessage convertToHalCdmaSmsMessageAidl(
-            byte[] pdu) {
-        android.hardware.radio.messaging.CdmaSmsMessage msg =
-                new android.hardware.radio.messaging.CdmaSmsMessage();
-        msg.address = new android.hardware.radio.messaging.CdmaSmsAddress();
-        msg.subAddress = new android.hardware.radio.messaging.CdmaSmsSubaddress();
-        int addrNbrOfDigits;
-        int subaddrNbrOfDigits;
-        int bearerDataLength;
-        ByteArrayInputStream bais = new ByteArrayInputStream(pdu);
-        DataInputStream dis = new DataInputStream(bais);
-
-        try {
-            msg.teleserviceId = dis.readInt(); // teleServiceId
-            msg.isServicePresent = (byte) dis.readInt() == 1; // servicePresent
-            msg.serviceCategory = dis.readInt(); // serviceCategory
-            msg.address.digitMode = dis.read();  // address digit mode
-            msg.address.isNumberModeDataNetwork =
-                    dis.read() == CdmaSmsAddress.NUMBER_MODE_DATA_NETWORK; // address number mode
-            msg.address.numberType = dis.read(); // address number type
-            msg.address.numberPlan = dis.read(); // address number plan
-            addrNbrOfDigits = (byte) dis.read();
-            byte[] digits = new byte[addrNbrOfDigits];
-            for (int i = 0; i < addrNbrOfDigits; i++) {
-                digits[i] = dis.readByte(); // address_orig_bytes[i]
-            }
-            msg.address.digits = digits;
-            msg.subAddress.subaddressType = dis.read(); //subaddressType
-            msg.subAddress.odd = (byte) dis.read() == 1; //subaddr odd
-            subaddrNbrOfDigits = (byte) dis.read();
-            digits = new byte[subaddrNbrOfDigits];
-            for (int i = 0; i < subaddrNbrOfDigits; i++) {
-                digits[i] = dis.readByte(); //subaddr_orig_bytes[i]
-            }
-            msg.subAddress.digits = digits;
-
-            bearerDataLength = dis.read();
-            byte[] bearerData = new byte[bearerDataLength];
-            for (int i = 0; i < bearerDataLength; i++) {
-                bearerData[i] = dis.readByte(); //bearerData[i]
-            }
-            msg.bearerData = bearerData;
-        } catch (IOException ex) {
-        }
-        return msg;
-    }
-
-    /**
-     * Convert CdmaSmsMessage defined in radio/1.0/types.hal to SmsMessage
-     * Note only primitive fields are set
-     * @param cdmaSmsMessage CdmaSmsMessage defined in radio/1.0/types.hal
-     * @return A converted SmsMessage
-     */
-    public static SmsMessage convertHalCdmaSmsMessage(
-            android.hardware.radio.V1_0.CdmaSmsMessage cdmaSmsMessage) {
-        // Note: Parcel.readByte actually reads one Int and masks to byte
-        SmsEnvelope env = new SmsEnvelope();
-        CdmaSmsAddress addr = new CdmaSmsAddress();
-        CdmaSmsSubaddress subaddr = new CdmaSmsSubaddress();
-        byte[] data;
-        byte count;
-        int countInt;
-        int addressDigitMode;
-
-        //currently not supported by the modem-lib: env.mMessageType
-        env.teleService = cdmaSmsMessage.teleserviceId;
-
-        if (cdmaSmsMessage.isServicePresent) {
-            env.messageType = SmsEnvelope.MESSAGE_TYPE_BROADCAST;
-        } else {
-            if (SmsEnvelope.TELESERVICE_NOT_SET == env.teleService) {
-                // assume type ACK
-                env.messageType = SmsEnvelope.MESSAGE_TYPE_ACKNOWLEDGE;
-            } else {
-                env.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
-            }
-        }
-        env.serviceCategory = cdmaSmsMessage.serviceCategory;
-
-        // address
-        addressDigitMode = cdmaSmsMessage.address.digitMode;
-        addr.digitMode = (byte) (0xFF & addressDigitMode);
-        addr.numberMode = (byte) (0xFF & cdmaSmsMessage.address.numberMode);
-        addr.ton = cdmaSmsMessage.address.numberType;
-        addr.numberPlan = (byte) (0xFF & cdmaSmsMessage.address.numberPlan);
-        count = (byte) cdmaSmsMessage.address.digits.size();
-        addr.numberOfDigits = count;
-        data = new byte[count];
-        for (int index = 0; index < count; index++) {
-            data[index] = cdmaSmsMessage.address.digits.get(index);
-
-            // convert the value if it is 4-bit DTMF to 8 bit
-            if (addressDigitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) {
-                data[index] = SmsMessage.convertDtmfToAscii(data[index]);
-            }
-        }
-
-        addr.origBytes = data;
-
-        subaddr.type = cdmaSmsMessage.subAddress.subaddressType;
-        subaddr.odd = (byte) (cdmaSmsMessage.subAddress.odd ? 1 : 0);
-        count = (byte) cdmaSmsMessage.subAddress.digits.size();
-
-        if (count < 0) {
-            count = 0;
-        }
-
-        // p_cur->sSubAddress.digits[digitCount] :
-
-        data = new byte[count];
-
-        for (int index = 0; index < count; ++index) {
-            data[index] = cdmaSmsMessage.subAddress.digits.get(index);
-        }
-
-        subaddr.origBytes = data;
-
-        /* currently not supported by the modem-lib:
-            env.bearerReply
-            env.replySeqNo
-            env.errorClass
-            env.causeCode
-        */
-
-        // bearer data
-        countInt = cdmaSmsMessage.bearerData.size();
-        if (countInt < 0) {
-            countInt = 0;
-        }
-
-        data = new byte[countInt];
-        for (int index = 0; index < countInt; index++) {
-            data[index] = cdmaSmsMessage.bearerData.get(index);
-        }
-        // BD gets further decoded when accessed in SMSDispatcher
-        env.bearerData = data;
-
-        // link the filled objects to the SMS
-        env.origAddress = addr;
-        env.origSubaddress = subaddr;
-
-        SmsMessage msg = new SmsMessage(addr, env);
-
-        return msg;
-    }
-
-    /**
-     * Convert CdmaSmsMessage defined in CdmaSmsMessage.aidl to SmsMessage
-     * Note only primitive fields are set
-     * @param msg CdmaSmsMessage defined in CdmaSmsMessage.aidl
-     * @return A converted SmsMessage
-     */
-    public static SmsMessage convertHalCdmaSmsMessage(
-            android.hardware.radio.messaging.CdmaSmsMessage msg) {
-        // Note: Parcel.readByte actually reads one Int and masks to byte
-        SmsEnvelope env = new SmsEnvelope();
-        CdmaSmsAddress addr = new CdmaSmsAddress();
-        CdmaSmsSubaddress subaddr = new CdmaSmsSubaddress();
-
-        // address
-        int addressDigitMode = msg.address.digitMode;
-        addr.digitMode = (byte) (0xFF & addressDigitMode);
-        addr.numberMode = (byte) (0xFF & (msg.address.isNumberModeDataNetwork ? 1 : 0));
-        addr.ton = msg.address.numberType;
-        addr.numberPlan = (byte) (0xFF & msg.address.numberPlan);
-        addr.numberOfDigits = msg.address.digits.length;
-        byte[] data = new byte[msg.address.digits.length];
-        for (int index = 0; index < data.length; index++) {
-            data[index] = msg.address.digits[index];
-            // convert the value if it is 4-bit DTMF to 8 bit
-            if (addressDigitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) {
-                data[index] = SmsMessage.convertDtmfToAscii(data[index]);
-            }
-        }
-        addr.origBytes = data;
-
-        // subaddress
-        subaddr.type = msg.subAddress.subaddressType;
-        subaddr.odd = (byte) (msg.subAddress.odd ? 1 : 0);
-        subaddr.origBytes = msg.subAddress.digits;
-
-        // envelope
-        // currently not supported by the modem-lib: env.bearerReply, env.replySeqNo,
-        // env.errorClass, env.causeCode, env.mMessageType
-        env.teleService = msg.teleserviceId;
-        if (msg.isServicePresent) {
-            env.messageType = SmsEnvelope.MESSAGE_TYPE_BROADCAST;
-        } else {
-            if (SmsEnvelope.TELESERVICE_NOT_SET == env.teleService) {
-                // assume type ACK
-                env.messageType = SmsEnvelope.MESSAGE_TYPE_ACKNOWLEDGE;
-            } else {
-                env.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
-            }
-        }
-        env.serviceCategory = msg.serviceCategory;
-
-        // bearer data is further decoded when accessed in SmsDispatcher
-        env.bearerData = msg.bearerData;
-
-        // link the filled objects to the SMS
-        env.origAddress = addr;
-        env.origSubaddress = subaddr;
-
-        return new SmsMessage(addr, env);
-    }
-
-    /**
-     * Convert to DataProfileInfo defined in radio/1.0/types.hal
-     * @param dp Data profile
-     * @return The converted DataProfileInfo
-     */
-    public static android.hardware.radio.V1_0.DataProfileInfo convertToHalDataProfile10(
-            DataProfile dp) {
-        android.hardware.radio.V1_0.DataProfileInfo dpi =
-                new android.hardware.radio.V1_0.DataProfileInfo();
-
-        dpi.profileId = dp.getProfileId();
-        dpi.apn = dp.getApn();
-        dpi.protocol = ApnSetting.getProtocolStringFromInt(dp.getProtocolType());
-        dpi.roamingProtocol = ApnSetting.getProtocolStringFromInt(dp.getRoamingProtocolType());
-        dpi.authType = dp.getAuthType();
-        dpi.user = TextUtils.emptyIfNull(dp.getUserName());
-        dpi.password = TextUtils.emptyIfNull(dp.getPassword());
-        dpi.type = dp.getType();
-        dpi.maxConnsTime = dp.getMaxConnectionsTime();
-        dpi.maxConns = dp.getMaxConnections();
-        dpi.waitTime = dp.getWaitTime();
-        dpi.enabled = dp.isEnabled();
-        dpi.supportedApnTypesBitmap = dp.getSupportedApnTypesBitmask();
-        // Shift by 1 bit due to the discrepancy between
-        // android.hardware.radio.V1_0.RadioAccessFamily and the bitmask version of
-        // ServiceState.RIL_RADIO_TECHNOLOGY_XXXX.
-        dpi.bearerBitmap = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
-                dp.getBearerBitmask()) << 1;
-        dpi.mtu = dp.getMtuV4();
-        dpi.mvnoType = android.hardware.radio.V1_0.MvnoType.NONE;
-        dpi.mvnoMatchData = "";
-
-        return dpi;
-    }
-
-    /**
-     * Convert to DataProfileInfo defined in radio/1.4/types.hal
-     * @param dp Data profile
-     * @return The converted DataProfileInfo
-     */
-    public static android.hardware.radio.V1_4.DataProfileInfo convertToHalDataProfile14(
-            DataProfile dp) {
-        android.hardware.radio.V1_4.DataProfileInfo dpi =
-                new android.hardware.radio.V1_4.DataProfileInfo();
-
-        dpi.apn = dp.getApn();
-        dpi.protocol = dp.getProtocolType();
-        dpi.roamingProtocol = dp.getRoamingProtocolType();
-        dpi.authType = dp.getAuthType();
-        dpi.user = TextUtils.emptyIfNull(dp.getUserName());
-        dpi.password = TextUtils.emptyIfNull(dp.getPassword());
-        dpi.type = dp.getType();
-        dpi.maxConnsTime = dp.getMaxConnectionsTime();
-        dpi.maxConns = dp.getMaxConnections();
-        dpi.waitTime = dp.getWaitTime();
-        dpi.enabled = dp.isEnabled();
-        dpi.supportedApnTypesBitmap = dp.getSupportedApnTypesBitmask();
-        // Shift by 1 bit due to the discrepancy between
-        // android.hardware.radio.V1_0.RadioAccessFamily and the bitmask version of
-        // ServiceState.RIL_RADIO_TECHNOLOGY_XXXX.
-        dpi.bearerBitmap = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
-                dp.getBearerBitmask()) << 1;
-        dpi.mtu = dp.getMtuV4();
-        dpi.persistent = dp.isPersistent();
-        dpi.preferred = dp.isPreferred();
-
-        // profile id is only meaningful when it's persistent on the modem.
-        dpi.profileId = (dpi.persistent) ? dp.getProfileId()
-                : android.hardware.radio.V1_0.DataProfileId.INVALID;
-
-        return dpi;
-    }
-
-    /**
-     * Convert to DataProfileInfo defined in radio/1.5/types.hal
-     * @param dp Data profile
-     * @return The converted DataProfileInfo
-     */
-    public static android.hardware.radio.V1_5.DataProfileInfo convertToHalDataProfile15(
-            DataProfile dp) {
-        android.hardware.radio.V1_5.DataProfileInfo dpi =
-                new android.hardware.radio.V1_5.DataProfileInfo();
-
-        dpi.apn = dp.getApn();
-        dpi.protocol = dp.getProtocolType();
-        dpi.roamingProtocol = dp.getRoamingProtocolType();
-        dpi.authType = dp.getAuthType();
-        dpi.user = TextUtils.emptyIfNull(dp.getUserName());
-        dpi.password = TextUtils.emptyIfNull(dp.getPassword());
-        dpi.type = dp.getType();
-        dpi.maxConnsTime = dp.getMaxConnectionsTime();
-        dpi.maxConns = dp.getMaxConnections();
-        dpi.waitTime = dp.getWaitTime();
-        dpi.enabled = dp.isEnabled();
-        dpi.supportedApnTypesBitmap = dp.getSupportedApnTypesBitmask();
-        // Shift by 1 bit due to the discrepancy between
-        // android.hardware.radio.V1_0.RadioAccessFamily and the bitmask version of
-        // ServiceState.RIL_RADIO_TECHNOLOGY_XXXX.
-        dpi.bearerBitmap = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
-                dp.getBearerBitmask()) << 1;
-        dpi.mtuV4 = dp.getMtuV4();
-        dpi.mtuV6 = dp.getMtuV6();
-        dpi.persistent = dp.isPersistent();
-        dpi.preferred = dp.isPreferred();
-
-        // profile id is only meaningful when it's persistent on the modem.
-        dpi.profileId = (dpi.persistent) ? dp.getProfileId()
-                : android.hardware.radio.V1_0.DataProfileId.INVALID;
-
-        return dpi;
-    }
-
-    /**
-     * Convert to DataProfileInfo.aidl
-     * @param dp Data profile
-     * @return The converted DataProfileInfo
-     */
-    public static android.hardware.radio.data.DataProfileInfo convertToHalDataProfile(
-            DataProfile dp) {
-        android.hardware.radio.data.DataProfileInfo dpi =
-                new android.hardware.radio.data.DataProfileInfo();
-
-        dpi.apn = dp.getApn();
-        dpi.protocol = dp.getProtocolType();
-        dpi.roamingProtocol = dp.getRoamingProtocolType();
-        dpi.authType = dp.getAuthType();
-        dpi.user = convertNullToEmptyString(dp.getUserName());
-        dpi.password = convertNullToEmptyString(dp.getPassword());
-        dpi.type = dp.getType();
-        dpi.maxConnsTime = dp.getMaxConnectionsTime();
-        dpi.maxConns = dp.getMaxConnections();
-        dpi.waitTime = dp.getWaitTime();
-        dpi.enabled = dp.isEnabled();
-        dpi.supportedApnTypesBitmap = dp.getSupportedApnTypesBitmask();
-        // Shift by 1 bit due to the discrepancy between RadioAccessFamily.aidl and the bitmask
-        // version of ServiceState.RIL_RADIO_TECHNOLOGY_XXXX.
-        dpi.bearerBitmap = ServiceState.convertNetworkTypeBitmaskToBearerBitmask(
-                dp.getBearerBitmask()) << 1;
-        dpi.mtuV4 = dp.getMtuV4();
-        dpi.mtuV6 = dp.getMtuV6();
-        dpi.persistent = dp.isPersistent();
-        dpi.preferred = dp.isPreferred();
-        dpi.alwaysOn = false;
-        if (dp.getApnSetting() != null) {
-            dpi.alwaysOn = dp.getApnSetting().isAlwaysOn();
-        }
-        dpi.trafficDescriptor = convertToHalTrafficDescriptorAidl(dp.getTrafficDescriptor());
-
-        // profile id is only meaningful when it's persistent on the modem.
-        dpi.profileId = (dpi.persistent) ? dp.getProfileId()
-                : android.hardware.radio.data.DataProfileInfo.ID_INVALID;
-
-        return dpi;
-    }
-
-    /**
-     * Convert from DataProfileInfo.aidl to DataProfile
-     * @param dpi DataProfileInfo
-     * @return The converted DataProfile
-     */
-    public static DataProfile convertToDataProfile(
-            android.hardware.radio.data.DataProfileInfo dpi) {
-        ApnSetting apnSetting = new ApnSetting.Builder()
-                .setEntryName(dpi.apn)
-                .setApnName(dpi.apn)
-                .setApnTypeBitmask(dpi.supportedApnTypesBitmap)
-                .setAuthType(dpi.authType)
-                .setMaxConnsTime(dpi.maxConnsTime)
-                .setMaxConns(dpi.maxConns)
-                .setWaitTime(dpi.waitTime)
-                .setCarrierEnabled(dpi.enabled)
-                .setModemCognitive(dpi.persistent)
-                .setMtuV4(dpi.mtuV4)
-                .setMtuV6(dpi.mtuV6)
-                .setNetworkTypeBitmask(ServiceState.convertBearerBitmaskToNetworkTypeBitmask(
-                        dpi.bearerBitmap) >> 1)
-                .setProfileId(dpi.profileId)
-                .setPassword(dpi.password)
-                .setProtocol(dpi.protocol)
-                .setRoamingProtocol(dpi.roamingProtocol)
-                .setUser(dpi.user)
-                .setAlwaysOn(dpi.alwaysOn)
-                .build();
-
-        TrafficDescriptor td;
-        try {
-            td = convertHalTrafficDescriptor(dpi.trafficDescriptor);
-        } catch (IllegalArgumentException e) {
-            loge("convertToDataProfile: Failed to convert traffic descriptor. e=" + e);
-            td = null;
-        }
-
-        return new DataProfile.Builder()
-                .setType(dpi.type)
-                .setPreferred(dpi.preferred)
-                .setTrafficDescriptor(td)
-                .setApnSetting(apnSetting)
-                .build();
-    }
-
-    /**
-     * Convert to OptionalSliceInfo defined in radio/1.6/types.hal
-     * @param sliceInfo Slice info
-     * @return The converted OptionalSliceInfo
-     */
-    public static android.hardware.radio.V1_6.OptionalSliceInfo convertToHalSliceInfo(
-            @Nullable NetworkSliceInfo sliceInfo) {
-        android.hardware.radio.V1_6.OptionalSliceInfo optionalSliceInfo =
-                new android.hardware.radio.V1_6.OptionalSliceInfo();
-        if (sliceInfo == null) {
-            return optionalSliceInfo;
-        }
-
-        android.hardware.radio.V1_6.SliceInfo si = new android.hardware.radio.V1_6.SliceInfo();
-        si.sst = (byte) sliceInfo.getSliceServiceType();
-        si.mappedHplmnSst = (byte) sliceInfo.getMappedHplmnSliceServiceType();
-        si.sliceDifferentiator = sliceInfo.getSliceDifferentiator();
-        si.mappedHplmnSD = sliceInfo.getMappedHplmnSliceDifferentiator();
-        optionalSliceInfo.value(si);
-        return optionalSliceInfo;
-    }
-
-    /**
-     * Convert to SliceInfo.aidl
-     * @param sliceInfo Slice info
-     * @return The converted SliceInfo
-     */
-    public static android.hardware.radio.data.SliceInfo convertToHalSliceInfoAidl(
-            @Nullable NetworkSliceInfo sliceInfo) {
-        if (sliceInfo == null) {
-            return null;
-        }
-
-        android.hardware.radio.data.SliceInfo si = new android.hardware.radio.data.SliceInfo();
-        si.sliceServiceType = (byte) sliceInfo.getSliceServiceType();
-        si.mappedHplmnSst = (byte) sliceInfo.getMappedHplmnSliceServiceType();
-        si.sliceDifferentiator = sliceInfo.getSliceDifferentiator();
-        si.mappedHplmnSd = sliceInfo.getMappedHplmnSliceDifferentiator();
-        return si;
-    }
-
-    /**
-     * Convert to OptionalTrafficDescriptor defined in radio/1.6/types.hal
-     * @param trafficDescriptor Traffic descriptor
-     * @return The converted OptionalTrafficDescriptor
-     */
-    public static android.hardware.radio.V1_6.OptionalTrafficDescriptor
-            convertToHalTrafficDescriptor(@Nullable TrafficDescriptor trafficDescriptor) {
-        android.hardware.radio.V1_6.OptionalTrafficDescriptor optionalTrafficDescriptor =
-                new android.hardware.radio.V1_6.OptionalTrafficDescriptor();
-        if (trafficDescriptor == null) {
-            return optionalTrafficDescriptor;
-        }
-
-        android.hardware.radio.V1_6.TrafficDescriptor td =
-                new android.hardware.radio.V1_6.TrafficDescriptor();
-
-        android.hardware.radio.V1_6.OptionalDnn optionalDnn =
-                new android.hardware.radio.V1_6.OptionalDnn();
-        if (trafficDescriptor.getDataNetworkName() != null) {
-            optionalDnn.value(trafficDescriptor.getDataNetworkName());
-        }
-        td.dnn = optionalDnn;
-
-        android.hardware.radio.V1_6.OptionalOsAppId optionalOsAppId =
-                new android.hardware.radio.V1_6.OptionalOsAppId();
-        if (trafficDescriptor.getOsAppId() != null) {
-            android.hardware.radio.V1_6.OsAppId osAppId = new android.hardware.radio.V1_6.OsAppId();
-            osAppId.osAppId = primitiveArrayToArrayList(trafficDescriptor.getOsAppId());
-            optionalOsAppId.value(osAppId);
-        }
-        td.osAppId = optionalOsAppId;
-
-        optionalTrafficDescriptor.value(td);
-        return optionalTrafficDescriptor;
-    }
-
-    /**
-     * Convert to TrafficDescriptor.aidl
-     * @param trafficDescriptor Traffic descriptor
-     * @return The converted TrafficDescriptor
-     */
-    public static android.hardware.radio.data.TrafficDescriptor
-            convertToHalTrafficDescriptorAidl(@Nullable TrafficDescriptor trafficDescriptor) {
-        if (trafficDescriptor == null) {
-            return new android.hardware.radio.data.TrafficDescriptor();
-        }
-
-        android.hardware.radio.data.TrafficDescriptor td =
-                new android.hardware.radio.data.TrafficDescriptor();
-        td.dnn = trafficDescriptor.getDataNetworkName();
-        if (trafficDescriptor.getOsAppId() == null) {
-            td.osAppId = null;
-        } else {
-            android.hardware.radio.data.OsAppId osAppId = new android.hardware.radio.data.OsAppId();
-            osAppId.osAppId = trafficDescriptor.getOsAppId();
-            td.osAppId = osAppId;
-        }
-        return td;
-    }
-
-    /**
-     * Convert to ResetNvType defined in radio/1.0/types.hal
-     * @param resetType NV reset type
-     * @return The converted reset type in integer or -1 if param is invalid
-     */
-    public static int convertToHalResetNvType(int resetType) {
-        /**
-         * resetType values
-         * 1 - reload all NV items
-         * 2 - erase NV reset (SCRTN)
-         * 3 - factory reset (RTN)
-         */
-        switch (resetType) {
-            case 1: return android.hardware.radio.V1_0.ResetNvType.RELOAD;
-            case 2: return android.hardware.radio.V1_0.ResetNvType.ERASE;
-            case 3: return android.hardware.radio.V1_0.ResetNvType.FACTORY_RESET;
-        }
-        return -1;
-    }
-
-    /**
-     * Convert to ResetNvType.aidl
-     * @param resetType NV reset type
-     * @return The converted reset type in integer or -1 if param is invalid
-     */
-    public static int convertToHalResetNvTypeAidl(int resetType) {
-        /**
-         * resetType values
-         * 1 - reload all NV items
-         * 2 - erase NV reset (SCRTN)
-         * 3 - factory reset (RTN)
-         */
-        switch (resetType) {
-            case 1: return android.hardware.radio.modem.ResetNvType.RELOAD;
-            case 2: return android.hardware.radio.modem.ResetNvType.ERASE;
-            case 3: return android.hardware.radio.modem.ResetNvType.FACTORY_RESET;
-        }
-        return -1;
-    }
-
-    /**
-     * Convert to a list of LinkAddress defined in radio/1.5/types.hal
-     * @param linkProperties Link properties
-     * @return The converted list of LinkAddresses
-     */
-    public static ArrayList<android.hardware.radio.V1_5.LinkAddress> convertToHalLinkProperties15(
-            LinkProperties linkProperties) {
-        ArrayList<android.hardware.radio.V1_5.LinkAddress> addresses15 = new ArrayList<>();
-        if (linkProperties != null) {
-            for (android.net.LinkAddress la : linkProperties.getAllLinkAddresses()) {
-                android.hardware.radio.V1_5.LinkAddress linkAddress =
-                        new android.hardware.radio.V1_5.LinkAddress();
-                linkAddress.address = la.getAddress().getHostAddress();
-                linkAddress.properties = la.getFlags();
-                linkAddress.deprecationTime = la.getDeprecationTime();
-                linkAddress.expirationTime = la.getExpirationTime();
-                addresses15.add(linkAddress);
-            }
-        }
-        return addresses15;
-    }
-
-    /**
-     * Convert to a list of LinkAddress.aidl
-     * @param linkProperties Link properties
-     * @return The converted list of LinkAddresses
-     */
-    public static android.hardware.radio.data.LinkAddress[] convertToHalLinkProperties(
-            LinkProperties linkProperties) {
-        if (linkProperties == null) {
-            return new android.hardware.radio.data.LinkAddress[0];
-        }
-        android.hardware.radio.data.LinkAddress[] addresses =
-                new android.hardware.radio.data.LinkAddress[
-                        linkProperties.getAllLinkAddresses().size()];
-        for (int i = 0; i < linkProperties.getAllLinkAddresses().size(); i++) {
-            LinkAddress la = linkProperties.getAllLinkAddresses().get(i);
-            android.hardware.radio.data.LinkAddress linkAddress =
-                    new android.hardware.radio.data.LinkAddress();
-            linkAddress.address = la.getAddress().getHostAddress();
-            linkAddress.addressProperties = la.getFlags();
-            linkAddress.deprecationTime = la.getDeprecationTime();
-            linkAddress.expirationTime = la.getExpirationTime();
-            addresses[i] = linkAddress;
-        }
-        return addresses;
-    }
-
-    /**
-     * Convert RadioAccessSpecifier defined in radio/1.5/types.hal to RadioAccessSpecifier
-     * @param specifier RadioAccessSpecifier defined in radio/1.5/types.hal
-     * @return The converted RadioAccessSpecifier
-     */
-    public static RadioAccessSpecifier convertHalRadioAccessSpecifier(
-            android.hardware.radio.V1_5.RadioAccessSpecifier specifier) {
-        if (specifier == null) return null;
-        ArrayList<Integer> halBands = new ArrayList<>();
-        switch (specifier.bands.getDiscriminator()) {
-            case android.hardware.radio.V1_5.RadioAccessSpecifier.Bands.hidl_discriminator
-                    .geranBands:
-                halBands = specifier.bands.geranBands();
-                break;
-            case android.hardware.radio.V1_5.RadioAccessSpecifier.Bands.hidl_discriminator
-                    .utranBands:
-                halBands = specifier.bands.utranBands();
-                break;
-            case android.hardware.radio.V1_5.RadioAccessSpecifier.Bands.hidl_discriminator
-                    .eutranBands:
-                halBands = specifier.bands.eutranBands();
-                break;
-            case android.hardware.radio.V1_5.RadioAccessSpecifier.Bands.hidl_discriminator
-                    .ngranBands:
-                halBands = specifier.bands.ngranBands();
-                break;
-        }
-        return new RadioAccessSpecifier(convertHalRadioAccessNetworks(specifier.radioAccessNetwork),
-                halBands.stream().mapToInt(Integer::intValue).toArray(),
-                specifier.channels.stream().mapToInt(Integer::intValue).toArray());
-    }
-
-    /**
-     * Convert RadioAccessSpecifier defined in RadioAccessSpecifier.aidl to RadioAccessSpecifier
-     * @param specifier RadioAccessSpecifier defined in RadioAccessSpecifier.aidl
-     * @return The converted RadioAccessSpecifier
-     */
-    public static RadioAccessSpecifier convertHalRadioAccessSpecifier(
-            android.hardware.radio.network.RadioAccessSpecifier specifier) {
-        if (specifier == null) return null;
-        int[] halBands = null;
-        switch (specifier.bands.getTag()) {
-            case android.hardware.radio.network.RadioAccessSpecifierBands.geranBands:
-                halBands = specifier.bands.getGeranBands();
-                break;
-            case android.hardware.radio.network.RadioAccessSpecifierBands.utranBands:
-                halBands = specifier.bands.getUtranBands();
-                break;
-            case android.hardware.radio.network.RadioAccessSpecifierBands.eutranBands:
-                halBands = specifier.bands.getEutranBands();
-                break;
-            case android.hardware.radio.network.RadioAccessSpecifierBands.ngranBands:
-                halBands = specifier.bands.getNgranBands();
-                break;
-        }
-        return new RadioAccessSpecifier(specifier.accessNetwork, halBands, specifier.channels);
-    }
-
-    /**
-     * Convert to RadioAccessSpecifier defined in radio/1.1/types.hal
-     * @param ras Radio access specifier
-     * @return The converted RadioAccessSpecifier
-     */
-    public static android.hardware.radio.V1_1.RadioAccessSpecifier
-            convertToHalRadioAccessSpecifier11(RadioAccessSpecifier ras) {
-        android.hardware.radio.V1_1.RadioAccessSpecifier rasInHalFormat =
-                new android.hardware.radio.V1_1.RadioAccessSpecifier();
-        rasInHalFormat.radioAccessNetwork = ras.getRadioAccessNetwork();
-        ArrayList<Integer> bands = new ArrayList<>();
-        if (ras.getBands() != null) {
-            for (int band : ras.getBands()) {
-                bands.add(band);
-            }
-        }
-        switch (ras.getRadioAccessNetwork()) {
-            case AccessNetworkConstants.AccessNetworkType.GERAN:
-                rasInHalFormat.geranBands = bands;
-                break;
-            case AccessNetworkConstants.AccessNetworkType.UTRAN:
-                rasInHalFormat.utranBands = bands;
-                break;
-            case AccessNetworkConstants.AccessNetworkType.EUTRAN:
-                rasInHalFormat.eutranBands = bands;
-                break;
-            default:
-                return null;
-        }
-
-        if (ras.getChannels() != null) {
-            for (int channel : ras.getChannels()) {
-                rasInHalFormat.channels.add(channel);
-            }
-        }
-
-        return rasInHalFormat;
-    }
-
-    /**
-     * Convert to RadioAccessSpecifier defined in radio/1.5/types.hal
-     * @param ras Radio access specifier
-     * @return The converted RadioAccessSpecifier
-     */
-    public static android.hardware.radio.V1_5.RadioAccessSpecifier
-            convertToHalRadioAccessSpecifier15(RadioAccessSpecifier ras) {
-        android.hardware.radio.V1_5.RadioAccessSpecifier rasInHalFormat =
-                new android.hardware.radio.V1_5.RadioAccessSpecifier();
-        android.hardware.radio.V1_5.RadioAccessSpecifier.Bands bandsInHalFormat =
-                new android.hardware.radio.V1_5.RadioAccessSpecifier.Bands();
-        rasInHalFormat.radioAccessNetwork = convertToHalRadioAccessNetworks(
-                ras.getRadioAccessNetwork());
-        ArrayList<Integer> bands = new ArrayList<>();
-        if (ras.getBands() != null) {
-            for (int band : ras.getBands()) {
-                bands.add(band);
-            }
-        }
-        switch (ras.getRadioAccessNetwork()) {
-            case AccessNetworkConstants.AccessNetworkType.GERAN:
-                bandsInHalFormat.geranBands(bands);
-                break;
-            case AccessNetworkConstants.AccessNetworkType.UTRAN:
-                bandsInHalFormat.utranBands(bands);
-                break;
-            case AccessNetworkConstants.AccessNetworkType.EUTRAN:
-                bandsInHalFormat.eutranBands(bands);
-                break;
-            case AccessNetworkConstants.AccessNetworkType.NGRAN:
-                bandsInHalFormat.ngranBands(bands);
-                break;
-            default:
-                return null;
-        }
-        rasInHalFormat.bands = bandsInHalFormat;
-
-        if (ras.getChannels() != null) {
-            for (int channel : ras.getChannels()) {
-                rasInHalFormat.channels.add(channel);
-            }
-        }
-
-        return rasInHalFormat;
-    }
-
-    /**
-     * Convert to RadioAccessSpecifier.aidl
-     * @param ras Radio access specifier
-     * @return The converted RadioAccessSpecifier
-     */
-    public static android.hardware.radio.network.RadioAccessSpecifier
-            convertToHalRadioAccessSpecifierAidl(RadioAccessSpecifier ras) {
-        android.hardware.radio.network.RadioAccessSpecifier rasInHalFormat =
-                new android.hardware.radio.network.RadioAccessSpecifier();
-        android.hardware.radio.network.RadioAccessSpecifierBands bandsInHalFormat =
-                new android.hardware.radio.network.RadioAccessSpecifierBands();
-        rasInHalFormat.accessNetwork = convertToHalAccessNetworkAidl(ras.getRadioAccessNetwork());
-        int[] bands;
-        if (ras.getBands() != null) {
-            bands = new int[ras.getBands().length];
-            for (int i = 0; i < ras.getBands().length; i++) {
-                bands[i] = ras.getBands()[i];
-            }
-        } else {
-            bands = new int[0];
-        }
-        switch (ras.getRadioAccessNetwork()) {
-            case AccessNetworkConstants.AccessNetworkType.GERAN:
-                bandsInHalFormat.setGeranBands(bands);
-                break;
-            case AccessNetworkConstants.AccessNetworkType.UTRAN:
-                bandsInHalFormat.setUtranBands(bands);
-                break;
-            case AccessNetworkConstants.AccessNetworkType.EUTRAN:
-                bandsInHalFormat.setEutranBands(bands);
-                break;
-            case AccessNetworkConstants.AccessNetworkType.NGRAN:
-                bandsInHalFormat.setNgranBands(bands);
-                break;
-            default:
-                return null;
-        }
-        rasInHalFormat.bands = bandsInHalFormat;
-
-        int[] channels;
-        if (ras.getChannels() != null) {
-            channels = new int[ras.getChannels().length];
-            for (int i = 0; i < ras.getChannels().length; i++) {
-                channels[i] = ras.getChannels()[i];
-            }
-        } else {
-            channels = new int[0];
-        }
-        rasInHalFormat.channels = channels;
-
-        return rasInHalFormat;
-    }
-
-    /**
-     * Convert to censored terminal response
-     * @param terminalResponse Terminal response
-     * @return The converted censored terminal response
-     */
-    public static String convertToCensoredTerminalResponse(String terminalResponse) {
-        try {
-            byte[] bytes = IccUtils.hexStringToBytes(terminalResponse);
-            if (bytes != null) {
-                List<ComprehensionTlv> ctlvs = ComprehensionTlv.decodeMany(bytes, 0);
-                int from = 0;
-                for (ComprehensionTlv ctlv : ctlvs) {
-                    // Find text strings which might be personal information input by user,
-                    // then replace it with "********".
-                    if (ComprehensionTlvTag.TEXT_STRING.value() == ctlv.getTag()) {
-                        byte[] target = Arrays.copyOfRange(ctlv.getRawValue(), from,
-                                ctlv.getValueIndex() + ctlv.getLength());
-                        terminalResponse = terminalResponse.toLowerCase().replace(
-                                IccUtils.bytesToHexString(target).toLowerCase(), "********");
-                    }
-                    // The text string tag and the length field should also be hidden.
-                    from = ctlv.getValueIndex() + ctlv.getLength();
-                }
-            }
-        } catch (Exception e) {
-            terminalResponse = null;
-        }
-
-        return terminalResponse;
-    }
-
-    /**
-     * Convert to {@link TelephonyManager.NetworkTypeBitMask}, the bitmask represented by
-     * {@link android.telephony.Annotation.NetworkType}.
-     *
-     * @param raf {@link android.hardware.radio.V1_0.RadioAccessFamily}
-     * @return {@link TelephonyManager.NetworkTypeBitMask}
-     */
-    @TelephonyManager.NetworkTypeBitMask
-    public static int convertHalNetworkTypeBitMask(int raf) {
-        int networkTypeRaf = 0;
-
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GSM) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GSM;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.GPRS) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_GPRS;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EDGE) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EDGE;
-        }
-        // convert both IS95A/IS95B to CDMA as network mode doesn't support CDMA
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95A) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.IS95B) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_CDMA;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.ONE_X_RTT) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_0) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_A) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EVDO_B) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.EHRPD) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSUPA) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSDPA) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPA) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPA;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.HSPAP) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.UMTS) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_UMTS;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.TD_SCDMA) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE;
-        }
-        if ((raf & android.hardware.radio.V1_0.RadioAccessFamily.LTE_CA) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA;
-        }
-        if ((raf & android.hardware.radio.V1_4.RadioAccessFamily.NR) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_NR;
-        }
-        if ((raf & (1 << ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)) != 0) {
-            networkTypeRaf |= TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN;
-        }
-        return (networkTypeRaf == 0) ? TelephonyManager.NETWORK_TYPE_UNKNOWN : networkTypeRaf;
-    }
-
-    /**
-     * Convert to RadioAccessFamily defined in radio/1.4/types.hal
-     * @param networkTypeBitmask {@link TelephonyManager.NetworkTypeBitMask}, the bitmask
-     *        represented by {@link android.telephony.Annotation.NetworkType}
-     * @return The converted RadioAccessFamily
-     */
-    public static int convertToHalRadioAccessFamily(
-            @TelephonyManager.NetworkTypeBitMask int networkTypeBitmask) {
-        int raf = 0;
-
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_GSM) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.GSM;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_GPRS) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.GPRS;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EDGE) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EDGE;
-        }
-        // convert CDMA to IS95A, consistent with ServiceState.networkTypeToRilRadioTechnology
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_CDMA) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.IS95A;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.ONE_X_RTT;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EVDO_0;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EVDO_A;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EVDO_B;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.EHRPD;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSUPA;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSDPA;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSPA) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSPA;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.HSPAP;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_UMTS) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.UMTS;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.TD_SCDMA;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN) != 0) {
-            raf |= (1 << android.hardware.radio.V1_4.RadioTechnology.IWLAN);
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_LTE) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.LTE;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA) != 0) {
-            raf |= android.hardware.radio.V1_0.RadioAccessFamily.LTE_CA;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_NR) != 0) {
-            raf |= android.hardware.radio.V1_4.RadioAccessFamily.NR;
-        }
-        return (raf == 0) ? android.hardware.radio.V1_4.RadioAccessFamily.UNKNOWN : raf;
-    }
-
-    /**
-     * Convert to RadioAccessFamily.aidl
-     * @param networkTypeBitmask {@link TelephonyManager.NetworkTypeBitMask}, the bitmask
-     *        represented by {@link android.telephony.Annotation.NetworkType}
-     * @return The converted RadioAccessFamily
-     */
-    public static int convertToHalRadioAccessFamilyAidl(
-            @TelephonyManager.NetworkTypeBitMask int networkTypeBitmask) {
-        int raf = 0;
-
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_GSM) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.GSM;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_GPRS) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.GPRS;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EDGE) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.EDGE;
-        }
-        // convert CDMA to IS95A, consistent with ServiceState.networkTypeToRilRadioTechnology
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_CDMA) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.IS95A;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.ONE_X_RTT;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_0) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.EVDO_0;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_A) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.EVDO_A;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EVDO_B) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.EVDO_B;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_EHRPD) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.EHRPD;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.HSUPA;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSDPA) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.HSDPA;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSPA) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.HSPA;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_HSPAP) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.HSPAP;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_UMTS) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.UMTS;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_TD_SCDMA) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.TD_SCDMA;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.IWLAN;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_LTE) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.LTE;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_LTE_CA) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.LTE_CA;
-        }
-        if ((networkTypeBitmask & TelephonyManager.NETWORK_TYPE_BITMASK_NR) != 0) {
-            raf |= android.hardware.radio.RadioAccessFamily.NR;
-        }
-        return (raf == 0) ? android.hardware.radio.RadioAccessFamily.UNKNOWN : raf;
-    }
-
-    /**
-     * Convert AccessNetworkType to AccessNetwork defined in radio/1.5/types.hal
-     * @param accessNetworkType Access network type
-     * @return The converted AccessNetwork
-     */
-    public static int convertToHalAccessNetwork(int accessNetworkType) {
-        switch (accessNetworkType) {
-            case AccessNetworkConstants.AccessNetworkType.GERAN:
-                return android.hardware.radio.V1_5.AccessNetwork.GERAN;
-            case AccessNetworkConstants.AccessNetworkType.UTRAN:
-                return android.hardware.radio.V1_5.AccessNetwork.UTRAN;
-            case AccessNetworkConstants.AccessNetworkType.EUTRAN:
-                return android.hardware.radio.V1_5.AccessNetwork.EUTRAN;
-            case AccessNetworkConstants.AccessNetworkType.CDMA2000:
-                return android.hardware.radio.V1_5.AccessNetwork.CDMA2000;
-            case AccessNetworkConstants.AccessNetworkType.IWLAN:
-                return android.hardware.radio.V1_5.AccessNetwork.IWLAN;
-            case AccessNetworkConstants.AccessNetworkType.NGRAN:
-                return android.hardware.radio.V1_5.AccessNetwork.NGRAN;
-            case AccessNetworkConstants.AccessNetworkType.UNKNOWN:
-            default:
-                return android.hardware.radio.V1_5.AccessNetwork.UNKNOWN;
-        }
-    }
-
-    /**
-     * Convert to AccessNetwork.aidl
-     * @param accessNetworkType Access network type
-     * @return The converted AccessNetwork
-     */
-    public static int convertToHalAccessNetworkAidl(int accessNetworkType) {
-        switch (accessNetworkType) {
-            case AccessNetworkConstants.AccessNetworkType.GERAN:
-                return android.hardware.radio.AccessNetwork.GERAN;
-            case AccessNetworkConstants.AccessNetworkType.UTRAN:
-                return android.hardware.radio.AccessNetwork.UTRAN;
-            case AccessNetworkConstants.AccessNetworkType.EUTRAN:
-                return android.hardware.radio.AccessNetwork.EUTRAN;
-            case AccessNetworkConstants.AccessNetworkType.CDMA2000:
-                return android.hardware.radio.AccessNetwork.CDMA2000;
-            case AccessNetworkConstants.AccessNetworkType.IWLAN:
-                return android.hardware.radio.AccessNetwork.IWLAN;
-            case AccessNetworkConstants.AccessNetworkType.NGRAN:
-                return android.hardware.radio.AccessNetwork.NGRAN;
-            case AccessNetworkConstants.AccessNetworkType.UNKNOWN:
-            default:
-                return android.hardware.radio.AccessNetwork.UNKNOWN;
-        }
-    }
-
-    /**
-     * Convert to RadioAccessNetwork defined in radio/1.1/types.hal
-     * @param accessNetworkType Access network type
-     * @return The converted RadioAccessNetwork
-     */
-    public static int convertToHalRadioAccessNetworks(int accessNetworkType) {
-        switch (accessNetworkType) {
-            case AccessNetworkConstants.AccessNetworkType.GERAN:
-                return android.hardware.radio.V1_1.RadioAccessNetworks.GERAN;
-            case AccessNetworkConstants.AccessNetworkType.UTRAN:
-                return android.hardware.radio.V1_1.RadioAccessNetworks.UTRAN;
-            case AccessNetworkConstants.AccessNetworkType.EUTRAN:
-                return android.hardware.radio.V1_1.RadioAccessNetworks.EUTRAN;
-            case AccessNetworkConstants.AccessNetworkType.NGRAN:
-                return android.hardware.radio.V1_5.RadioAccessNetworks.NGRAN;
-            case AccessNetworkConstants.AccessNetworkType.CDMA2000:
-                return android.hardware.radio.V1_5.RadioAccessNetworks.CDMA2000;
-            case AccessNetworkConstants.AccessNetworkType.UNKNOWN:
-            default:
-                return android.hardware.radio.V1_5.RadioAccessNetworks.UNKNOWN;
-        }
-    }
-
-    /**
-     * Convert RadioAccessNetworks defined in radio/1.5/types.hal to AccessNetworkType
-     * @param ran RadioAccessNetwork defined in radio/1.5/types.hal
-     * @return The converted AccessNetworkType
-     */
-    public static int convertHalRadioAccessNetworks(int ran) {
-        switch (ran) {
-            case android.hardware.radio.V1_5.RadioAccessNetworks.GERAN:
-                return AccessNetworkConstants.AccessNetworkType.GERAN;
-            case android.hardware.radio.V1_5.RadioAccessNetworks.UTRAN:
-                return AccessNetworkConstants.AccessNetworkType.UTRAN;
-            case android.hardware.radio.V1_5.RadioAccessNetworks.EUTRAN:
-                return AccessNetworkConstants.AccessNetworkType.EUTRAN;
-            case android.hardware.radio.V1_5.RadioAccessNetworks.NGRAN:
-                return AccessNetworkConstants.AccessNetworkType.NGRAN;
-            case android.hardware.radio.V1_5.RadioAccessNetworks.CDMA2000:
-                return AccessNetworkConstants.AccessNetworkType.CDMA2000;
-            case android.hardware.radio.V1_5.RadioAccessNetworks.UNKNOWN:
-            default:
-                return AccessNetworkConstants.AccessNetworkType.UNKNOWN;
-        }
-    }
-
-    /**
-     * Convert to SimApdu defined in radio/1.0/types.hal
-     * @param channel channel
-     * @param cla cla
-     * @param instruction instruction
-     * @param p1 p1
-     * @param p2 p2
-     * @param p3 p3
-     * @param data data
-     * @return The converted SimApdu
-     */
-    public static android.hardware.radio.V1_0.SimApdu convertToHalSimApdu(int channel, int cla,
-            int instruction, int p1, int p2, int p3, String data) {
-        android.hardware.radio.V1_0.SimApdu msg = new android.hardware.radio.V1_0.SimApdu();
-        msg.sessionId = channel;
-        msg.cla = cla;
-        msg.instruction = instruction;
-        msg.p1 = p1;
-        msg.p2 = p2;
-        msg.p3 = p3;
-        msg.data = convertNullToEmptyString(data);
-        return msg;
-    }
-
-    /**
-     * Convert to SimApdu.aidl
-     * @param channel channel
-     * @param cla cla
-     * @param instruction instruction
-     * @param p1 p1
-     * @param p2 p2
-     * @param p3 p3
-     * @param data data
-     * @return The converted SimApdu
-     */
-    public static android.hardware.radio.sim.SimApdu convertToHalSimApduAidl(int channel, int cla,
-            int instruction, int p1, int p2, int p3, String data) {
-        android.hardware.radio.sim.SimApdu msg = new android.hardware.radio.sim.SimApdu();
-        msg.sessionId = channel;
-        msg.cla = cla;
-        msg.instruction = instruction;
-        msg.p1 = p1;
-        msg.p2 = p2;
-        msg.p3 = p3;
-        msg.data = convertNullToEmptyString(data);
-        return msg;
-    }
-
-    /**
-     * Convert to SimLockMultiSimPolicy defined in radio/1.4/types.hal
-     * @param policy Multi SIM policy
-     * @return The converted SimLockMultiSimPolicy
-     */
-    public static int convertToHalSimLockMultiSimPolicy(int policy) {
-        switch (policy) {
-            case CarrierRestrictionRules.MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT:
-                return android.hardware.radio.V1_4.SimLockMultiSimPolicy
-                        .ONE_VALID_SIM_MUST_BE_PRESENT;
-            case CarrierRestrictionRules.MULTISIM_POLICY_NONE:
-                // fallthrough
-            default:
-                return android.hardware.radio.V1_4.SimLockMultiSimPolicy.NO_MULTISIM_POLICY;
-
-        }
-    }
-
-    /**
-     * Convert to SimLockMultiSimPolicy.aidl
-     * @param policy Multi SIM policy
-     * @return The converted SimLockMultiSimPolicy
-     */
-    public static int convertToHalSimLockMultiSimPolicyAidl(int policy) {
-        switch (policy) {
-            case CarrierRestrictionRules.MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT:
-                return android.hardware.radio.sim.SimLockMultiSimPolicy
-                        .ONE_VALID_SIM_MUST_BE_PRESENT;
-            case CarrierRestrictionRules.MULTISIM_POLICY_NONE:
-                // fallthrough
-            default:
-                return android.hardware.radio.sim.SimLockMultiSimPolicy.NO_MULTISIM_POLICY;
-
-        }
-    }
-
-    /**
-     * Convert a list of CarrierIdentifiers into a list of Carriers defined in radio/1.0/types.hal
-     * @param carriers List of CarrierIdentifiers
-     * @return The converted list of Carriers
-     */
-    public static ArrayList<android.hardware.radio.V1_0.Carrier> convertToHalCarrierRestrictionList(
-            List<CarrierIdentifier> carriers) {
-        ArrayList<android.hardware.radio.V1_0.Carrier> result = new ArrayList<>();
-        for (CarrierIdentifier ci : carriers) {
-            android.hardware.radio.V1_0.Carrier c = new android.hardware.radio.V1_0.Carrier();
-            c.mcc = convertNullToEmptyString(ci.getMcc());
-            c.mnc = convertNullToEmptyString(ci.getMnc());
-            int matchType = CarrierIdentifier.MatchType.ALL;
-            String matchData = null;
-            if (!TextUtils.isEmpty(ci.getSpn())) {
-                matchType = CarrierIdentifier.MatchType.SPN;
-                matchData = ci.getSpn();
-            } else if (!TextUtils.isEmpty(ci.getImsi())) {
-                matchType = CarrierIdentifier.MatchType.IMSI_PREFIX;
-                matchData = ci.getImsi();
-            } else if (!TextUtils.isEmpty(ci.getGid1())) {
-                matchType = CarrierIdentifier.MatchType.GID1;
-                matchData = ci.getGid1();
-            } else if (!TextUtils.isEmpty(ci.getGid2())) {
-                matchType = CarrierIdentifier.MatchType.GID2;
-                matchData = ci.getGid2();
-            }
-            c.matchType = matchType;
-            c.matchData = convertNullToEmptyString(matchData);
-            result.add(c);
-        }
-        return result;
-    }
-
-    /**
-     * Convert a list of CarrierIdentifiers into an array of Carrier.aidl
-     * @param carriers List of CarrierIdentifiers
-     * @return The converted array of Carriers
-     */
-    public static android.hardware.radio.sim.Carrier[] convertToHalCarrierRestrictionListAidl(
-            List<CarrierIdentifier> carriers) {
-        android.hardware.radio.sim.Carrier[] result =
-                new android.hardware.radio.sim.Carrier[carriers.size()];
-        for (int i = 0; i < carriers.size(); i++) {
-            CarrierIdentifier ci = carriers.get(i);
-            android.hardware.radio.sim.Carrier carrier = new android.hardware.radio.sim.Carrier();
-            carrier.mcc = convertNullToEmptyString(ci.getMcc());
-            carrier.mnc = convertNullToEmptyString(ci.getMnc());
-            int matchType = CarrierIdentifier.MatchType.ALL;
-            String matchData = null;
-            if (!TextUtils.isEmpty(ci.getSpn())) {
-                matchType = CarrierIdentifier.MatchType.SPN;
-                matchData = ci.getSpn();
-            } else if (!TextUtils.isEmpty(ci.getImsi())) {
-                matchType = CarrierIdentifier.MatchType.IMSI_PREFIX;
-                matchData = ci.getImsi();
-            } else if (!TextUtils.isEmpty(ci.getGid1())) {
-                matchType = CarrierIdentifier.MatchType.GID1;
-                matchData = ci.getGid1();
-            } else if (!TextUtils.isEmpty(ci.getGid2())) {
-                matchType = CarrierIdentifier.MatchType.GID2;
-                matchData = ci.getGid2();
-            }
-            carrier.matchType = matchType;
-            carrier.matchData = convertNullToEmptyString(matchData);
-            result[i] = carrier;
-        }
-        return result;
-    }
-
-    /**
-     * Convert to Dial defined in radio/1.0/types.hal
-     * @param address Address
-     * @param clirMode CLIR mode
-     * @param uusInfo UUS info
-     * @return The converted Dial
-     */
-    public static android.hardware.radio.V1_0.Dial convertToHalDial(String address, int clirMode,
-            UUSInfo uusInfo) {
-        android.hardware.radio.V1_0.Dial dial = new android.hardware.radio.V1_0.Dial();
-        dial.address = convertNullToEmptyString(address);
-        dial.clir = clirMode;
-        if (uusInfo != null) {
-            android.hardware.radio.V1_0.UusInfo info = new android.hardware.radio.V1_0.UusInfo();
-            info.uusType = uusInfo.getType();
-            info.uusDcs = uusInfo.getDcs();
-            info.uusData = new String(uusInfo.getUserData());
-            dial.uusInfo.add(info);
-        }
-        return dial;
-    }
-
-    /**
-     * Convert to Dial.aidl
-     * @param address Address
-     * @param clirMode CLIR mode
-     * @param uusInfo UUS info
-     * @return The converted Dial.aidl
-     */
-    public static android.hardware.radio.voice.Dial convertToHalDialAidl(String address,
-            int clirMode, UUSInfo uusInfo) {
-        android.hardware.radio.voice.Dial dial = new android.hardware.radio.voice.Dial();
-        dial.address = convertNullToEmptyString(address);
-        dial.clir = clirMode;
-        if (uusInfo != null) {
-            android.hardware.radio.voice.UusInfo info = new android.hardware.radio.voice.UusInfo();
-            info.uusType = uusInfo.getType();
-            info.uusDcs = uusInfo.getDcs();
-            info.uusData = new String(uusInfo.getUserData());
-            dial.uusInfo = new android.hardware.radio.voice.UusInfo[] {info};
-        } else {
-            dial.uusInfo = new android.hardware.radio.voice.UusInfo[0];
-        }
-        return dial;
-    }
-
-    /**
-     * Convert to SignalThresholdInfo defined in radio/1.5/types.hal
-     * @param signalThresholdInfo Signal threshold info
-     * @return The converted SignalThresholdInfo
-     */
-    public static android.hardware.radio.V1_5.SignalThresholdInfo convertToHalSignalThresholdInfo(
-            SignalThresholdInfo signalThresholdInfo) {
-        android.hardware.radio.V1_5.SignalThresholdInfo signalThresholdInfoHal =
-                new android.hardware.radio.V1_5.SignalThresholdInfo();
-        signalThresholdInfoHal.signalMeasurement = signalThresholdInfo.getSignalMeasurementType();
-        signalThresholdInfoHal.hysteresisMs = signalThresholdInfo.getHysteresisMs();
-        signalThresholdInfoHal.hysteresisDb = signalThresholdInfo.getHysteresisDb();
-        signalThresholdInfoHal.thresholds = primitiveArrayToArrayList(
-                signalThresholdInfo.getThresholds());
-        signalThresholdInfoHal.isEnabled = signalThresholdInfo.isEnabled();
-        return signalThresholdInfoHal;
-    }
-
-    /**
-     * Convert to SignalThresholdInfo.aidl
-     * @param signalThresholdInfo Signal threshold info
-     * @return The converted SignalThresholdInfo
-     */
-    public static android.hardware.radio.network.SignalThresholdInfo
-            convertToHalSignalThresholdInfoAidl(SignalThresholdInfo signalThresholdInfo) {
-        android.hardware.radio.network.SignalThresholdInfo signalThresholdInfoHal =
-                new android.hardware.radio.network.SignalThresholdInfo();
-        signalThresholdInfoHal.signalMeasurement = signalThresholdInfo.getSignalMeasurementType();
-        signalThresholdInfoHal.hysteresisMs = signalThresholdInfo.getHysteresisMs();
-        signalThresholdInfoHal.hysteresisDb = signalThresholdInfo.getHysteresisDb();
-        signalThresholdInfoHal.thresholds = signalThresholdInfo.getThresholds();
-        signalThresholdInfoHal.isEnabled = signalThresholdInfo.isEnabled();
-        signalThresholdInfoHal.ran = signalThresholdInfo.getRadioAccessNetworkType();
-        return signalThresholdInfoHal;
-    }
-
-    /**
-     * Convert to SmsWriteArgsStatus defined in radio/1.0/types.hal
-     * @param status StatusOnIcc
-     * @return The converted SmsWriteArgsStatus defined in radio/1.0/types.hal
-     */
-    public static int convertToHalSmsWriteArgsStatus(int status) {
-        switch (status & 0x7) {
-            case SmsManager.STATUS_ON_ICC_READ:
-                return android.hardware.radio.V1_0.SmsWriteArgsStatus.REC_READ;
-            case SmsManager.STATUS_ON_ICC_UNREAD:
-                return android.hardware.radio.V1_0.SmsWriteArgsStatus.REC_UNREAD;
-            case SmsManager.STATUS_ON_ICC_SENT:
-                return android.hardware.radio.V1_0.SmsWriteArgsStatus.STO_SENT;
-            case SmsManager.STATUS_ON_ICC_UNSENT:
-                return android.hardware.radio.V1_0.SmsWriteArgsStatus.STO_UNSENT;
-            default:
-                return android.hardware.radio.V1_0.SmsWriteArgsStatus.REC_READ;
-        }
-    }
-
-    /**
-     * Convert to statuses defined in SmsWriteArgs.aidl
-     * @param status StatusOnIcc
-     * @return The converted statuses defined in SmsWriteArgs.aidl
-     */
-    public static int convertToHalSmsWriteArgsStatusAidl(int status) {
-        switch (status & 0x7) {
-            case SmsManager.STATUS_ON_ICC_READ:
-                return android.hardware.radio.messaging.SmsWriteArgs.STATUS_REC_READ;
-            case SmsManager.STATUS_ON_ICC_UNREAD:
-                return android.hardware.radio.messaging.SmsWriteArgs.STATUS_REC_UNREAD;
-            case SmsManager.STATUS_ON_ICC_SENT:
-                return android.hardware.radio.messaging.SmsWriteArgs.STATUS_STO_SENT;
-            case SmsManager.STATUS_ON_ICC_UNSENT:
-                return android.hardware.radio.messaging.SmsWriteArgs.STATUS_STO_UNSENT;
-            default:
-                return android.hardware.radio.messaging.SmsWriteArgs.STATUS_REC_READ;
-        }
-    }
-
-    /**
-     * Convert a list of HardwareConfig defined in radio/1.0/types.hal to a list of HardwareConfig
-     * @param hwListRil List of HardwareConfig defined in radio/1.0/types.hal
-     * @return The converted list of HardwareConfig
-     */
-    public static ArrayList<HardwareConfig> convertHalHardwareConfigList(
-            ArrayList<android.hardware.radio.V1_0.HardwareConfig> hwListRil) {
-        int num;
-        ArrayList<HardwareConfig> response;
-        HardwareConfig hw;
-
-        num = hwListRil.size();
-        response = new ArrayList<>(num);
-
-        for (android.hardware.radio.V1_0.HardwareConfig hwRil : hwListRil) {
-            int type = hwRil.type;
-            switch(type) {
-                case HardwareConfig.DEV_HARDWARE_TYPE_MODEM: {
-                    hw = new HardwareConfig(type);
-                    android.hardware.radio.V1_0.HardwareConfigModem hwModem = hwRil.modem.get(0);
-                    hw.assignModem(hwRil.uuid, hwRil.state, hwModem.rilModel, hwModem.rat,
-                            hwModem.maxVoice, hwModem.maxData, hwModem.maxStandby);
-                    break;
-                }
-                case HardwareConfig.DEV_HARDWARE_TYPE_SIM: {
-                    hw = new HardwareConfig(type);
-                    hw.assignSim(hwRil.uuid, hwRil.state, hwRil.sim.get(0).modemUuid);
-                    break;
-                }
-                default: {
-                    throw new RuntimeException(
-                            "RIL_REQUEST_GET_HARDWARE_CONFIG invalid hardware type:" + type);
-                }
-            }
-            response.add(hw);
-        }
-        return response;
-    }
-
-    /**
-     * Convert a list of HardwareConfig defined in HardwareConfig.aidl to a list of HardwareConfig
-     * @param hwListRil List of HardwareConfig defined in HardwareConfig.aidl
-     * @return The converted list of HardwareConfig
-     */
-    public static ArrayList<HardwareConfig> convertHalHardwareConfigList(
-            android.hardware.radio.modem.HardwareConfig[] hwListRil) {
-        ArrayList<HardwareConfig> response = new ArrayList<>(hwListRil.length);
-        HardwareConfig hw;
-
-        for (android.hardware.radio.modem.HardwareConfig hwRil : hwListRil) {
-            int type = hwRil.type;
-            switch (type) {
-                case HardwareConfig.DEV_HARDWARE_TYPE_MODEM: {
-                    hw = new HardwareConfig(type);
-                    android.hardware.radio.modem.HardwareConfigModem hwModem = hwRil.modem[0];
-                    hw.assignModem(hwRil.uuid, hwRil.state, hwModem.rilModel, hwModem.rat,
-                            hwModem.maxVoiceCalls, hwModem.maxDataCalls, hwModem.maxStandby);
-                    break;
-                }
-                case HardwareConfig.DEV_HARDWARE_TYPE_SIM: {
-                    hw = new HardwareConfig(type);
-                    hw.assignSim(hwRil.uuid, hwRil.state, hwRil.sim[0].modemUuid);
-                    break;
-                }
-                default: {
-                    throw new RuntimeException(
-                            "RIL_REQUEST_GET_HARDWARE_CONFIG invalid hardware type:" + type);
-                }
-            }
-            response.add(hw);
-        }
-        return response;
-    }
-
-    /**
-     * Convert RadioCapability defined in radio/1.0/types.hal to RadioCapability
-     * @param rc RadioCapability defined in radio/1.0/types.hal
-     * @param ril RIL
-     * @return The converted RadioCapability
-     */
-    public static RadioCapability convertHalRadioCapability(
-            android.hardware.radio.V1_0.RadioCapability rc, RIL ril) {
-        int session = rc.session;
-        int phase = rc.phase;
-        int rat = convertHalNetworkTypeBitMask(rc.raf);
-        String logicModemUuid = rc.logicalModemUuid;
-        int status = rc.status;
-
-        ril.riljLog("convertHalRadioCapability: session=" + session + ", phase=" + phase + ", rat="
-                + rat + ", logicModemUuid=" + logicModemUuid + ", status=" + status + ", rcRil.raf="
-                + rc.raf);
-        return new RadioCapability(ril.mPhoneId, session, phase, rat, logicModemUuid, status);
-    }
-
-    /**
-     * Convert RadioCapability defined in RadioCapability.aidl to RadioCapability
-     * @param rc RadioCapability defined in RadioCapability.aidl
-     * @param ril RIL
-     * @return The converted RadioCapability
-     */
-    public static RadioCapability convertHalRadioCapability(
-            android.hardware.radio.modem.RadioCapability rc, RIL ril) {
-        int session = rc.session;
-        int phase = rc.phase;
-        int rat = convertHalNetworkTypeBitMask(rc.raf);
-        String logicModemUuid = rc.logicalModemUuid;
-        int status = rc.status;
-
-        ril.riljLog("convertHalRadioCapability: session=" + session + ", phase=" + phase + ", rat="
-                + rat + ", logicModemUuid=" + logicModemUuid + ", status=" + status + ", rcRil.raf="
-                + rc.raf);
-        return new RadioCapability(ril.mPhoneId, session, phase, rat, logicModemUuid, status);
-    }
-
-    /**
-     * Convert LceDataInfo defined in radio/1.0/types.hal and LinkCapacityEstimate defined in
-     * radio/1.2, 1.6/types.hal to a list of LinkCapacityEstimates
-     * @param lceObj LceDataInfo defined in radio/1.0/types.hal or LinkCapacityEstimate defined in
-     *        radio/1.2, 1.6/types.hal
-     * @return The converted list of LinkCapacityEstimates
-     */
-    public static List<LinkCapacityEstimate> convertHalLceData(Object lceObj) {
-        final List<LinkCapacityEstimate> lceList = new ArrayList<>();
-        if (lceObj == null) return lceList;
-        if (lceObj instanceof android.hardware.radio.V1_0.LceDataInfo) {
-            android.hardware.radio.V1_0.LceDataInfo lce =
-                    (android.hardware.radio.V1_0.LceDataInfo) lceObj;
-            lceList.add(new LinkCapacityEstimate(LinkCapacityEstimate.LCE_TYPE_COMBINED,
-                    lce.lastHopCapacityKbps, LinkCapacityEstimate.INVALID));
-        } else if (lceObj instanceof android.hardware.radio.V1_2.LinkCapacityEstimate) {
-            android.hardware.radio.V1_2.LinkCapacityEstimate lce =
-                    (android.hardware.radio.V1_2.LinkCapacityEstimate) lceObj;
-            lceList.add(new LinkCapacityEstimate(LinkCapacityEstimate.LCE_TYPE_COMBINED,
-                    lce.downlinkCapacityKbps, lce.uplinkCapacityKbps));
-        } else if (lceObj instanceof android.hardware.radio.V1_6.LinkCapacityEstimate) {
-            android.hardware.radio.V1_6.LinkCapacityEstimate lce =
-                    (android.hardware.radio.V1_6.LinkCapacityEstimate) lceObj;
-            int primaryDownlinkCapacityKbps = lce.downlinkCapacityKbps;
-            int primaryUplinkCapacityKbps = lce.uplinkCapacityKbps;
-            if (primaryDownlinkCapacityKbps != LinkCapacityEstimate.INVALID
-                    && lce.secondaryDownlinkCapacityKbps != LinkCapacityEstimate.INVALID) {
-                primaryDownlinkCapacityKbps =
-                        lce.downlinkCapacityKbps - lce.secondaryDownlinkCapacityKbps;
-            }
-            if (primaryUplinkCapacityKbps != LinkCapacityEstimate.INVALID
-                    && lce.secondaryUplinkCapacityKbps != LinkCapacityEstimate.INVALID) {
-                primaryUplinkCapacityKbps =
-                        lce.uplinkCapacityKbps - lce.secondaryUplinkCapacityKbps;
-            }
-            lceList.add(new LinkCapacityEstimate(LinkCapacityEstimate.LCE_TYPE_PRIMARY,
-                    primaryDownlinkCapacityKbps, primaryUplinkCapacityKbps));
-            lceList.add(new LinkCapacityEstimate(LinkCapacityEstimate.LCE_TYPE_SECONDARY,
-                    lce.secondaryDownlinkCapacityKbps, lce.secondaryUplinkCapacityKbps));
-        }
-        return lceList;
-    }
-
-    /**
-     * Convert LceDataInfo defined in LceDataInfo.aidl to a list of LinkCapacityEstimates
-     * @param lce LceDataInfo defined in LceDataInfo.aidl
-     * @return The converted list of LinkCapacityEstimates
-     */
-    public static List<LinkCapacityEstimate> convertHalLceData(
-            android.hardware.radio.network.LceDataInfo lce) {
-        final List<LinkCapacityEstimate> lceList = new ArrayList<>();
-        lceList.add(new LinkCapacityEstimate(LinkCapacityEstimate.LCE_TYPE_COMBINED,
-                lce.lastHopCapacityKbps, LinkCapacityEstimate.INVALID));
-        return lceList;
-    }
-
-    /**
-     * Convert LinkCapacityEstimate defined in LinkCapacityEstimate.aidl to a list of
-     * LinkCapacityEstimates
-     * @param lce LinkCapacityEstimate defined in LinkCapacityEstimate.aidl
-     * @return The converted list of LinkCapacityEstimates
-     */
-    public static List<LinkCapacityEstimate> convertHalLceData(
-            android.hardware.radio.network.LinkCapacityEstimate lce) {
-        final List<LinkCapacityEstimate> lceList = new ArrayList<>();
-        int primaryDownlinkCapacityKbps = lce.downlinkCapacityKbps;
-        int primaryUplinkCapacityKbps = lce.uplinkCapacityKbps;
-        if (primaryDownlinkCapacityKbps != LinkCapacityEstimate.INVALID
-                && lce.secondaryDownlinkCapacityKbps != LinkCapacityEstimate.INVALID) {
-            primaryDownlinkCapacityKbps =
-                    lce.downlinkCapacityKbps - lce.secondaryDownlinkCapacityKbps;
-        }
-        if (primaryUplinkCapacityKbps != LinkCapacityEstimate.INVALID
-                && lce.secondaryUplinkCapacityKbps != LinkCapacityEstimate.INVALID) {
-            primaryUplinkCapacityKbps =
-                    lce.uplinkCapacityKbps - lce.secondaryUplinkCapacityKbps;
-        }
-        lceList.add(new LinkCapacityEstimate(LinkCapacityEstimate.LCE_TYPE_PRIMARY,
-                primaryDownlinkCapacityKbps, primaryUplinkCapacityKbps));
-        lceList.add(new LinkCapacityEstimate(LinkCapacityEstimate.LCE_TYPE_SECONDARY,
-                lce.secondaryDownlinkCapacityKbps, lce.secondaryUplinkCapacityKbps));
-        return lceList;
-    }
-
-
-    /**
-     * Convert a list of CellInfo defined in radio/1.0, 1.2, 1.4, 1.5, 1.6/types.hal to a list of
-     * CellInfos
-     * @param records List of CellInfo defined in radio/1.0, 1.2, 1.4, 1.5, 1.6/types.hal
-     * @return The converted list of CellInfos
-     */
-    public static ArrayList<CellInfo> convertHalCellInfoList(ArrayList<Object> records) {
-        ArrayList<CellInfo> response = new ArrayList<>(records.size());
-        if (records.isEmpty()) return response;
-        final long nanotime = SystemClock.elapsedRealtimeNanos();
-        for (Object obj : records) {
-            response.add(convertHalCellInfo(obj, nanotime));
-        }
-        return response;
-    }
-
-    /**
-     * Convert a list of CellInfo defined in CellInfo.aidl to a list of CellInfos
-     * @param records List of CellInfo defined in CellInfo.aidl
-     * @return The converted list of CellInfos
-     */
-    public static ArrayList<CellInfo> convertHalCellInfoList(
-            android.hardware.radio.network.CellInfo[] records) {
-        ArrayList<CellInfo> response = new ArrayList<>(records.length);
-        if (records.length == 0) return response;
-        final long nanotime = SystemClock.elapsedRealtimeNanos();
-        for (android.hardware.radio.network.CellInfo ci : records) {
-            response.add(convertHalCellInfo(ci, nanotime));
-        }
-        return response;
-    }
-
-    /**
-     * Convert a CellInfo defined in radio/1.0, 1.2, 1.4, 1.5, 1.6/types.hal to CellInfo
-     * @param cellInfo CellInfo defined in radio/1.0, 1.2, 1.4, 1.5, 1.6/types.hal
-     * @param nanotime time the CellInfo was created
-     * @return The converted CellInfo
-     */
-    private static CellInfo convertHalCellInfo(Object cellInfo, long nanotime) {
-        if (cellInfo == null) return null;
-        int type;
-        int connectionStatus;
-        boolean registered;
-        CellIdentityGsm gsmCi = null;
-        CellSignalStrengthGsm gsmSs = null;
-        CellIdentityCdma cdmaCi = null;
-        CellSignalStrengthCdma cdmaSs = null;
-        CellIdentityLte lteCi = null;
-        CellSignalStrengthLte lteSs = null;
-        CellConfigLte lteCc = null;
-        CellIdentityWcdma wcdmaCi = null;
-        CellSignalStrengthWcdma wcdmaSs = null;
-        CellIdentityTdscdma tdscdmaCi = null;
-        CellSignalStrengthTdscdma tdscdmaSs = null;
-        CellIdentityNr nrCi = null;
-        CellSignalStrengthNr nrSs = null;
-        if (cellInfo instanceof android.hardware.radio.V1_0.CellInfo) {
-            final android.hardware.radio.V1_0.CellInfo record =
-                    (android.hardware.radio.V1_0.CellInfo) cellInfo;
-            connectionStatus = CellInfo.CONNECTION_UNKNOWN;
-            registered = record.registered;
-            switch (record.cellInfoType) {
-                case android.hardware.radio.V1_0.CellInfoType.GSM:
-                    type = CellInfo.TYPE_GSM;
-                    android.hardware.radio.V1_0.CellInfoGsm gsm = record.gsm.get(0);
-                    gsmCi = convertHalCellIdentityGsm(gsm.cellIdentityGsm);
-                    gsmSs = convertHalGsmSignalStrength(gsm.signalStrengthGsm);
-                    break;
-                case android.hardware.radio.V1_0.CellInfoType.CDMA:
-                    type = CellInfo.TYPE_CDMA;
-                    android.hardware.radio.V1_0.CellInfoCdma cdma = record.cdma.get(0);
-                    cdmaCi = convertHalCellIdentityCdma(cdma.cellIdentityCdma);
-                    cdmaSs = convertHalCdmaSignalStrength(
-                            cdma.signalStrengthCdma, cdma.signalStrengthEvdo);
-                    break;
-                case android.hardware.radio.V1_0.CellInfoType.LTE:
-                    type = CellInfo.TYPE_LTE;
-                    android.hardware.radio.V1_0.CellInfoLte lte = record.lte.get(0);
-                    lteCi = convertHalCellIdentityLte(lte.cellIdentityLte);
-                    lteSs = convertHalLteSignalStrength(lte.signalStrengthLte);
-                    lteCc = new CellConfigLte();
-                    break;
-                case android.hardware.radio.V1_0.CellInfoType.WCDMA:
-                    type = CellInfo.TYPE_WCDMA;
-                    android.hardware.radio.V1_0.CellInfoWcdma wcdma = record.wcdma.get(0);
-                    wcdmaCi = convertHalCellIdentityWcdma(wcdma.cellIdentityWcdma);
-                    wcdmaSs = convertHalWcdmaSignalStrength(wcdma.signalStrengthWcdma);
-                    break;
-                case android.hardware.radio.V1_0.CellInfoType.TD_SCDMA:
-                    type = CellInfo.TYPE_TDSCDMA;
-                    android.hardware.radio.V1_0.CellInfoTdscdma tdscdma = record.tdscdma.get(0);
-                    tdscdmaCi = convertHalCellIdentityTdscdma(tdscdma.cellIdentityTdscdma);
-                    tdscdmaSs = convertHalTdscdmaSignalStrength(tdscdma.signalStrengthTdscdma);
-                    break;
-                default: return null;
-            }
-        } else if (cellInfo instanceof android.hardware.radio.V1_2.CellInfo) {
-            final android.hardware.radio.V1_2.CellInfo record =
-                    (android.hardware.radio.V1_2.CellInfo) cellInfo;
-            connectionStatus = record.connectionStatus;
-            registered = record.registered;
-            switch(record.cellInfoType) {
-                case android.hardware.radio.V1_0.CellInfoType.GSM:
-                    type = CellInfo.TYPE_GSM;
-                    android.hardware.radio.V1_2.CellInfoGsm gsm = record.gsm.get(0);
-                    gsmCi = convertHalCellIdentityGsm(gsm.cellIdentityGsm);
-                    gsmSs = convertHalGsmSignalStrength(gsm.signalStrengthGsm);
-                    break;
-                case android.hardware.radio.V1_0.CellInfoType.CDMA:
-                    type = CellInfo.TYPE_CDMA;
-                    android.hardware.radio.V1_2.CellInfoCdma cdma = record.cdma.get(0);
-                    cdmaCi = convertHalCellIdentityCdma(cdma.cellIdentityCdma);
-                    cdmaSs = convertHalCdmaSignalStrength(
-                            cdma.signalStrengthCdma, cdma.signalStrengthEvdo);
-                    break;
-                case android.hardware.radio.V1_0.CellInfoType.LTE:
-                    type = CellInfo.TYPE_LTE;
-                    android.hardware.radio.V1_2.CellInfoLte lte = record.lte.get(0);
-                    lteCi = convertHalCellIdentityLte(lte.cellIdentityLte);
-                    lteSs = convertHalLteSignalStrength(lte.signalStrengthLte);
-                    lteCc = new CellConfigLte();
-                    break;
-                case android.hardware.radio.V1_0.CellInfoType.WCDMA:
-                    type = CellInfo.TYPE_WCDMA;
-                    android.hardware.radio.V1_2.CellInfoWcdma wcdma = record.wcdma.get(0);
-                    wcdmaCi = convertHalCellIdentityWcdma(wcdma.cellIdentityWcdma);
-                    wcdmaSs = convertHalWcdmaSignalStrength(wcdma.signalStrengthWcdma);
-                    break;
-                case android.hardware.radio.V1_0.CellInfoType.TD_SCDMA:
-                    type = CellInfo.TYPE_TDSCDMA;
-                    android.hardware.radio.V1_2.CellInfoTdscdma tdscdma = record.tdscdma.get(0);
-                    tdscdmaCi = convertHalCellIdentityTdscdma(tdscdma.cellIdentityTdscdma);
-                    tdscdmaSs = convertHalTdscdmaSignalStrength(tdscdma.signalStrengthTdscdma);
-                    break;
-                default: return null;
-            }
-        } else if (cellInfo instanceof android.hardware.radio.V1_4.CellInfo) {
-            final android.hardware.radio.V1_4.CellInfo record =
-                    (android.hardware.radio.V1_4.CellInfo) cellInfo;
-            connectionStatus = record.connectionStatus;
-            registered = record.isRegistered;
-            switch (record.info.getDiscriminator()) {
-                case android.hardware.radio.V1_4.CellInfo.Info.hidl_discriminator.gsm:
-                    type = CellInfo.TYPE_GSM;
-                    android.hardware.radio.V1_2.CellInfoGsm gsm = record.info.gsm();
-                    gsmCi = convertHalCellIdentityGsm(gsm.cellIdentityGsm);
-                    gsmSs = convertHalGsmSignalStrength(gsm.signalStrengthGsm);
-                    break;
-                case android.hardware.radio.V1_4.CellInfo.Info.hidl_discriminator.cdma:
-                    type = CellInfo.TYPE_CDMA;
-                    android.hardware.radio.V1_2.CellInfoCdma cdma = record.info.cdma();
-                    cdmaCi = convertHalCellIdentityCdma(cdma.cellIdentityCdma);
-                    cdmaSs = convertHalCdmaSignalStrength(
-                            cdma.signalStrengthCdma, cdma.signalStrengthEvdo);
-                    break;
-                case android.hardware.radio.V1_4.CellInfo.Info.hidl_discriminator.lte:
-                    type = CellInfo.TYPE_LTE;
-                    android.hardware.radio.V1_4.CellInfoLte lte = record.info.lte();
-                    lteCi = convertHalCellIdentityLte(lte.base.cellIdentityLte);
-                    lteSs = convertHalLteSignalStrength(lte.base.signalStrengthLte);
-                    lteCc = new CellConfigLte(lte.cellConfig.isEndcAvailable);
-                    break;
-                case android.hardware.radio.V1_4.CellInfo.Info.hidl_discriminator.wcdma:
-                    type = CellInfo.TYPE_WCDMA;
-                    android.hardware.radio.V1_2.CellInfoWcdma wcdma = record.info.wcdma();
-                    wcdmaCi = convertHalCellIdentityWcdma(wcdma.cellIdentityWcdma);
-                    wcdmaSs = convertHalWcdmaSignalStrength(wcdma.signalStrengthWcdma);
-                    break;
-                case android.hardware.radio.V1_4.CellInfo.Info.hidl_discriminator.tdscdma:
-                    type = CellInfo.TYPE_TDSCDMA;
-                    android.hardware.radio.V1_2.CellInfoTdscdma tdscdma = record.info.tdscdma();
-                    tdscdmaCi = convertHalCellIdentityTdscdma(tdscdma.cellIdentityTdscdma);
-                    tdscdmaSs = convertHalTdscdmaSignalStrength(tdscdma.signalStrengthTdscdma);
-                    break;
-                case android.hardware.radio.V1_4.CellInfo.Info.hidl_discriminator.nr:
-                    type = CellInfo.TYPE_NR;
-                    android.hardware.radio.V1_4.CellInfoNr nr = record.info.nr();
-                    nrCi = convertHalCellIdentityNr(nr.cellidentity);
-                    nrSs = convertHalNrSignalStrength(nr.signalStrength);
-                    break;
-                default: return null;
-            }
-        } else if (cellInfo instanceof android.hardware.radio.V1_5.CellInfo) {
-            final android.hardware.radio.V1_5.CellInfo record =
-                    (android.hardware.radio.V1_5.CellInfo) cellInfo;
-            connectionStatus = record.connectionStatus;
-            registered = record.registered;
-            switch (record.ratSpecificInfo.getDiscriminator()) {
-                case android.hardware.radio.V1_5.CellInfo
-                        .CellInfoRatSpecificInfo.hidl_discriminator.gsm:
-                    type = CellInfo.TYPE_GSM;
-                    android.hardware.radio.V1_5.CellInfoGsm gsm = record.ratSpecificInfo.gsm();
-                    gsmCi = convertHalCellIdentityGsm(gsm.cellIdentityGsm);
-                    gsmSs = convertHalGsmSignalStrength(gsm.signalStrengthGsm);
-                    break;
-                case android.hardware.radio.V1_5.CellInfo
-                        .CellInfoRatSpecificInfo.hidl_discriminator.cdma:
-                    type = CellInfo.TYPE_CDMA;
-                    android.hardware.radio.V1_2.CellInfoCdma cdma = record.ratSpecificInfo.cdma();
-                    cdmaCi = convertHalCellIdentityCdma(cdma.cellIdentityCdma);
-                    cdmaSs = convertHalCdmaSignalStrength(
-                            cdma.signalStrengthCdma, cdma.signalStrengthEvdo);
-                    break;
-                case android.hardware.radio.V1_5.CellInfo
-                        .CellInfoRatSpecificInfo.hidl_discriminator.lte:
-                    type = CellInfo.TYPE_LTE;
-                    android.hardware.radio.V1_5.CellInfoLte lte = record.ratSpecificInfo.lte();
-                    lteCi = convertHalCellIdentityLte(lte.cellIdentityLte);
-                    lteSs = convertHalLteSignalStrength(lte.signalStrengthLte);
-                    lteCc = new CellConfigLte();
-                    break;
-                case android.hardware.radio.V1_5.CellInfo
-                        .CellInfoRatSpecificInfo.hidl_discriminator.wcdma:
-                    type = CellInfo.TYPE_WCDMA;
-                    android.hardware.radio.V1_5.CellInfoWcdma wcdma =
-                            record.ratSpecificInfo.wcdma();
-                    wcdmaCi = convertHalCellIdentityWcdma(wcdma.cellIdentityWcdma);
-                    wcdmaSs = convertHalWcdmaSignalStrength(wcdma.signalStrengthWcdma);
-                    break;
-                case android.hardware.radio.V1_5.CellInfo
-                        .CellInfoRatSpecificInfo.hidl_discriminator.tdscdma:
-                    type = CellInfo.TYPE_TDSCDMA;
-                    android.hardware.radio.V1_5.CellInfoTdscdma tdscdma =
-                            record.ratSpecificInfo.tdscdma();
-                    tdscdmaCi = convertHalCellIdentityTdscdma(tdscdma.cellIdentityTdscdma);
-                    tdscdmaSs = convertHalTdscdmaSignalStrength(tdscdma.signalStrengthTdscdma);
-                    break;
-                case android.hardware.radio.V1_5.CellInfo
-                        .CellInfoRatSpecificInfo.hidl_discriminator.nr:
-                    type = CellInfo.TYPE_NR;
-                    android.hardware.radio.V1_5.CellInfoNr nr = record.ratSpecificInfo.nr();
-                    nrCi = convertHalCellIdentityNr(nr.cellIdentityNr);
-                    nrSs = convertHalNrSignalStrength(nr.signalStrengthNr);
-                    break;
-                default: return null;
-            }
-        } else if (cellInfo instanceof android.hardware.radio.V1_6.CellInfo) {
-            final android.hardware.radio.V1_6.CellInfo record =
-                    (android.hardware.radio.V1_6.CellInfo) cellInfo;
-            connectionStatus = record.connectionStatus;
-            registered = record.registered;
-            switch (record.ratSpecificInfo.getDiscriminator()) {
-                case android.hardware.radio.V1_6.CellInfo
-                        .CellInfoRatSpecificInfo.hidl_discriminator.gsm:
-                    type = CellInfo.TYPE_GSM;
-                    android.hardware.radio.V1_5.CellInfoGsm gsm = record.ratSpecificInfo.gsm();
-                    gsmCi = convertHalCellIdentityGsm(gsm.cellIdentityGsm);
-                    gsmSs = convertHalGsmSignalStrength(gsm.signalStrengthGsm);
-                    break;
-                case android.hardware.radio.V1_6.CellInfo
-                        .CellInfoRatSpecificInfo.hidl_discriminator.cdma:
-                    type = CellInfo.TYPE_CDMA;
-                    android.hardware.radio.V1_2.CellInfoCdma cdma = record.ratSpecificInfo.cdma();
-                    cdmaCi = convertHalCellIdentityCdma(cdma.cellIdentityCdma);
-                    cdmaSs = convertHalCdmaSignalStrength(
-                            cdma.signalStrengthCdma, cdma.signalStrengthEvdo);
-                    break;
-                case android.hardware.radio.V1_6.CellInfo
-                        .CellInfoRatSpecificInfo.hidl_discriminator.lte:
-                    type = CellInfo.TYPE_LTE;
-                    android.hardware.radio.V1_6.CellInfoLte lte = record.ratSpecificInfo.lte();
-                    lteCi = convertHalCellIdentityLte(lte.cellIdentityLte);
-                    lteSs = convertHalLteSignalStrength(lte.signalStrengthLte);
-                    lteCc = new CellConfigLte();
-                    break;
-                case android.hardware.radio.V1_6.CellInfo
-                        .CellInfoRatSpecificInfo.hidl_discriminator.wcdma:
-                    type = CellInfo.TYPE_WCDMA;
-                    android.hardware.radio.V1_5.CellInfoWcdma wcdma =
-                            record.ratSpecificInfo.wcdma();
-                    wcdmaCi = convertHalCellIdentityWcdma(wcdma.cellIdentityWcdma);
-                    wcdmaSs = convertHalWcdmaSignalStrength(wcdma.signalStrengthWcdma);
-                    break;
-                case android.hardware.radio.V1_6.CellInfo
-                        .CellInfoRatSpecificInfo.hidl_discriminator.tdscdma:
-                    type = CellInfo.TYPE_TDSCDMA;
-                    android.hardware.radio.V1_5.CellInfoTdscdma tdscdma =
-                            record.ratSpecificInfo.tdscdma();
-                    tdscdmaCi = convertHalCellIdentityTdscdma(tdscdma.cellIdentityTdscdma);
-                    tdscdmaSs = convertHalTdscdmaSignalStrength(tdscdma.signalStrengthTdscdma);
-                    break;
-                case android.hardware.radio.V1_6.CellInfo
-                        .CellInfoRatSpecificInfo.hidl_discriminator.nr:
-                    type = CellInfo.TYPE_NR;
-                    android.hardware.radio.V1_6.CellInfoNr nr = record.ratSpecificInfo.nr();
-                    nrCi = convertHalCellIdentityNr(nr.cellIdentityNr);
-                    nrSs = convertHalNrSignalStrength(nr.signalStrengthNr);
-                    break;
-                default: return null;
-            }
-        } else {
-            return null;
-        }
-
-        switch (type) {
-            case CellInfo.TYPE_GSM:
-                return new CellInfoGsm(connectionStatus, registered, nanotime, gsmCi, gsmSs);
-            case CellInfo.TYPE_CDMA:
-                return new CellInfoCdma(connectionStatus, registered, nanotime, cdmaCi, cdmaSs);
-            case CellInfo.TYPE_LTE:
-                return new CellInfoLte(connectionStatus, registered, nanotime, lteCi, lteSs, lteCc);
-            case CellInfo.TYPE_WCDMA:
-                return new CellInfoWcdma(connectionStatus, registered, nanotime, wcdmaCi, wcdmaSs);
-            case CellInfo.TYPE_TDSCDMA:
-                return new CellInfoTdscdma(connectionStatus, registered, nanotime, tdscdmaCi,
-                        tdscdmaSs);
-            case CellInfo.TYPE_NR:
-                return new CellInfoNr(connectionStatus, registered, nanotime, nrCi, nrSs);
-            case CellInfo.TYPE_UNKNOWN:
-            default:
-                return null;
-        }
-    }
-
-    /**
-     * Convert a CellInfo defined in CellInfo.aidl to CellInfo
-     * @param cellInfo CellInfo defined in CellInfo.aidl
-     * @param nanotime time the CellInfo was created
-     * @return The converted CellInfo
-     */
-    private static CellInfo convertHalCellInfo(android.hardware.radio.network.CellInfo cellInfo,
-            long nanotime) {
-        if (cellInfo == null) return null;
-        int connectionStatus = cellInfo.connectionStatus;
-        boolean registered = cellInfo.registered;
-        switch (cellInfo.ratSpecificInfo.getTag()) {
-            case android.hardware.radio.network.CellInfoRatSpecificInfo.gsm:
-                android.hardware.radio.network.CellInfoGsm gsm = cellInfo.ratSpecificInfo.getGsm();
-                return new CellInfoGsm(connectionStatus, registered, nanotime,
-                        convertHalCellIdentityGsm(gsm.cellIdentityGsm),
-                        convertHalGsmSignalStrength(gsm.signalStrengthGsm));
-            case android.hardware.radio.network.CellInfoRatSpecificInfo.cdma:
-                android.hardware.radio.network.CellInfoCdma cdma =
-                        cellInfo.ratSpecificInfo.getCdma();
-                return new CellInfoCdma(connectionStatus, registered, nanotime,
-                        convertHalCellIdentityCdma(cdma.cellIdentityCdma),
-                        convertHalCdmaSignalStrength(cdma.signalStrengthCdma,
-                                cdma.signalStrengthEvdo));
-            case android.hardware.radio.network.CellInfoRatSpecificInfo.lte:
-                android.hardware.radio.network.CellInfoLte lte = cellInfo.ratSpecificInfo.getLte();
-                return new CellInfoLte(connectionStatus, registered, nanotime,
-                        convertHalCellIdentityLte(lte.cellIdentityLte),
-                        convertHalLteSignalStrength(lte.signalStrengthLte), new CellConfigLte());
-            case android.hardware.radio.network.CellInfoRatSpecificInfo.wcdma:
-                android.hardware.radio.network.CellInfoWcdma wcdma =
-                        cellInfo.ratSpecificInfo.getWcdma();
-                return new CellInfoWcdma(connectionStatus, registered, nanotime,
-                        convertHalCellIdentityWcdma(wcdma.cellIdentityWcdma),
-                        convertHalWcdmaSignalStrength(wcdma.signalStrengthWcdma));
-            case android.hardware.radio.network.CellInfoRatSpecificInfo.tdscdma:
-                android.hardware.radio.network.CellInfoTdscdma tdscdma =
-                        cellInfo.ratSpecificInfo.getTdscdma();
-                return new CellInfoTdscdma(connectionStatus, registered, nanotime,
-                        convertHalCellIdentityTdscdma(tdscdma.cellIdentityTdscdma),
-                        convertHalTdscdmaSignalStrength(tdscdma.signalStrengthTdscdma));
-            case android.hardware.radio.network.CellInfoRatSpecificInfo.nr:
-                android.hardware.radio.network.CellInfoNr nr = cellInfo.ratSpecificInfo.getNr();
-                return new CellInfoNr(connectionStatus, registered, nanotime,
-                        convertHalCellIdentityNr(nr.cellIdentityNr),
-                        convertHalNrSignalStrength(nr.signalStrengthNr));
-            default:
-                return null;
-        }
-    }
-
-    /**
-     * Convert a CellIdentity defined in radio/1.0, 1.2, 1.5/types.hal to CellIdentity
-     * @param halCi CellIdentity defined in radio/1.0, 1.2, 1.5/types.hal
-     * @return The converted CellIdentity
-     */
-    public static CellIdentity convertHalCellIdentity(Object halCi) {
-        if (halCi == null) return null;
-        if (halCi instanceof android.hardware.radio.V1_0.CellIdentity) {
-            android.hardware.radio.V1_0.CellIdentity ci =
-                    (android.hardware.radio.V1_0.CellIdentity) halCi;
-            switch (ci.cellInfoType) {
-                case CellInfo.TYPE_GSM:
-                    if (ci.cellIdentityGsm.size() == 1) {
-                        return convertHalCellIdentityGsm(ci.cellIdentityGsm.get(0));
-                    }
-                    break;
-                case CellInfo.TYPE_CDMA:
-                    if (ci.cellIdentityCdma.size() == 1) {
-                        return convertHalCellIdentityCdma(ci.cellIdentityCdma.get(0));
-                    }
-                    break;
-                case CellInfo.TYPE_LTE:
-                    if (ci.cellIdentityLte.size() == 1) {
-                        return convertHalCellIdentityLte(ci.cellIdentityLte.get(0));
-                    }
-                    break;
-                case CellInfo.TYPE_WCDMA:
-                    if (ci.cellIdentityWcdma.size() == 1) {
-                        return convertHalCellIdentityWcdma(ci.cellIdentityWcdma.get(0));
-                    }
-                    break;
-                case CellInfo.TYPE_TDSCDMA:
-                    if (ci.cellIdentityTdscdma.size() == 1) {
-                        return convertHalCellIdentityTdscdma(ci.cellIdentityTdscdma.get(0));
-                    }
-                    break;
-            }
-        } else if (halCi instanceof android.hardware.radio.V1_2.CellIdentity) {
-            android.hardware.radio.V1_2.CellIdentity ci =
-                    (android.hardware.radio.V1_2.CellIdentity) halCi;
-            switch (ci.cellInfoType) {
-                case CellInfo.TYPE_GSM:
-                    if (ci.cellIdentityGsm.size() == 1) {
-                        return convertHalCellIdentityGsm(ci.cellIdentityGsm.get(0));
-                    }
-                    break;
-                case CellInfo.TYPE_CDMA:
-                    if (ci.cellIdentityCdma.size() == 1) {
-                        return convertHalCellIdentityCdma(ci.cellIdentityCdma.get(0));
-                    }
-                    break;
-                case CellInfo.TYPE_LTE:
-                    if (ci.cellIdentityLte.size() == 1) {
-                        return convertHalCellIdentityLte(ci.cellIdentityLte.get(0));
-                    }
-                    break;
-                case CellInfo.TYPE_WCDMA:
-                    if (ci.cellIdentityWcdma.size() == 1) {
-                        return convertHalCellIdentityWcdma(ci.cellIdentityWcdma.get(0));
-                    }
-                    break;
-                case CellInfo.TYPE_TDSCDMA:
-                    if (ci.cellIdentityTdscdma.size() == 1) {
-                        return convertHalCellIdentityTdscdma(ci.cellIdentityTdscdma.get(0));
-                    }
-                    break;
-            }
-        } else if (halCi instanceof android.hardware.radio.V1_5.CellIdentity) {
-            android.hardware.radio.V1_5.CellIdentity ci =
-                    (android.hardware.radio.V1_5.CellIdentity) halCi;
-            switch (ci.getDiscriminator()) {
-                case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.gsm:
-                    return convertHalCellIdentityGsm(ci.gsm());
-                case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.cdma:
-                    return convertHalCellIdentityCdma(ci.cdma());
-                case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.lte:
-                    return convertHalCellIdentityLte(ci.lte());
-                case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.wcdma:
-                    return convertHalCellIdentityWcdma(ci.wcdma());
-                case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.tdscdma:
-                    return convertHalCellIdentityTdscdma(ci.tdscdma());
-                case android.hardware.radio.V1_5.CellIdentity.hidl_discriminator.nr:
-                    return convertHalCellIdentityNr(ci.nr());
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Convert a CellIdentity defined in CellIdentity.aidl to CellInfo
-     * @param ci CellIdentity defined in CellIdentity.aidl
-     * @return The converted CellIdentity
-     */
-    public static CellIdentity convertHalCellIdentity(
-            android.hardware.radio.network.CellIdentity ci) {
-        if (ci == null) return null;
-        switch (ci.getTag()) {
-            case android.hardware.radio.network.CellIdentity.gsm:
-                return convertHalCellIdentityGsm(ci.getGsm());
-            case android.hardware.radio.network.CellIdentity.cdma:
-                return convertHalCellIdentityCdma(ci.getCdma());
-            case android.hardware.radio.network.CellIdentity.lte:
-                return convertHalCellIdentityLte(ci.getLte());
-            case android.hardware.radio.network.CellIdentity.wcdma:
-                return convertHalCellIdentityWcdma(ci.getWcdma());
-            case android.hardware.radio.network.CellIdentity.tdscdma:
-                return convertHalCellIdentityTdscdma(ci.getTdscdma());
-            case android.hardware.radio.network.CellIdentity.nr:
-                return convertHalCellIdentityNr(ci.getNr());
-            default: return null;
-        }
-    }
-
-    /**
-     * Convert a CellIdentityGsm defined in radio/1.0, 1.2, 1.5/types.hal to CellIdentityGsm
-     * @param gsm CellIdentityGsm defined in radio/1.0, 1.2, 1.5/types.hal
-     * @return The converted CellIdentityGsm
-     */
-    public static CellIdentityGsm convertHalCellIdentityGsm(Object gsm) {
-        if (gsm == null) return null;
-        if (gsm instanceof android.hardware.radio.V1_0.CellIdentityGsm) {
-            android.hardware.radio.V1_0.CellIdentityGsm ci =
-                    (android.hardware.radio.V1_0.CellIdentityGsm) gsm;
-            return new CellIdentityGsm(ci.lac, ci.cid, ci.arfcn,
-                    ci.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : ci.bsic, ci.mcc, ci.mnc, "", "",
-                    new ArraySet<>());
-        } else if (gsm instanceof android.hardware.radio.V1_2.CellIdentityGsm) {
-            android.hardware.radio.V1_2.CellIdentityGsm ci =
-                    (android.hardware.radio.V1_2.CellIdentityGsm) gsm;
-            return new CellIdentityGsm(ci.base.lac, ci.base.cid, ci.base.arfcn,
-                    ci.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : ci.base.bsic, ci.base.mcc,
-                    ci.base.mnc, ci.operatorNames.alphaLong, ci.operatorNames.alphaShort,
-                    new ArraySet<>());
-        } else if (gsm instanceof android.hardware.radio.V1_5.CellIdentityGsm) {
-            android.hardware.radio.V1_5.CellIdentityGsm ci =
-                    (android.hardware.radio.V1_5.CellIdentityGsm) gsm;
-            return new CellIdentityGsm(ci.base.base.lac, ci.base.base.cid, ci.base.base.arfcn,
-                    ci.base.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE
-                            : ci.base.base.bsic, ci.base.base.mcc, ci.base.base.mnc,
-                    ci.base.operatorNames.alphaLong, ci.base.operatorNames.alphaShort,
-                    ci.additionalPlmns);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Convert a CellIdentityGsm defined in CellIdentityGsm.aidl to CellIdentityGsm
-     * @param cid CellIdentityGsm defined in CellIdentityGsm.aidl
-     * @return The converted CellIdentityGsm
-     */
-    public static CellIdentityGsm convertHalCellIdentityGsm(
-            android.hardware.radio.network.CellIdentityGsm cid) {
-        return new CellIdentityGsm(cid.lac, cid.cid, cid.arfcn,
-                cid.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.bsic, cid.mcc, cid.mnc,
-                cid.operatorNames.alphaLong, cid.operatorNames.alphaShort, new ArraySet<>());
-    }
-
-    /**
-     * Convert a CellIdentityCdma defined in radio/1.0, 1.2/types.hal to CellIdentityCdma
-     * @param cdma CellIdentityCdma defined in radio/1.0, 1.2/types.hal
-     * @return The converted CellIdentityCdma
-     */
-    public static CellIdentityCdma convertHalCellIdentityCdma(Object cdma) {
-        if (cdma == null) return null;
-        if (cdma instanceof android.hardware.radio.V1_0.CellIdentityCdma) {
-            android.hardware.radio.V1_0.CellIdentityCdma ci =
-                    (android.hardware.radio.V1_0.CellIdentityCdma) cdma;
-            return new CellIdentityCdma(ci.networkId, ci.systemId, ci.baseStationId, ci.longitude,
-                    ci.latitude, "", "");
-        } else if (cdma instanceof android.hardware.radio.V1_2.CellIdentityCdma) {
-            android.hardware.radio.V1_2.CellIdentityCdma ci =
-                    (android.hardware.radio.V1_2.CellIdentityCdma) cdma;
-            return new CellIdentityCdma(ci.base.networkId, ci.base.systemId, ci.base.baseStationId,
-                    ci.base.longitude, ci.base.latitude, ci.operatorNames.alphaLong,
-                    ci.operatorNames.alphaShort);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Convert a CellIdentityCdma defined in CellIdentityCdma.aidl to CellIdentityCdma
-     * @param cid CellIdentityCdma defined in CelIdentityCdma.aidl
-     * @return The converted CellIdentityCdma
-     */
-    public static CellIdentityCdma convertHalCellIdentityCdma(
-            android.hardware.radio.network.CellIdentityCdma cid) {
-        return new CellIdentityCdma(cid.networkId, cid.systemId, cid.baseStationId, cid.longitude,
-                cid.latitude, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort);
-    }
-
-    /**
-     * Convert a CellIdentityLte defined in radio/1.0, 1.2, 1.5/types.hal to CellIdentityLte
-     * @param lte CellIdentityLte defined in radio/1.0, 1.2, 1.5/types.hal
-     * @return The converted CellIdentityLte
-     */
-    public static CellIdentityLte convertHalCellIdentityLte(Object lte) {
-        if (lte == null) return null;
-        if (lte instanceof android.hardware.radio.V1_0.CellIdentityLte) {
-            android.hardware.radio.V1_0.CellIdentityLte ci =
-                    (android.hardware.radio.V1_0.CellIdentityLte) lte;
-            return new CellIdentityLte(ci.ci, ci.pci, ci.tac, ci.earfcn, new int[] {},
-                    CellInfo.UNAVAILABLE, ci.mcc, ci.mnc, "", "", new ArraySet<>(), null);
-        } else if (lte instanceof android.hardware.radio.V1_2.CellIdentityLte) {
-            android.hardware.radio.V1_2.CellIdentityLte ci =
-                    (android.hardware.radio.V1_2.CellIdentityLte) lte;
-            return new CellIdentityLte(ci.base.ci, ci.base.pci, ci.base.tac, ci.base.earfcn,
-                    new int[] {}, ci.bandwidth, ci.base.mcc, ci.base.mnc,
-                    ci.operatorNames.alphaLong, ci.operatorNames.alphaShort, new ArraySet<>(),
-                    null);
-        } else if (lte instanceof android.hardware.radio.V1_5.CellIdentityLte) {
-            android.hardware.radio.V1_5.CellIdentityLte ci =
-                    (android.hardware.radio.V1_5.CellIdentityLte) lte;
-            return new CellIdentityLte(ci.base.base.ci, ci.base.base.pci, ci.base.base.tac,
-                    ci.base.base.earfcn, ci.bands.stream().mapToInt(Integer::intValue).toArray(),
-                    ci.base.bandwidth, ci.base.base.mcc, ci.base.base.mnc,
-                    ci.base.operatorNames.alphaLong, ci.base.operatorNames.alphaShort,
-                    ci.additionalPlmns, convertHalClosedSubscriberGroupInfo(ci.optionalCsgInfo));
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Convert a CellIdentityLte defined in CellIdentityLte.aidl to CellIdentityLte
-     * @param cid CellIdentityLte defined in CellIdentityLte.aidl
-     * @return The converted CellIdentityLte
-     */
-    public static CellIdentityLte convertHalCellIdentityLte(
-            android.hardware.radio.network.CellIdentityLte cid) {
-        return new CellIdentityLte(cid.ci, cid.pci, cid.tac, cid.earfcn, cid.bands, cid.bandwidth,
-                cid.mcc, cid.mnc, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
-                primitiveArrayToArrayList(cid.additionalPlmns),
-                convertHalClosedSubscriberGroupInfo(cid.csgInfo));
-    }
-
-    /**
-     * Convert a CellIdentityWcdma defined in radio/1.0, 1.2, 1.5/types.hal to CellIdentityWcdma
-     * @param wcdma CellIdentityWcdma defined in radio/1.0, 1.2, 1.5/types.hal
-     * @return The converted CellIdentityWcdma
-     */
-    public static CellIdentityWcdma convertHalCellIdentityWcdma(Object wcdma) {
-        if (wcdma == null) return null;
-        if (wcdma instanceof android.hardware.radio.V1_0.CellIdentityWcdma) {
-            android.hardware.radio.V1_0.CellIdentityWcdma ci =
-                    (android.hardware.radio.V1_0.CellIdentityWcdma) wcdma;
-            return new CellIdentityWcdma(ci.lac, ci.cid, ci.psc, ci.uarfcn, ci.mcc, ci.mnc, "", "",
-                    new ArraySet<>(), null);
-        } else if (wcdma instanceof android.hardware.radio.V1_2.CellIdentityWcdma) {
-            android.hardware.radio.V1_2.CellIdentityWcdma ci =
-                    (android.hardware.radio.V1_2.CellIdentityWcdma) wcdma;
-            return new CellIdentityWcdma(ci.base.lac, ci.base.cid, ci.base.psc, ci.base.uarfcn,
-                    ci.base.mcc, ci.base.mnc, ci.operatorNames.alphaLong,
-                    ci.operatorNames.alphaShort, new ArraySet<>(), null);
-        } else if (wcdma instanceof android.hardware.radio.V1_5.CellIdentityWcdma) {
-            android.hardware.radio.V1_5.CellIdentityWcdma ci =
-                    (android.hardware.radio.V1_5.CellIdentityWcdma) wcdma;
-            return new CellIdentityWcdma(ci.base.base.lac, ci.base.base.cid, ci.base.base.psc,
-                    ci.base.base.uarfcn, ci.base.base.mcc, ci.base.base.mnc,
-                    ci.base.operatorNames.alphaLong, ci.base.operatorNames.alphaShort,
-                    ci.additionalPlmns, convertHalClosedSubscriberGroupInfo(ci.optionalCsgInfo));
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Convert a CellIdentityWcdma defined in CellIdentityWcdma.aidl to CellIdentityWcdma
-     * @param cid CellIdentityWcdma defined in CellIdentityWcdma.aidl
-     * @return The converted CellIdentityWcdma
-     */
-    public static CellIdentityWcdma convertHalCellIdentityWcdma(
-            android.hardware.radio.network.CellIdentityWcdma cid) {
-        return new CellIdentityWcdma(cid.lac, cid.cid, cid.psc, cid.uarfcn, cid.mcc, cid.mnc,
-                cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
-                primitiveArrayToArrayList(cid.additionalPlmns),
-                convertHalClosedSubscriberGroupInfo(cid.csgInfo));
-    }
-
-    /**
-     * Convert a CellIdentityTdscdma defined in radio/1.0, 1.2, 1.5/types.hal to CellIdentityTdscdma
-     * @param tdscdma CellIdentityTdscdma defined in radio/1.0, 1.2, 1.5/types.hal
-     * @return The converted CellIdentityTdscdma
-     */
-    public static CellIdentityTdscdma convertHalCellIdentityTdscdma(Object tdscdma) {
-        if (tdscdma == null) return null;
-        if (tdscdma instanceof android.hardware.radio.V1_0.CellIdentityTdscdma) {
-            android.hardware.radio.V1_0.CellIdentityTdscdma ci =
-                    (android.hardware.radio.V1_0.CellIdentityTdscdma) tdscdma;
-            return new CellIdentityTdscdma(ci.mcc, ci.mnc, ci.lac, ci.cid, ci.cpid,
-                    CellInfo.UNAVAILABLE, "", "", Collections.emptyList(), null);
-        } else if (tdscdma instanceof android.hardware.radio.V1_2.CellIdentityTdscdma) {
-            android.hardware.radio.V1_2.CellIdentityTdscdma ci =
-                    (android.hardware.radio.V1_2.CellIdentityTdscdma) tdscdma;
-            return new CellIdentityTdscdma(ci.base.mcc, ci.base.mnc, ci.base.lac, ci.base.cid,
-                    ci.base.cpid, ci.uarfcn, ci.operatorNames.alphaLong,
-                    ci.operatorNames.alphaShort, Collections.emptyList(), null);
-        } else if (tdscdma instanceof android.hardware.radio.V1_5.CellIdentityTdscdma) {
-            android.hardware.radio.V1_5.CellIdentityTdscdma ci =
-                    (android.hardware.radio.V1_5.CellIdentityTdscdma) tdscdma;
-            return new CellIdentityTdscdma(ci.base.base.mcc, ci.base.base.mnc, ci.base.base.lac,
-                    ci.base.base.cid, ci.base.base.cpid, ci.base.uarfcn,
-                    ci.base.operatorNames.alphaLong, ci.base.operatorNames.alphaShort,
-                    ci.additionalPlmns, convertHalClosedSubscriberGroupInfo(ci.optionalCsgInfo));
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Convert a CellIdentityTdscdma defined in CellIdentityTdscdma.aidl to CellIdentityTdscdma
-     * @param cid CellIdentityTdscdma defined in radio/1.0, 1.2, 1.5/types.hal
-     * @return The converted CellIdentityTdscdma
-     */
-    public static CellIdentityTdscdma convertHalCellIdentityTdscdma(
-            android.hardware.radio.network.CellIdentityTdscdma cid) {
-        return new CellIdentityTdscdma(cid.mcc, cid.mnc, cid.lac, cid.cid, cid.cpid, cid.uarfcn,
-                cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
-                primitiveArrayToArrayList(cid.additionalPlmns),
-                convertHalClosedSubscriberGroupInfo(cid.csgInfo));
-    }
-
-    /**
-     * Convert a CellIdentityNr defined in radio/1.4, 1.5/types.hal to CellIdentityNr
-     * @param nr CellIdentityNr defined in radio/1.4 1.5/types.hal
-     * @return The converted CellIdentityNr
-     */
-    public static CellIdentityNr convertHalCellIdentityNr(Object nr) {
-        if (nr == null) return null;
-        if (nr instanceof android.hardware.radio.V1_4.CellIdentityNr) {
-            android.hardware.radio.V1_4.CellIdentityNr ci =
-                    (android.hardware.radio.V1_4.CellIdentityNr) nr;
-            return new CellIdentityNr(ci.pci, ci.tac, ci.nrarfcn, new int[] {}, ci.mcc, ci.mnc,
-                    ci.nci, ci.operatorNames.alphaLong, ci.operatorNames.alphaShort,
-                    new ArraySet<>());
-        } else if (nr instanceof android.hardware.radio.V1_5.CellIdentityNr) {
-            android.hardware.radio.V1_5.CellIdentityNr ci =
-                    (android.hardware.radio.V1_5.CellIdentityNr) nr;
-            return new CellIdentityNr(ci.base.pci, ci.base.tac, ci.base.nrarfcn,
-                    ci.bands.stream().mapToInt(Integer::intValue).toArray(), ci.base.mcc,
-                    ci.base.mnc, ci.base.nci, ci.base.operatorNames.alphaLong,
-                    ci.base.operatorNames.alphaShort, ci.additionalPlmns);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Convert a CellIdentityNr defined in CellIdentityNr.aidl to CellIdentityNr
-     * @param cid CellIdentityNr defined in CellIdentityNr.aidl
-     * @return The converted CellIdentityNr
-     */
-    public static CellIdentityNr convertHalCellIdentityNr(
-            android.hardware.radio.network.CellIdentityNr cid) {
-        return new CellIdentityNr(cid.pci, cid.tac, cid.nrarfcn, cid.bands, cid.mcc, cid.mnc,
-                cid.nci, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort,
-                primitiveArrayToArrayList(cid.additionalPlmns));
-    }
-
-    /**
-     * Convert a SignalStrength defined in radio/1.0, 1.2, 1.4, 1.6/types.hal to SignalStrength
-     * @param ss SignalStrength defined in radio/1.0, 1.2, 1.4, 1.6/types.hal
-     * @return The converted SignalStrength
-     */
-    public static SignalStrength convertHalSignalStrength(Object ss) {
-        if (ss == null) return null;
-        if (ss instanceof android.hardware.radio.V1_0.SignalStrength) {
-            android.hardware.radio.V1_0.SignalStrength signalStrength =
-                    (android.hardware.radio.V1_0.SignalStrength) ss;
-            return new SignalStrength(
-                    convertHalCdmaSignalStrength(signalStrength.cdma, signalStrength.evdo),
-                    convertHalGsmSignalStrength(signalStrength.gw), new CellSignalStrengthWcdma(),
-                    convertHalTdscdmaSignalStrength(signalStrength.tdScdma),
-                    convertHalLteSignalStrength(signalStrength.lte),
-                    new CellSignalStrengthNr());
-        } else if (ss instanceof android.hardware.radio.V1_2.SignalStrength) {
-            android.hardware.radio.V1_2.SignalStrength signalStrength =
-                    (android.hardware.radio.V1_2.SignalStrength) ss;
-            return new SignalStrength(
-                    convertHalCdmaSignalStrength(signalStrength.cdma, signalStrength.evdo),
-                    convertHalGsmSignalStrength(signalStrength.gsm),
-                    convertHalWcdmaSignalStrength(signalStrength.wcdma),
-                    convertHalTdscdmaSignalStrength(signalStrength.tdScdma),
-                    convertHalLteSignalStrength(signalStrength.lte), new CellSignalStrengthNr());
-        } else if (ss instanceof android.hardware.radio.V1_4.SignalStrength) {
-            android.hardware.radio.V1_4.SignalStrength signalStrength =
-                    (android.hardware.radio.V1_4.SignalStrength) ss;
-            return new SignalStrength(
-                    convertHalCdmaSignalStrength(signalStrength.cdma, signalStrength.evdo),
-                    convertHalGsmSignalStrength(signalStrength.gsm),
-                    convertHalWcdmaSignalStrength(signalStrength.wcdma),
-                    convertHalTdscdmaSignalStrength(signalStrength.tdscdma),
-                    convertHalLteSignalStrength(signalStrength.lte),
-                    convertHalNrSignalStrength(signalStrength.nr));
-        } else if (ss instanceof android.hardware.radio.V1_6.SignalStrength) {
-            android.hardware.radio.V1_6.SignalStrength signalStrength =
-                    (android.hardware.radio.V1_6.SignalStrength) ss;
-            return new SignalStrength(
-                    convertHalCdmaSignalStrength(signalStrength.cdma, signalStrength.evdo),
-                    convertHalGsmSignalStrength(signalStrength.gsm),
-                    convertHalWcdmaSignalStrength(signalStrength.wcdma),
-                    convertHalTdscdmaSignalStrength(signalStrength.tdscdma),
-                    convertHalLteSignalStrength(signalStrength.lte),
-                    convertHalNrSignalStrength(signalStrength.nr));
-        }
-        return null;
-    }
-
-    /**
-     * Convert a SignalStrength defined in SignalStrength.aidl to SignalStrength
-     * @param signalStrength SignalStrength defined in SignalStrength.aidl
-     * @return The converted SignalStrength
-     */
-    public static SignalStrength convertHalSignalStrength(
-            android.hardware.radio.network.SignalStrength signalStrength) {
-        return new SignalStrength(
-                convertHalCdmaSignalStrength(signalStrength.cdma, signalStrength.evdo),
-                convertHalGsmSignalStrength(signalStrength.gsm),
-                convertHalWcdmaSignalStrength(signalStrength.wcdma),
-                convertHalTdscdmaSignalStrength(signalStrength.tdscdma),
-                convertHalLteSignalStrength(signalStrength.lte),
-                convertHalNrSignalStrength(signalStrength.nr));
-    }
-
-    /**
-     * Convert a GsmSignalStrength defined in radio/1.0/types.hal to CellSignalStrengthGsm
-     * @param ss GsmSignalStrength defined in radio/1.0/types.hal
-     * @return The converted CellSignalStrengthGsm
-     */
-    public static CellSignalStrengthGsm convertHalGsmSignalStrength(
-            android.hardware.radio.V1_0.GsmSignalStrength ss) {
-        CellSignalStrengthGsm ret = new CellSignalStrengthGsm(
-                CellSignalStrength.getRssiDbmFromAsu(ss.signalStrength), ss.bitErrorRate,
-                ss.timingAdvance);
-        if (ret.getRssi() == CellInfo.UNAVAILABLE) {
-            ret.setDefaultValues();
-            ret.updateLevel(null, null);
-        }
-        return ret;
-    }
-
-    /**
-     * Convert a GsmSignalStrength defined in GsmSignalStrength.aidl to CellSignalStrengthGsm
-     * @param ss GsmSignalStrength defined in GsmSignalStrength.aidl
-     * @return The converted CellSignalStrengthGsm
-     */
-    public static CellSignalStrengthGsm convertHalGsmSignalStrength(
-            android.hardware.radio.network.GsmSignalStrength ss) {
-        CellSignalStrengthGsm ret = new CellSignalStrengthGsm(
-                CellSignalStrength.getRssiDbmFromAsu(ss.signalStrength), ss.bitErrorRate,
-                ss.timingAdvance);
-        if (ret.getRssi() == CellInfo.UNAVAILABLE) {
-            ret.setDefaultValues();
-            ret.updateLevel(null, null);
-        }
-        return ret;
-    }
-
-    /**
-     * Convert a CdmaSignalStrength and EvdoSignalStrength defined in radio/1.0/types.hal to
-     * CellSignalStrengthCdma
-     * @param cdma CdmaSignalStrength defined in radio/1.0/types.hal
-     * @param evdo EvdoSignalStrength defined in radio/1.0/types.hal
-     * @return The converted CellSignalStrengthCdma
-     */
-    public static CellSignalStrengthCdma convertHalCdmaSignalStrength(
-            android.hardware.radio.V1_0.CdmaSignalStrength cdma,
-            android.hardware.radio.V1_0.EvdoSignalStrength evdo) {
-        return new CellSignalStrengthCdma(-cdma.dbm, -cdma.ecio, -evdo.dbm, -evdo.ecio,
-                evdo.signalNoiseRatio);
-    }
-
-    /**
-     * Convert a CdmaSignalStrength and EvdoSignalStrength defined in radio/network to
-     * CellSignalStrengthCdma
-     * @param cdma CdmaSignalStrength defined in CdmaSignalStrength.aidl
-     * @param evdo EvdoSignalStrength defined in EvdoSignalStrength.aidl
-     * @return The converted CellSignalStrengthCdma
-     */
-    public static CellSignalStrengthCdma convertHalCdmaSignalStrength(
-            android.hardware.radio.network.CdmaSignalStrength cdma,
-            android.hardware.radio.network.EvdoSignalStrength evdo) {
-        return new CellSignalStrengthCdma(-cdma.dbm, -cdma.ecio, -evdo.dbm, -evdo.ecio,
-                evdo.signalNoiseRatio);
-    }
-
-    /**
-     * Convert a LteSignalStrength defined in radio/1.0, 1.6/types.hal to CellSignalStrengthLte
-     * @param lte LteSignalStrength defined in radio/1.0, 1.6/types.hal
-     * @return The converted CellSignalStrengthLte
-     */
-    public static CellSignalStrengthLte convertHalLteSignalStrength(Object lte) {
-        if (lte == null) return null;
-        if (lte instanceof android.hardware.radio.V1_0.LteSignalStrength) {
-            android.hardware.radio.V1_0.LteSignalStrength ss =
-                    (android.hardware.radio.V1_0.LteSignalStrength) lte;
-            return new CellSignalStrengthLte(
-                    CellSignalStrengthLte.convertRssiAsuToDBm(ss.signalStrength),
-                    ss.rsrp != CellInfo.UNAVAILABLE ? -ss.rsrp : ss.rsrp,
-                    ss.rsrq != CellInfo.UNAVAILABLE ? -ss.rsrq : ss.rsrq,
-                    CellSignalStrengthLte.convertRssnrUnitFromTenDbToDB(ss.rssnr), ss.cqi,
-                    ss.timingAdvance);
-        } else if (lte instanceof android.hardware.radio.V1_6.LteSignalStrength) {
-            android.hardware.radio.V1_6.LteSignalStrength ss =
-                    (android.hardware.radio.V1_6.LteSignalStrength) lte;
-            return new CellSignalStrengthLte(
-                    CellSignalStrengthLte.convertRssiAsuToDBm(ss.base.signalStrength),
-                    ss.base.rsrp != CellInfo.UNAVAILABLE ? -ss.base.rsrp : ss.base.rsrp,
-                    ss.base.rsrq != CellInfo.UNAVAILABLE ? -ss.base.rsrq : ss.base.rsrq,
-                    CellSignalStrengthLte.convertRssnrUnitFromTenDbToDB(ss.base.rssnr),
-                    ss.cqiTableIndex, ss.base.cqi, ss.base.timingAdvance);
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Convert a LteSignalStrength defined in LteSignalStrength.aidl to CellSignalStrengthLte
-     * @param ss LteSignalStrength defined in LteSignalStrength.aidl
-     * @return The converted CellSignalStrengthLte
-     */
-    public static CellSignalStrengthLte convertHalLteSignalStrength(
-            android.hardware.radio.network.LteSignalStrength ss) {
-        return new CellSignalStrengthLte(
-                CellSignalStrengthLte.convertRssiAsuToDBm(ss.signalStrength),
-                ss.rsrp != CellInfo.UNAVAILABLE ? -ss.rsrp : ss.rsrp,
-                ss.rsrq != CellInfo.UNAVAILABLE ? -ss.rsrq : ss.rsrq,
-                CellSignalStrengthLte.convertRssnrUnitFromTenDbToDB(ss.rssnr), ss.cqiTableIndex,
-                ss.cqi, ss.timingAdvance);
-    }
-
-    /**
-     * Convert a WcdmaSignalStrength defined in radio/1.0, 1.2/types.hal to CellSignalStrengthWcdma
-     * @param wcdma WcdmaSignalStrength defined in radio/1.0, 1.2/types.hal
-     * @return The converted CellSignalStrengthWcdma
-     */
-    public static CellSignalStrengthWcdma convertHalWcdmaSignalStrength(Object wcdma) {
-        if (wcdma == null) return null;
-        CellSignalStrengthWcdma ret = null;
-        if (wcdma instanceof android.hardware.radio.V1_0.WcdmaSignalStrength) {
-            android.hardware.radio.V1_0.WcdmaSignalStrength ss =
-                    (android.hardware.radio.V1_0.WcdmaSignalStrength) wcdma;
-            ret = new CellSignalStrengthWcdma(
-                    CellSignalStrength.getRssiDbmFromAsu(ss.signalStrength), ss.bitErrorRate,
-                    CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE);
-        } else if (wcdma instanceof android.hardware.radio.V1_2.WcdmaSignalStrength) {
-            android.hardware.radio.V1_2.WcdmaSignalStrength ss =
-                    (android.hardware.radio.V1_2.WcdmaSignalStrength) wcdma;
-            ret = new CellSignalStrengthWcdma(
-                    CellSignalStrength.getRssiDbmFromAsu(ss.base.signalStrength),
-                    ss.base.bitErrorRate, CellSignalStrength.getRscpDbmFromAsu(ss.rscp),
-                    CellSignalStrength.getEcNoDbFromAsu(ss.ecno));
-        }
-        if (ret != null && ret.getRssi() == CellInfo.UNAVAILABLE
-                && ret.getRscp() == CellInfo.UNAVAILABLE) {
-            ret.setDefaultValues();
-            ret.updateLevel(null, null);
-        }
-        return ret;
-    }
-
-    /**
-     * Convert a WcdmaSignalStrength defined in WcdmaSignalStrength.aidl to CellSignalStrengthWcdma
-     * @param ss WcdmaSignalStrength defined in WcdmaSignalStrength.aidl
-     * @return The converted CellSignalStrengthWcdma
-     */
-    public static CellSignalStrengthWcdma convertHalWcdmaSignalStrength(
-            android.hardware.radio.network.WcdmaSignalStrength ss) {
-        CellSignalStrengthWcdma ret = new CellSignalStrengthWcdma(
-                CellSignalStrength.getRssiDbmFromAsu(ss.signalStrength),
-                ss.bitErrorRate, CellSignalStrength.getRscpDbmFromAsu(ss.rscp),
-                CellSignalStrength.getEcNoDbFromAsu(ss.ecno));
-        if (ret.getRssi() == CellInfo.UNAVAILABLE && ret.getRscp() == CellInfo.UNAVAILABLE) {
-            ret.setDefaultValues();
-            ret.updateLevel(null, null);
-        }
-        return ret;
-    }
-
-    /**
-     * Convert a TdScdmaSignalStrength defined in radio/1.0/types.hal or TdscdmaSignalStrength
-     * defined in radio/1.2/types.hal to CellSignalStrengthTdscdma
-     * @param tdscdma TdScdmaSignalStrength defined in radio/1.0/types.hal or TdscdmaSignalStrength
-     *        defined in radio/1.2/types.hal
-     * @return The converted CellSignalStrengthTdscdma
-     */
-    public static CellSignalStrengthTdscdma convertHalTdscdmaSignalStrength(Object tdscdma) {
-        if (tdscdma == null) return null;
-        CellSignalStrengthTdscdma ret = null;
-        if (tdscdma instanceof android.hardware.radio.V1_0.TdScdmaSignalStrength) {
-            android.hardware.radio.V1_0.TdScdmaSignalStrength ss =
-                    (android.hardware.radio.V1_0.TdScdmaSignalStrength) tdscdma;
-            ret = new CellSignalStrengthTdscdma(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
-                    ss.rscp != CellInfo.UNAVAILABLE ? -ss.rscp : ss.rscp);
-        } else if (tdscdma instanceof android.hardware.radio.V1_2.TdscdmaSignalStrength) {
-            android.hardware.radio.V1_2.TdscdmaSignalStrength ss =
-                    (android.hardware.radio.V1_2.TdscdmaSignalStrength) tdscdma;
-            ret = new CellSignalStrengthTdscdma(
-                    CellSignalStrength.getRssiDbmFromAsu(ss.signalStrength), ss.bitErrorRate,
-                    CellSignalStrength.getRscpDbmFromAsu(ss.rscp));
-        }
-        if (ret != null && ret.getRssi() == CellInfo.UNAVAILABLE
-                && ret.getRscp() == CellInfo.UNAVAILABLE) {
-            ret.setDefaultValues();
-            ret.updateLevel(null, null);
-        }
-        return ret;
-    }
-
-    /**
-     * Convert a TdscdmaSignalStrength defined in TdscdmaSignalStrength.aidl to
-     * CellSignalStrengthTdscdma
-     * @param ss TdscdmaSignalStrength defined in TdscdmaSignalStrength.aidl
-     * @return The converted CellSignalStrengthTdscdma
-     */
-    public static CellSignalStrengthTdscdma convertHalTdscdmaSignalStrength(
-            android.hardware.radio.network.TdscdmaSignalStrength ss) {
-        CellSignalStrengthTdscdma ret = new CellSignalStrengthTdscdma(
-                CellSignalStrength.getRssiDbmFromAsu(ss.signalStrength),
-                ss.bitErrorRate, CellSignalStrength.getRscpDbmFromAsu(ss.rscp));
-        if (ret.getRssi() == CellInfo.UNAVAILABLE && ret.getRscp() == CellInfo.UNAVAILABLE) {
-            ret.setDefaultValues();
-            ret.updateLevel(null, null);
-        }
-        return ret;
-    }
-
-    /**
-     * Convert a NrSignalStrength defined in radio/1.4, 1.6/types.hal to CellSignalStrengthNr
-     * @param nr NrSignalStrength defined in radio/1.4, 1.6/types.hal
-     * @return The converted CellSignalStrengthNr
-     */
-    public static CellSignalStrengthNr convertHalNrSignalStrength(Object nr) {
-        if (nr == null) return null;
-        if (nr instanceof android.hardware.radio.V1_4.NrSignalStrength) {
-            android.hardware.radio.V1_4.NrSignalStrength ss =
-                    (android.hardware.radio.V1_4.NrSignalStrength) nr;
-            return new CellSignalStrengthNr(CellSignalStrengthNr.flip(ss.csiRsrp),
-                    CellSignalStrengthNr.flip(ss.csiRsrq), ss.csiSinr,
-                    CellSignalStrengthNr.flip(ss.ssRsrp), CellSignalStrengthNr.flip(ss.ssRsrq),
-                    ss.ssSinr);
-        } else if (nr instanceof android.hardware.radio.V1_6.NrSignalStrength) {
-            android.hardware.radio.V1_6.NrSignalStrength ss =
-                    (android.hardware.radio.V1_6.NrSignalStrength) nr;
-            return new CellSignalStrengthNr(CellSignalStrengthNr.flip(ss.base.csiRsrp),
-                    CellSignalStrengthNr.flip(ss.base.csiRsrq), ss.base.csiSinr,
-                    ss.csiCqiTableIndex, ss.csiCqiReport, CellSignalStrengthNr.flip(ss.base.ssRsrp),
-                    CellSignalStrengthNr.flip(ss.base.ssRsrq), ss.base.ssSinr);
-        }
-        return null;
-    }
-
-    /**
-     * Convert a NrSignalStrength defined in NrSignalStrength.aidl to CellSignalStrengthNr
-     * @param ss NrSignalStrength defined in NrSignalStrength.aidl
-     * @return The converted CellSignalStrengthNr
-     */
-    public static CellSignalStrengthNr convertHalNrSignalStrength(
-            android.hardware.radio.network.NrSignalStrength ss) {
-        return new CellSignalStrengthNr(CellSignalStrengthNr.flip(ss.csiRsrp),
-                CellSignalStrengthNr.flip(ss.csiRsrq), ss.csiSinr, ss.csiCqiTableIndex,
-                primitiveArrayToArrayList(ss.csiCqiReport), CellSignalStrengthNr.flip(ss.ssRsrp),
-                CellSignalStrengthNr.flip(ss.ssRsrq), ss.ssSinr);
-    }
-
-    private static ClosedSubscriberGroupInfo convertHalClosedSubscriberGroupInfo(
-            android.hardware.radio.V1_5.OptionalCsgInfo optionalCsgInfo) {
-        android.hardware.radio.V1_5.ClosedSubscriberGroupInfo csgInfo =
-                optionalCsgInfo.getDiscriminator()
-                        == android.hardware.radio.V1_5.OptionalCsgInfo.hidl_discriminator.csgInfo
-                        ? optionalCsgInfo.csgInfo() : null;
-        if (csgInfo == null) return null;
-        return new ClosedSubscriberGroupInfo(csgInfo.csgIndication, csgInfo.homeNodebName,
-                csgInfo.csgIdentity);
-    }
-
-    private static ClosedSubscriberGroupInfo convertHalClosedSubscriberGroupInfo(
-            android.hardware.radio.network.ClosedSubscriberGroupInfo csgInfo) {
-        if (csgInfo == null) return null;
-        return new ClosedSubscriberGroupInfo(csgInfo.csgIndication, csgInfo.homeNodebName,
-                csgInfo.csgIdentity);
-    }
-
-    /**
-     * Convert a list of BarringInfo defined in radio/1.5/types.hal to a sparse array of
-     * BarringServiceInfos
-     * @param halBarringInfos List of BarringInfos defined in radio/1.5/types.hal
-     * @return The converted sparse array of BarringServiceInfos
-     */
-    public static SparseArray<BarringInfo.BarringServiceInfo> convertHalBarringInfoList(
-            List<android.hardware.radio.V1_5.BarringInfo> halBarringInfos) {
-        SparseArray<BarringInfo.BarringServiceInfo> serviceInfos = new SparseArray<>();
-        for (android.hardware.radio.V1_5.BarringInfo halBarringInfo : halBarringInfos) {
-            if (halBarringInfo.barringType
-                    == android.hardware.radio.V1_5.BarringInfo.BarringType.CONDITIONAL) {
-                if (halBarringInfo.barringTypeSpecificInfo.getDiscriminator()
-                        != android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo
-                        .hidl_discriminator.conditional) {
-                    // this is an error case where the barring info is conditional but the
-                    // conditional barring fields weren't included
-                    continue;
-                }
-                android.hardware.radio.V1_5.BarringInfo.BarringTypeSpecificInfo
-                        .Conditional conditionalInfo =
-                        halBarringInfo.barringTypeSpecificInfo.conditional();
-                serviceInfos.put(
-                        halBarringInfo.serviceType, new BarringInfo.BarringServiceInfo(
-                                halBarringInfo.barringType, // will always be CONDITIONAL here
-                                conditionalInfo.isBarred,
-                                conditionalInfo.factor,
-                                conditionalInfo.timeSeconds));
-            } else {
-                // Barring type is either NONE or UNCONDITIONAL
-                serviceInfos.put(
-                        halBarringInfo.serviceType, new BarringInfo.BarringServiceInfo(
-                                halBarringInfo.barringType, false, 0, 0));
-            }
-        }
-        return serviceInfos;
-    }
-
-    /**
-     * Convert a list of BarringInfo defined in BarringInfo.aidl to a sparse array of
-     * BarringServiceInfos
-     * @param halBarringInfos List of BarringInfos defined in BarringInfo.aidl
-     * @return The converted sparse array of BarringServiceInfos
-     */
-    public static SparseArray<BarringInfo.BarringServiceInfo> convertHalBarringInfoList(
-            android.hardware.radio.network.BarringInfo[] halBarringInfos) {
-        SparseArray<BarringInfo.BarringServiceInfo> serviceInfos = new SparseArray<>();
-        for (android.hardware.radio.network.BarringInfo halBarringInfo : halBarringInfos) {
-            if (halBarringInfo.barringType
-                    == android.hardware.radio.network.BarringInfo.BARRING_TYPE_CONDITIONAL) {
-                if (halBarringInfo.barringTypeSpecificInfo == null) {
-                    // this is an error case where the barring info is conditional but the
-                    // conditional barring fields weren't included
-                    continue;
-                }
-                serviceInfos.put(
-                        halBarringInfo.serviceType, new BarringInfo.BarringServiceInfo(
-                                halBarringInfo.barringType, // will always be CONDITIONAL here
-                                halBarringInfo.barringTypeSpecificInfo.isBarred,
-                                halBarringInfo.barringTypeSpecificInfo.factor,
-                                halBarringInfo.barringTypeSpecificInfo.timeSeconds));
-            } else {
-                // Barring type is either NONE or UNCONDITIONAL
-                serviceInfos.put(halBarringInfo.serviceType, new BarringInfo.BarringServiceInfo(
-                        halBarringInfo.barringType, false, 0, 0));
-            }
-        }
-        return serviceInfos;
-    }
-
-    private static LinkAddress convertToLinkAddress(String addressString) {
-        return convertToLinkAddress(addressString, 0, LinkAddress.LIFETIME_UNKNOWN,
-                LinkAddress.LIFETIME_UNKNOWN);
-    }
-
-    private static LinkAddress convertToLinkAddress(String addressString, int properties,
-            long deprecationTime, long expirationTime) {
-        addressString = addressString.trim();
-        InetAddress address = null;
-        int prefixLength = -1;
-        try {
-            String[] pieces = addressString.split("/", 2);
-            address = InetAddresses.parseNumericAddress(pieces[0]);
-            if (pieces.length == 1) {
-                prefixLength = (address instanceof Inet4Address) ? 32 : 128;
-            } else if (pieces.length == 2) {
-                prefixLength = Integer.parseInt(pieces[1]);
-            }
-        } catch (NullPointerException e) {            // Null string.
-        } catch (ArrayIndexOutOfBoundsException e) {  // No prefix length.
-        } catch (NumberFormatException e) {           // Non-numeric prefix.
-        } catch (IllegalArgumentException e) {        // Invalid IP address.
-        }
-
-        if (address == null || prefixLength == -1) {
-            throw new IllegalArgumentException("Invalid link address " + addressString);
-        }
-
-        return new LinkAddress(address, prefixLength, properties, 0, deprecationTime,
-                expirationTime);
-    }
-
-    /**
-     * Convert SetupDataCallResult defined in radio/1.0, 1.4, 1.5, 1.6/types.hal into
-     * DataCallResponse
-     * @param dcResult SetupDataCallResult defined in radio/1.0, 1.4, 1.5, 1.6/types.hal
-     * @return The converted DataCallResponse
-     */
-    @VisibleForTesting
-    public static DataCallResponse convertHalDataCallResult(Object dcResult) {
-        if (dcResult == null) return null;
-
-        int cause, cid, active, mtu, mtuV4, mtuV6;
-        long suggestedRetryTime;
-        String ifname;
-        int protocolType;
-        String[] addresses = null;
-        String[] dnses = null;
-        String[] gateways = null;
-        String[] pcscfs = null;
-        Qos defaultQos = null;
-        @DataCallResponse.HandoverFailureMode
-        int handoverFailureMode = DataCallResponse.HANDOVER_FAILURE_MODE_LEGACY;
-        int pduSessionId = DataCallResponse.PDU_SESSION_ID_NOT_SET;
-        List<LinkAddress> laList = new ArrayList<>();
-        List<QosBearerSession> qosSessions = new ArrayList<>();
-        NetworkSliceInfo sliceInfo = null;
-        List<TrafficDescriptor> trafficDescriptors = new ArrayList<>();
-
-        if (dcResult instanceof android.hardware.radio.V1_0.SetupDataCallResult) {
-            final android.hardware.radio.V1_0.SetupDataCallResult result =
-                    (android.hardware.radio.V1_0.SetupDataCallResult) dcResult;
-            cause = result.status;
-            suggestedRetryTime = result.suggestedRetryTime;
-            cid = result.cid;
-            active = result.active;
-            protocolType = ApnSetting.getProtocolIntFromString(result.type);
-            ifname = result.ifname;
-            if (!TextUtils.isEmpty(result.addresses)) {
-                addresses = result.addresses.split("\\s+");
-            }
-            if (!TextUtils.isEmpty(result.dnses)) {
-                dnses = result.dnses.split("\\s+");
-            }
-            if (!TextUtils.isEmpty(result.gateways)) {
-                gateways = result.gateways.split("\\s+");
-            }
-            if (!TextUtils.isEmpty(result.pcscf)) {
-                pcscfs = result.pcscf.split("\\s+");
-            }
-            mtu = mtuV4 = mtuV6 = result.mtu;
-            if (addresses != null) {
-                for (String address : addresses) {
-                    laList.add(convertToLinkAddress(address));
-                }
-            }
-        } else if (dcResult instanceof android.hardware.radio.V1_4.SetupDataCallResult) {
-            final android.hardware.radio.V1_4.SetupDataCallResult result =
-                    (android.hardware.radio.V1_4.SetupDataCallResult) dcResult;
-            cause = result.cause;
-            suggestedRetryTime = result.suggestedRetryTime;
-            cid = result.cid;
-            active = result.active;
-            protocolType = result.type;
-            ifname = result.ifname;
-            addresses = result.addresses.toArray(new String[0]);
-            dnses = result.dnses.toArray(new String[0]);
-            gateways = result.gateways.toArray(new String[0]);
-            pcscfs = result.pcscf.toArray(new String[0]);
-            mtu = mtuV4 = mtuV6 = result.mtu;
-            if (addresses != null) {
-                for (String address : addresses) {
-                    laList.add(convertToLinkAddress(address));
-                }
-            }
-        } else if (dcResult instanceof android.hardware.radio.V1_5.SetupDataCallResult) {
-            final android.hardware.radio.V1_5.SetupDataCallResult result =
-                    (android.hardware.radio.V1_5.SetupDataCallResult) dcResult;
-            cause = result.cause;
-            suggestedRetryTime = result.suggestedRetryTime;
-            cid = result.cid;
-            active = result.active;
-            protocolType = result.type;
-            ifname = result.ifname;
-            laList = result.addresses.stream().map(la -> convertToLinkAddress(
-                    la.address, la.properties, la.deprecationTime, la.expirationTime))
-                    .collect(Collectors.toList());
-            dnses = result.dnses.toArray(new String[0]);
-            gateways = result.gateways.toArray(new String[0]);
-            pcscfs = result.pcscf.toArray(new String[0]);
-            mtu = Math.max(result.mtuV4, result.mtuV6);
-            mtuV4 = result.mtuV4;
-            mtuV6 = result.mtuV6;
-        } else if (dcResult instanceof android.hardware.radio.V1_6.SetupDataCallResult) {
-            final android.hardware.radio.V1_6.SetupDataCallResult result =
-                    (android.hardware.radio.V1_6.SetupDataCallResult) dcResult;
-            cause = result.cause;
-            suggestedRetryTime = result.suggestedRetryTime;
-            cid = result.cid;
-            active = result.active;
-            protocolType = result.type;
-            ifname = result.ifname;
-            laList = result.addresses.stream().map(la -> convertToLinkAddress(
-                    la.address, la.properties, la.deprecationTime, la.expirationTime))
-                    .collect(Collectors.toList());
-            dnses = result.dnses.toArray(new String[0]);
-            gateways = result.gateways.toArray(new String[0]);
-            pcscfs = result.pcscf.toArray(new String[0]);
-            mtu = Math.max(result.mtuV4, result.mtuV6);
-            mtuV4 = result.mtuV4;
-            mtuV6 = result.mtuV6;
-            handoverFailureMode = result.handoverFailureMode;
-            pduSessionId = result.pduSessionId;
-            defaultQos = convertHalQos(result.defaultQos);
-            qosSessions = result.qosSessions.stream().map(RILUtils::convertHalQosBearerSession)
-                    .collect(Collectors.toList());
-            sliceInfo = result.sliceInfo.getDiscriminator()
-                    == android.hardware.radio.V1_6.OptionalSliceInfo.hidl_discriminator.noinit
-                    ? null : convertHalSliceInfo(result.sliceInfo.value());
-            for (android.hardware.radio.V1_6.TrafficDescriptor td : result.trafficDescriptors) {
-                try {
-                    trafficDescriptors.add(RILUtils.convertHalTrafficDescriptor(td));
-                } catch (IllegalArgumentException e) {
-                    loge("convertHalDataCallResult: Failed to convert traffic descriptor. e=" + e);
-                }
-            }
-        } else {
-            loge("Unsupported SetupDataCallResult " + dcResult);
-            return null;
-        }
-
-        // Process dns
-        List<InetAddress> dnsList = new ArrayList<>();
-        if (dnses != null) {
-            for (String dns : dnses) {
-                dns = dns.trim();
-                InetAddress ia;
-                try {
-                    ia = InetAddresses.parseNumericAddress(dns);
-                    dnsList.add(ia);
-                } catch (IllegalArgumentException e) {
-                    Rlog.e(TAG, "Unknown dns: " + dns, e);
-                }
-            }
-        }
-
-        // Process gateway
-        List<InetAddress> gatewayList = new ArrayList<>();
-        if (gateways != null) {
-            for (String gateway : gateways) {
-                gateway = gateway.trim();
-                InetAddress ia;
-                try {
-                    ia = InetAddresses.parseNumericAddress(gateway);
-                    gatewayList.add(ia);
-                } catch (IllegalArgumentException e) {
-                    Rlog.e(TAG, "Unknown gateway: " + gateway, e);
-                }
-            }
-        }
-
-        // Process gateway
-        List<InetAddress> pcscfList = new ArrayList<>();
-        if (pcscfs != null) {
-            for (String pcscf : pcscfs) {
-                pcscf = pcscf.trim();
-                InetAddress ia;
-                try {
-                    ia = InetAddresses.parseNumericAddress(pcscf);
-                    pcscfList.add(ia);
-                } catch (IllegalArgumentException e) {
-                    Rlog.e(TAG, "Unknown pcscf: " + pcscf, e);
-                }
-            }
-        }
-
-        return new DataCallResponse.Builder()
-                .setCause(cause)
-                .setRetryDurationMillis(suggestedRetryTime)
-                .setId(cid)
-                .setLinkStatus(active)
-                .setProtocolType(protocolType)
-                .setInterfaceName(ifname)
-                .setAddresses(laList)
-                .setDnsAddresses(dnsList)
-                .setGatewayAddresses(gatewayList)
-                .setPcscfAddresses(pcscfList)
-                .setMtu(mtu)
-                .setMtuV4(mtuV4)
-                .setMtuV6(mtuV6)
-                .setHandoverFailureMode(handoverFailureMode)
-                .setPduSessionId(pduSessionId)
-                .setDefaultQos(defaultQos)
-                .setQosBearerSessions(qosSessions)
-                .setSliceInfo(sliceInfo)
-                .setTrafficDescriptors(trafficDescriptors)
-                .build();
-    }
-
-    /**
-     * Convert SetupDataCallResult defined in SetupDataCallResult.aidl into DataCallResponse
-     * @param result SetupDataCallResult defined in SetupDataCallResult.aidl
-     * @return The converted DataCallResponse
-     */
-    @VisibleForTesting
-    public static DataCallResponse convertHalDataCallResult(
-            android.hardware.radio.data.SetupDataCallResult result) {
-        if (result == null) return null;
-        List<LinkAddress> laList = new ArrayList<>();
-        for (android.hardware.radio.data.LinkAddress la : result.addresses) {
-            laList.add(convertToLinkAddress(la.address, la.addressProperties,
-                    la.deprecationTime, la.expirationTime));
-        }
-        List<InetAddress> dnsList = new ArrayList<>();
-        if (result.dnses != null) {
-            for (String dns : result.dnses) {
-                dns = dns.trim();
-                InetAddress ia;
-                try {
-                    ia = InetAddresses.parseNumericAddress(dns);
-                    dnsList.add(ia);
-                } catch (IllegalArgumentException e) {
-                    Rlog.e(TAG, "Unknown dns: " + dns, e);
-                }
-            }
-        }
-        List<InetAddress> gatewayList = new ArrayList<>();
-        if (result.gateways != null) {
-            for (String gateway : result.gateways) {
-                gateway = gateway.trim();
-                InetAddress ia;
-                try {
-                    ia = InetAddresses.parseNumericAddress(gateway);
-                    gatewayList.add(ia);
-                } catch (IllegalArgumentException e) {
-                    Rlog.e(TAG, "Unknown gateway: " + gateway, e);
-                }
-            }
-        }
-        List<InetAddress> pcscfList = new ArrayList<>();
-        if (result.pcscf != null) {
-            for (String pcscf : result.pcscf) {
-                pcscf = pcscf.trim();
-                InetAddress ia;
-                try {
-                    ia = InetAddresses.parseNumericAddress(pcscf);
-                    pcscfList.add(ia);
-                } catch (IllegalArgumentException e) {
-                    Rlog.e(TAG, "Unknown pcscf: " + pcscf, e);
-                }
-            }
-        }
-        List<QosBearerSession> qosSessions = new ArrayList<>();
-        for (android.hardware.radio.data.QosSession session : result.qosSessions) {
-            qosSessions.add(convertHalQosBearerSession(session));
-        }
-        List<TrafficDescriptor> trafficDescriptors = new ArrayList<>();
-        for (android.hardware.radio.data.TrafficDescriptor td : result.trafficDescriptors) {
-            try {
-                trafficDescriptors.add(convertHalTrafficDescriptor(td));
-            } catch (IllegalArgumentException e) {
-                loge("convertHalDataCallResult: Failed to convert traffic descriptor. e=" + e);
-            }
-        }
-
-        return new DataCallResponse.Builder()
-                .setCause(result.cause)
-                .setRetryDurationMillis(result.suggestedRetryTime)
-                .setId(result.cid)
-                .setLinkStatus(result.active)
-                .setProtocolType(result.type)
-                .setInterfaceName(result.ifname)
-                .setAddresses(laList)
-                .setDnsAddresses(dnsList)
-                .setGatewayAddresses(gatewayList)
-                .setPcscfAddresses(pcscfList)
-                .setMtu(Math.max(result.mtuV4, result.mtuV6))
-                .setMtuV4(result.mtuV4)
-                .setMtuV6(result.mtuV6)
-                .setHandoverFailureMode(result.handoverFailureMode)
-                .setPduSessionId(result.pduSessionId)
-                .setDefaultQos(convertHalQos(result.defaultQos))
-                .setQosBearerSessions(qosSessions)
-                .setSliceInfo(result.sliceInfo == null ? null
-                        : convertHalSliceInfo(result.sliceInfo))
-                .setTrafficDescriptors(trafficDescriptors)
-                .build();
-    }
-
-    private static NetworkSliceInfo convertHalSliceInfo(android.hardware.radio.V1_6.SliceInfo si) {
-        NetworkSliceInfo.Builder builder = new NetworkSliceInfo.Builder()
-                .setSliceServiceType(si.sst)
-                .setMappedHplmnSliceServiceType(si.mappedHplmnSst);
-        if (si.sliceDifferentiator != NetworkSliceInfo.SLICE_DIFFERENTIATOR_NO_SLICE) {
-            builder.setSliceDifferentiator(si.sliceDifferentiator)
-                    .setMappedHplmnSliceDifferentiator(si.mappedHplmnSD);
-        }
-        return builder.build();
-    }
-
-    private static NetworkSliceInfo convertHalSliceInfo(android.hardware.radio.data.SliceInfo si) {
-        NetworkSliceInfo.Builder builder = new NetworkSliceInfo.Builder()
-                .setSliceServiceType(si.sliceServiceType)
-                .setMappedHplmnSliceServiceType(si.mappedHplmnSst);
-        if (si.sliceDifferentiator != NetworkSliceInfo.SLICE_DIFFERENTIATOR_NO_SLICE) {
-            builder.setSliceDifferentiator(si.sliceDifferentiator)
-                    .setMappedHplmnSliceDifferentiator(si.mappedHplmnSd);
-        }
-        return builder.build();
-    }
-
-    private static TrafficDescriptor convertHalTrafficDescriptor(
-            android.hardware.radio.V1_6.TrafficDescriptor td) throws IllegalArgumentException {
-        String dnn = td.dnn.getDiscriminator()
-                == android.hardware.radio.V1_6.OptionalDnn.hidl_discriminator.noinit
-                ? null : td.dnn.value();
-        byte[] osAppId = td.osAppId.getDiscriminator()
-                == android.hardware.radio.V1_6.OptionalOsAppId.hidl_discriminator.noinit
-                ? null : arrayListToPrimitiveArray(td.osAppId.value().osAppId);
-
-        TrafficDescriptor.Builder builder = new TrafficDescriptor.Builder();
-        if (dnn != null) {
-            builder.setDataNetworkName(dnn);
-        }
-        if (osAppId != null) {
-            builder.setOsAppId(osAppId);
-        }
-        return builder.build();
-    }
-
-    private static TrafficDescriptor convertHalTrafficDescriptor(
-            android.hardware.radio.data.TrafficDescriptor td) throws IllegalArgumentException {
-        String dnn = td.dnn;
-        byte[] osAppId = td.osAppId == null ? null : td.osAppId.osAppId;
-        TrafficDescriptor.Builder builder = new TrafficDescriptor.Builder();
-        if (dnn != null) {
-            builder.setDataNetworkName(dnn);
-        }
-        if (osAppId != null) {
-            builder.setOsAppId(osAppId);
-        }
-        return builder.build();
-    }
-
-    /**
-     * Convert SlicingConfig defined in radio/1.6/types.hal to NetworkSlicingConfig
-     * @param sc SlicingConfig defined in radio/1.6/types.hal
-     * @return The converted NetworkSlicingConfig
-     */
-    public static NetworkSlicingConfig convertHalSlicingConfig(
-            android.hardware.radio.V1_6.SlicingConfig sc) {
-        List<UrspRule> urspRules = sc.urspRules.stream().map(ur -> new UrspRule(ur.precedence,
-                ur.trafficDescriptors.stream()
-                        .map(td -> {
-                            try {
-                                return convertHalTrafficDescriptor(td);
-                            } catch (IllegalArgumentException e) {
-                                loge("convertHalSlicingConfig: Failed to convert traffic descriptor"
-                                        + ". e=" + e);
-                                return null;
-                            }
-                        })
-                        .filter(Objects::nonNull)
-                        .collect(Collectors.toList()),
-                ur.routeSelectionDescriptor.stream().map(rsd -> new RouteSelectionDescriptor(
-                        rsd.precedence, rsd.sessionType.value(), rsd.sscMode.value(),
-                        rsd.sliceInfo.stream().map(RILUtils::convertHalSliceInfo)
-                                .collect(Collectors.toList()),
-                        rsd.dnn)).collect(Collectors.toList())))
-                .collect(Collectors.toList());
-        return new NetworkSlicingConfig(urspRules, sc.sliceInfo.stream()
-                .map(RILUtils::convertHalSliceInfo).collect(Collectors.toList()));
-    }
-
-    /**
-     * Convert SlicingConfig defined in SlicingConfig.aidl to NetworkSlicingConfig
-     * @param sc SlicingConfig defined in SlicingConfig.aidl
-     * @return The converted NetworkSlicingConfig
-     */
-    public static NetworkSlicingConfig convertHalSlicingConfig(
-            android.hardware.radio.data.SlicingConfig sc) {
-        List<UrspRule> urspRules = new ArrayList<>();
-        for (android.hardware.radio.data.UrspRule ur : sc.urspRules) {
-            List<TrafficDescriptor> tds = new ArrayList<>();
-            for (android.hardware.radio.data.TrafficDescriptor td : ur.trafficDescriptors) {
-                try {
-                    tds.add(convertHalTrafficDescriptor(td));
-                } catch (IllegalArgumentException e) {
-                    loge("convertHalTrafficDescriptor: " + e);
-                }
-            }
-            List<RouteSelectionDescriptor> rsds = new ArrayList<>();
-            for (android.hardware.radio.data.RouteSelectionDescriptor rsd
-                    : ur.routeSelectionDescriptor) {
-                List<NetworkSliceInfo> sliceInfo = new ArrayList<>();
-                for (android.hardware.radio.data.SliceInfo si : rsd.sliceInfo) {
-                    sliceInfo.add(convertHalSliceInfo(si));
-                }
-                rsds.add(new RouteSelectionDescriptor(rsd.precedence, rsd.sessionType, rsd.sscMode,
-                        sliceInfo, primitiveArrayToArrayList(rsd.dnn)));
-            }
-            urspRules.add(new UrspRule(ur.precedence, tds, rsds));
-        }
-        List<NetworkSliceInfo> sliceInfo = new ArrayList<>();
-        for (android.hardware.radio.data.SliceInfo si : sc.sliceInfo) {
-            sliceInfo.add(convertHalSliceInfo(si));
-        }
-        return new NetworkSlicingConfig(urspRules, sliceInfo);
-    }
-
-    private static Qos.QosBandwidth convertHalQosBandwidth(
-            android.hardware.radio.V1_6.QosBandwidth bandwidth) {
-        return new Qos.QosBandwidth(bandwidth.maxBitrateKbps, bandwidth.guaranteedBitrateKbps);
-    }
-
-    private static Qos.QosBandwidth convertHalQosBandwidth(
-            android.hardware.radio.data.QosBandwidth bandwidth) {
-        return new Qos.QosBandwidth(bandwidth.maxBitrateKbps, bandwidth.guaranteedBitrateKbps);
-    }
-
-    private static Qos convertHalQos(android.hardware.radio.V1_6.Qos qos) {
-        switch (qos.getDiscriminator()) {
-            case android.hardware.radio.V1_6.Qos.hidl_discriminator.eps:
-                android.hardware.radio.V1_6.EpsQos eps = qos.eps();
-                return new EpsQos(convertHalQosBandwidth(eps.downlink),
-                        convertHalQosBandwidth(eps.uplink), eps.qci);
-            case android.hardware.radio.V1_6.Qos.hidl_discriminator.nr:
-                android.hardware.radio.V1_6.NrQos nr = qos.nr();
-                return new NrQos(convertHalQosBandwidth(nr.downlink),
-                        convertHalQosBandwidth(nr.uplink), nr.qfi, nr.fiveQi, nr.averagingWindowMs);
-            default:
-                return null;
-        }
-    }
-
-    private static Qos convertHalQos(android.hardware.radio.data.Qos qos) {
-        switch (qos.getTag()) {
-            case android.hardware.radio.data.Qos.eps:
-                android.hardware.radio.data.EpsQos eps = qos.getEps();
-                return new EpsQos(convertHalQosBandwidth(eps.downlink),
-                        convertHalQosBandwidth(eps.uplink), eps.qci);
-            case android.hardware.radio.data.Qos.nr:
-                android.hardware.radio.data.NrQos nr = qos.getNr();
-                return new NrQos(convertHalQosBandwidth(nr.downlink),
-                        convertHalQosBandwidth(nr.uplink), nr.qfi, nr.fiveQi,
-                        nr.averagingWindowMs);
-            default:
-                return null;
-        }
-    }
-
-    private static QosBearerFilter convertHalQosBearerFilter(
-            android.hardware.radio.V1_6.QosFilter qosFilter) {
-        List<LinkAddress> localAddressList = new ArrayList<>();
-        String[] localAddresses = qosFilter.localAddresses.toArray(new String[0]);
-        if (localAddresses != null) {
-            for (String address : localAddresses) {
-                localAddressList.add(convertToLinkAddress(address));
-            }
-        }
-        List<LinkAddress> remoteAddressList = new ArrayList<>();
-        String[] remoteAddresses = qosFilter.remoteAddresses.toArray(new String[0]);
-        if (remoteAddresses != null) {
-            for (String address : remoteAddresses) {
-                remoteAddressList.add(convertToLinkAddress(address));
-            }
-        }
-        QosBearerFilter.PortRange localPort = null;
-        if (qosFilter.localPort != null) {
-            if (qosFilter.localPort.getDiscriminator()
-                    == android.hardware.radio.V1_6.MaybePort.hidl_discriminator.range) {
-                final android.hardware.radio.V1_6.PortRange portRange = qosFilter.localPort.range();
-                localPort = new QosBearerFilter.PortRange(portRange.start, portRange.end);
-            }
-        }
-        QosBearerFilter.PortRange remotePort = null;
-        if (qosFilter.remotePort != null) {
-            if (qosFilter.remotePort.getDiscriminator()
-                    == android.hardware.radio.V1_6.MaybePort.hidl_discriminator.range) {
-                final android.hardware.radio.V1_6.PortRange portRange =
-                        qosFilter.remotePort.range();
-                remotePort = new QosBearerFilter.PortRange(portRange.start, portRange.end);
-            }
-        }
-        int tos = -1;
-        if (qosFilter.tos != null) {
-            if (qosFilter.tos.getDiscriminator() == android.hardware.radio.V1_6.QosFilter
-                    .TypeOfService.hidl_discriminator.value) {
-                tos = qosFilter.tos.value();
-            }
-        }
-        long flowLabel = -1;
-        if (qosFilter.flowLabel != null) {
-            if (qosFilter.flowLabel.getDiscriminator() == android.hardware.radio.V1_6.QosFilter
-                    .Ipv6FlowLabel.hidl_discriminator.value) {
-                flowLabel = qosFilter.flowLabel.value();
-            }
-        }
-        long spi = -1;
-        if (qosFilter.spi != null) {
-            if (qosFilter.spi.getDiscriminator()
-                    == android.hardware.radio.V1_6.QosFilter.IpsecSpi.hidl_discriminator.value) {
-                spi = qosFilter.spi.value();
-            }
-        }
-        return new QosBearerFilter(localAddressList, remoteAddressList, localPort, remotePort,
-                qosFilter.protocol, tos, flowLabel, spi, qosFilter.direction, qosFilter.precedence);
-    }
-
-    private static QosBearerFilter convertHalQosBearerFilter(
-            android.hardware.radio.data.QosFilter qosFilter) {
-        List<LinkAddress> localAddressList = new ArrayList<>();
-        String[] localAddresses = qosFilter.localAddresses;
-        if (localAddresses != null) {
-            for (String address : localAddresses) {
-                localAddressList.add(convertToLinkAddress(address));
-            }
-        }
-        List<LinkAddress> remoteAddressList = new ArrayList<>();
-        String[] remoteAddresses = qosFilter.remoteAddresses;
-        if (remoteAddresses != null) {
-            for (String address : remoteAddresses) {
-                remoteAddressList.add(convertToLinkAddress(address));
-            }
-        }
-        QosBearerFilter.PortRange localPort = null;
-        if (qosFilter.localPort != null) {
-            localPort = new QosBearerFilter.PortRange(
-                    qosFilter.localPort.start, qosFilter.localPort.end);
-        }
-        QosBearerFilter.PortRange remotePort = null;
-        if (qosFilter.remotePort != null) {
-            remotePort = new QosBearerFilter.PortRange(
-                    qosFilter.remotePort.start, qosFilter.remotePort.end);
-        }
-        int tos = -1;
-        if (qosFilter.tos != null) {
-            if (qosFilter.tos.getTag()
-                    == android.hardware.radio.data.QosFilterTypeOfService.value) {
-                tos = qosFilter.tos.value;
-            }
-        }
-        long flowLabel = -1;
-        if (qosFilter.flowLabel != null) {
-            if (qosFilter.flowLabel.getTag()
-                    == android.hardware.radio.data.QosFilterIpv6FlowLabel.value) {
-                flowLabel = qosFilter.flowLabel.value;
-            }
-        }
-        long spi = -1;
-        if (qosFilter.spi != null) {
-            if (qosFilter.spi.getTag()
-                    == android.hardware.radio.data.QosFilterIpsecSpi.value) {
-                spi = qosFilter.spi.value;
-            }
-        }
-        return new QosBearerFilter(localAddressList, remoteAddressList, localPort, remotePort,
-                qosFilter.protocol, tos, flowLabel, spi, qosFilter.direction, qosFilter.precedence);
-    }
-
-    private static QosBearerSession convertHalQosBearerSession(
-            android.hardware.radio.V1_6.QosSession qosSession) {
-        List<QosBearerFilter> qosBearerFilters = new ArrayList<>();
-        if (qosSession.qosFilters != null) {
-            for (android.hardware.radio.V1_6.QosFilter filter : qosSession.qosFilters) {
-                qosBearerFilters.add(convertHalQosBearerFilter(filter));
-            }
-        }
-        return new QosBearerSession(qosSession.qosSessionId, convertHalQos(qosSession.qos),
-                qosBearerFilters);
-    }
-
-    private static QosBearerSession convertHalQosBearerSession(
-            android.hardware.radio.data.QosSession qosSession) {
-        List<QosBearerFilter> qosBearerFilters = new ArrayList<>();
-        if (qosSession.qosFilters != null) {
-            for (android.hardware.radio.data.QosFilter filter : qosSession.qosFilters) {
-                qosBearerFilters.add(convertHalQosBearerFilter(filter));
-            }
-        }
-        return new QosBearerSession(qosSession.qosSessionId, convertHalQos(qosSession.qos),
-                qosBearerFilters);
-    }
-
-    /**
-     * Convert a list of SetupDataCallResult defined in radio/1.0, 1.4, 1.5, 1.6/types.hal into
-     * a list of DataCallResponse
-     * @param dataCallResultList List of SetupDataCallResult defined in
-     *        radio/1.0, 1.4, 1.5, 1.6/types.hal
-     * @return The converted list of DataCallResponses
-     */
-    @VisibleForTesting
-    public static ArrayList<DataCallResponse> convertHalDataCallResultList(
-            List<? extends Object> dataCallResultList) {
-        ArrayList<DataCallResponse> response = new ArrayList<>(dataCallResultList.size());
-
-        for (Object obj : dataCallResultList) {
-            response.add(convertHalDataCallResult(obj));
-        }
-        return response;
-    }
-
-    /**
-     * Convert a list of SetupDataCallResult defined in SetupDataCallResult.aidl into a list of
-     * DataCallResponse
-     * @param dataCallResultList Array of SetupDataCallResult defined in SetupDataCallResult.aidl
-     * @return The converted list of DataCallResponses
-     */
-    @VisibleForTesting
-    public static ArrayList<DataCallResponse> convertHalDataCallResultList(
-            android.hardware.radio.data.SetupDataCallResult[] dataCallResultList) {
-        ArrayList<DataCallResponse> response = new ArrayList<>(dataCallResultList.length);
-
-        for (android.hardware.radio.data.SetupDataCallResult result : dataCallResultList) {
-            response.add(convertHalDataCallResult(result));
-        }
-        return response;
-    }
-
-    /**
-     * Convert KeepaliveStatusCode defined in radio/1.1/types.hal and KeepaliveStatus.aidl
-     * to KeepaliveStatus
-     * @param halCode KeepaliveStatus code defined in radio/1.1/types.hal or KeepaliveStatus.aidl
-     * @return The converted KeepaliveStatus
-     */
-    public static @KeepaliveStatusCode int convertHalKeepaliveStatusCode(int halCode) {
-        switch (halCode) {
-            case android.hardware.radio.V1_1.KeepaliveStatusCode.ACTIVE:
-                return KeepaliveStatus.STATUS_ACTIVE;
-            case android.hardware.radio.V1_1.KeepaliveStatusCode.INACTIVE:
-                return KeepaliveStatus.STATUS_INACTIVE;
-            case android.hardware.radio.V1_1.KeepaliveStatusCode.PENDING:
-                return KeepaliveStatus.STATUS_PENDING;
-            default:
-                return -1;
-        }
-    }
-
-    /**
-     * Convert RadioState defined in radio/1.0/types.hal and RadioState.aidl to RadioPowerState
-     * @param stateInt Radio state defined in radio/1.0/types.hal or RadioState.aidl
-     * @return The converted {@link Annotation.RadioPowerState RadioPowerState}
-     */
-    public static @Annotation.RadioPowerState int convertHalRadioState(int stateInt) {
-        int state;
-        switch(stateInt) {
-            case android.hardware.radio.V1_0.RadioState.OFF:
-                state = TelephonyManager.RADIO_POWER_OFF;
-                break;
-            case android.hardware.radio.V1_0.RadioState.UNAVAILABLE:
-                state = TelephonyManager.RADIO_POWER_UNAVAILABLE;
-                break;
-            case android.hardware.radio.V1_0.RadioState.ON:
-                state = TelephonyManager.RADIO_POWER_ON;
-                break;
-            default:
-                throw new RuntimeException("Unrecognized RadioState: " + stateInt);
-        }
-        return state;
-    }
-
-    /**
-     * Convert CellConnectionStatus defined in radio/1.2/types.hal to ConnectionStatus
-     * @param status Cell connection status defined in radio/1.2/types.hal
-     * @return The converted ConnectionStatus
-     */
-    public static int convertHalCellConnectionStatus(int status) {
-        switch (status) {
-            case android.hardware.radio.V1_2.CellConnectionStatus.PRIMARY_SERVING:
-                return PhysicalChannelConfig.CONNECTION_PRIMARY_SERVING;
-            case android.hardware.radio.V1_2.CellConnectionStatus.SECONDARY_SERVING:
-                return PhysicalChannelConfig.CONNECTION_SECONDARY_SERVING;
-            default:
-                return PhysicalChannelConfig.CONNECTION_UNKNOWN;
-        }
-    }
-
-    /**
-     * Convert Call defined in radio/1.0, 1.2, 1.6/types.hal to DriverCall
-     * @param halCall Call defined in radio/1.0, 1.2, 1.6/types.hal
-     * @return The converted DriverCall
-     */
-    public static DriverCall convertToDriverCall(Object halCall) {
-        DriverCall dc = new DriverCall();
-        final android.hardware.radio.V1_6.Call call16;
-        final android.hardware.radio.V1_2.Call call12;
-        final android.hardware.radio.V1_0.Call call10;
-        if (halCall instanceof android.hardware.radio.V1_6.Call) {
-            call16 = (android.hardware.radio.V1_6.Call) halCall;
-            call12 = call16.base;
-            call10 = call12.base;
-        } else if (halCall instanceof android.hardware.radio.V1_2.Call) {
-            call16 = null;
-            call12 = (android.hardware.radio.V1_2.Call) halCall;
-            call10 = call12.base;
-        } else if (halCall instanceof android.hardware.radio.V1_0.Call) {
-            call16 = null;
-            call12 = null;
-            call10 = (android.hardware.radio.V1_0.Call) halCall;
-        } else {
-            call16 = null;
-            call12 = null;
-            call10 = null;
-        }
-        if (call10 != null) {
-            dc.state = DriverCall.stateFromCLCC((int) (call10.state));
-            dc.index = call10.index;
-            dc.TOA = call10.toa;
-            dc.isMpty = call10.isMpty;
-            dc.isMT = call10.isMT;
-            dc.als = call10.als;
-            dc.isVoice = call10.isVoice;
-            dc.isVoicePrivacy = call10.isVoicePrivacy;
-            dc.number = call10.number;
-            dc.numberPresentation = DriverCall.presentationFromCLIP(
-                    (int) (call10.numberPresentation));
-            dc.name = call10.name;
-            dc.namePresentation = DriverCall.presentationFromCLIP((int) (call10.namePresentation));
-            if (call10.uusInfo.size() == 1) {
-                dc.uusInfo = new UUSInfo();
-                dc.uusInfo.setType(call10.uusInfo.get(0).uusType);
-                dc.uusInfo.setDcs(call10.uusInfo.get(0).uusDcs);
-                if (!TextUtils.isEmpty(call10.uusInfo.get(0).uusData)) {
-                    byte[] userData = call10.uusInfo.get(0).uusData.getBytes();
-                    dc.uusInfo.setUserData(userData);
-                }
-            }
-            // Make sure there's a leading + on addresses with a TOA of 145
-            dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
-        }
-        if (call12 != null) {
-            dc.audioQuality = (int) (call12.audioQuality);
-        }
-        if (call16 != null) {
-            dc.forwardedNumber = call16.forwardedNumber;
-        }
-        return dc;
-    }
-
-    /**
-     * Convert Call defined in Call.aidl to DriverCall
-     * @param halCall Call defined in Call.aidl
-     * @return The converted DriverCall
-     */
-    public static DriverCall convertToDriverCall(android.hardware.radio.voice.Call halCall) {
-        DriverCall dc = new DriverCall();
-        dc.state = DriverCall.stateFromCLCC((int) halCall.state);
-        dc.index = halCall.index;
-        dc.TOA = halCall.toa;
-        dc.isMpty = halCall.isMpty;
-        dc.isMT = halCall.isMT;
-        dc.als = halCall.als;
-        dc.isVoice = halCall.isVoice;
-        dc.isVoicePrivacy = halCall.isVoicePrivacy;
-        dc.number = halCall.number;
-        dc.numberPresentation = DriverCall.presentationFromCLIP((int) halCall.numberPresentation);
-        dc.name = halCall.name;
-        dc.namePresentation = DriverCall.presentationFromCLIP((int) halCall.namePresentation);
-        if (halCall.uusInfo.length == 1) {
-            dc.uusInfo = new UUSInfo();
-            dc.uusInfo.setType(halCall.uusInfo[0].uusType);
-            dc.uusInfo.setDcs(halCall.uusInfo[0].uusDcs);
-            if (!TextUtils.isEmpty(halCall.uusInfo[0].uusData)) {
-                dc.uusInfo.setUserData(halCall.uusInfo[0].uusData.getBytes());
-            }
-        }
-        // Make sure there's a leading + on addresses with a TOA of 145
-        dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
-        dc.audioQuality = (int) halCall.audioQuality;
-        dc.forwardedNumber = halCall.forwardedNumber;
-        return dc;
-    }
-
-    /**
-     * Convert OperatorStatus defined in radio/1.0/types.hal to OperatorInfo.State
-     * @param status Operator status defined in radio/1.0/types.hal
-     * @return The converted OperatorStatus as a String
-     */
-    public static String convertHalOperatorStatus(int status) {
-        if (status == android.hardware.radio.V1_0.OperatorStatus.UNKNOWN) {
-            return "unknown";
-        } else if (status == android.hardware.radio.V1_0.OperatorStatus.AVAILABLE) {
-            return "available";
-        } else if (status == android.hardware.radio.V1_0.OperatorStatus.CURRENT) {
-            return "current";
-        } else if (status == android.hardware.radio.V1_0.OperatorStatus.FORBIDDEN) {
-            return "forbidden";
-        } else {
-            return "";
-        }
-    }
-
-    /**
-     * Convert a list of Carriers defined in radio/1.0/types.hal to a list of CarrierIdentifiers
-     * @param carrierList List of Carriers defined in radio/1.0/types.hal
-     * @return The converted list of CarrierIdentifiers
-     */
-    public static List<CarrierIdentifier> convertHalCarrierList(
-            List<android.hardware.radio.V1_0.Carrier> carrierList) {
-        List<CarrierIdentifier> ret = new ArrayList<>();
-        for (int i = 0; i < carrierList.size(); i++) {
-            String mcc = carrierList.get(i).mcc;
-            String mnc = carrierList.get(i).mnc;
-            String spn = null, imsi = null, gid1 = null, gid2 = null;
-            int matchType = carrierList.get(i).matchType;
-            String matchData = carrierList.get(i).matchData;
-            if (matchType == CarrierIdentifier.MatchType.SPN) {
-                spn = matchData;
-            } else if (matchType == CarrierIdentifier.MatchType.IMSI_PREFIX) {
-                imsi = matchData;
-            } else if (matchType == CarrierIdentifier.MatchType.GID1) {
-                gid1 = matchData;
-            } else if (matchType == CarrierIdentifier.MatchType.GID2) {
-                gid2 = matchData;
-            }
-            ret.add(new CarrierIdentifier(mcc, mnc, spn, imsi, gid1, gid2));
-        }
-        return ret;
-    }
-
-    /**
-     * Convert a list of Carriers defined in radio/1.0/types.hal to a list of CarrierIdentifiers
-     * @param carrierList List of Carriers defined in radio/1.0/types.hal
-     * @return The converted list of CarrierIdentifiers
-     */
-    public static List<CarrierIdentifier> convertHalCarrierList(
-            android.hardware.radio.sim.Carrier[] carrierList) {
-        List<CarrierIdentifier> ret = new ArrayList<>();
-        for (int i = 0; i < carrierList.length; i++) {
-            String mcc = carrierList[i].mcc;
-            String mnc = carrierList[i].mnc;
-            String spn = null, imsi = null, gid1 = null, gid2 = null;
-            int matchType = carrierList[i].matchType;
-            String matchData = carrierList[i].matchData;
-            if (matchType == CarrierIdentifier.MatchType.SPN) {
-                spn = matchData;
-            } else if (matchType == CarrierIdentifier.MatchType.IMSI_PREFIX) {
-                imsi = matchData;
-            } else if (matchType == CarrierIdentifier.MatchType.GID1) {
-                gid1 = matchData;
-            } else if (matchType == CarrierIdentifier.MatchType.GID2) {
-                gid2 = matchData;
-            }
-            ret.add(new CarrierIdentifier(mcc, mnc, spn, imsi, gid1, gid2));
-        }
-        return ret;
-    }
-
-    /**
-     * Convert CardStatus defined in radio/1.0, 1.5/types.hal to IccCardStatus
-     * @param cardStatus CardStatus defined in radio/1.0, 1.5/types.hal
-     * @return The converted IccCardStatus
-     */
-    public static IccCardStatus convertHalCardStatus(Object cardStatus) {
-        final android.hardware.radio.V1_0.CardStatus cardStatus10;
-        final android.hardware.radio.V1_5.CardStatus cardStatus15;
-        if (cardStatus instanceof android.hardware.radio.V1_5.CardStatus) {
-            cardStatus15 = (android.hardware.radio.V1_5.CardStatus) cardStatus;
-            cardStatus10 = cardStatus15.base.base.base;
-        } else if (cardStatus instanceof android.hardware.radio.V1_0.CardStatus) {
-            cardStatus15 = null;
-            cardStatus10 = (android.hardware.radio.V1_0.CardStatus) cardStatus;
-        } else {
-            cardStatus15 = null;
-            cardStatus10 = null;
-        }
-
-        IccCardStatus iccCardStatus = new IccCardStatus();
-        if (cardStatus10 != null) {
-            iccCardStatus.setCardState(cardStatus10.cardState);
-            iccCardStatus.setUniversalPinState(cardStatus10.universalPinState);
-            iccCardStatus.mGsmUmtsSubscriptionAppIndex = cardStatus10.gsmUmtsSubscriptionAppIndex;
-            iccCardStatus.mCdmaSubscriptionAppIndex = cardStatus10.cdmaSubscriptionAppIndex;
-            iccCardStatus.mImsSubscriptionAppIndex = cardStatus10.imsSubscriptionAppIndex;
-            int numApplications = cardStatus10.applications.size();
-
-            // limit to maximum allowed applications
-            if (numApplications > com.android.internal.telephony.uicc.IccCardStatus.CARD_MAX_APPS) {
-                numApplications = com.android.internal.telephony.uicc.IccCardStatus.CARD_MAX_APPS;
-            }
-            iccCardStatus.mApplications = new IccCardApplicationStatus[numApplications];
-            for (int i = 0; i < numApplications; i++) {
-                android.hardware.radio.V1_0.AppStatus rilAppStatus =
-                        cardStatus10.applications.get(i);
-                IccCardApplicationStatus appStatus = new IccCardApplicationStatus();
-                appStatus.app_type = appStatus.AppTypeFromRILInt(rilAppStatus.appType);
-                appStatus.app_state = appStatus.AppStateFromRILInt(rilAppStatus.appState);
-                appStatus.perso_substate = appStatus.PersoSubstateFromRILInt(
-                        rilAppStatus.persoSubstate);
-                appStatus.aid = rilAppStatus.aidPtr;
-                appStatus.app_label = rilAppStatus.appLabelPtr;
-                appStatus.pin1_replaced = rilAppStatus.pin1Replaced != 0;
-                appStatus.pin1 = appStatus.PinStateFromRILInt(rilAppStatus.pin1);
-                appStatus.pin2 = appStatus.PinStateFromRILInt(rilAppStatus.pin2);
-                iccCardStatus.mApplications[i] = appStatus;
-            }
-        }
-        if (cardStatus15 != null) {
-            IccSlotPortMapping slotPortMapping = new IccSlotPortMapping();
-            slotPortMapping.mPhysicalSlotIndex = cardStatus15.base.base.physicalSlotId;
-            iccCardStatus.mSlotPortMapping = slotPortMapping;
-            iccCardStatus.atr = cardStatus15.base.base.atr;
-            iccCardStatus.iccid = cardStatus15.base.base.iccid;
-            iccCardStatus.eid = cardStatus15.base.eid;
-            int numApplications = cardStatus15.applications.size();
-
-            // limit to maximum allowed applications
-            if (numApplications > com.android.internal.telephony.uicc.IccCardStatus.CARD_MAX_APPS) {
-                numApplications = com.android.internal.telephony.uicc.IccCardStatus.CARD_MAX_APPS;
-            }
-            iccCardStatus.mApplications = new IccCardApplicationStatus[numApplications];
-            for (int i = 0; i < numApplications; i++) {
-                android.hardware.radio.V1_5.AppStatus rilAppStatus =
-                        cardStatus15.applications.get(i);
-                IccCardApplicationStatus appStatus = new IccCardApplicationStatus();
-                appStatus.app_type = appStatus.AppTypeFromRILInt(rilAppStatus.base.appType);
-                appStatus.app_state = appStatus.AppStateFromRILInt(rilAppStatus.base.appState);
-                appStatus.perso_substate = appStatus.PersoSubstateFromRILInt(
-                        rilAppStatus.persoSubstate);
-                appStatus.aid = rilAppStatus.base.aidPtr;
-                appStatus.app_label = rilAppStatus.base.appLabelPtr;
-                appStatus.pin1_replaced = rilAppStatus.base.pin1Replaced != 0;
-                appStatus.pin1 = appStatus.PinStateFromRILInt(rilAppStatus.base.pin1);
-                appStatus.pin2 = appStatus.PinStateFromRILInt(rilAppStatus.base.pin2);
-                iccCardStatus.mApplications[i] = appStatus;
-            }
-        }
-        return iccCardStatus;
-    }
-
-    /**
-     * Convert CardStatus defined in CardStatus.aidl to IccCardStatus
-     * @param cardStatus CardStatus defined in CardStatus.aidl
-     * @return The converted IccCardStatus
-     */
-    public static IccCardStatus convertHalCardStatus(
-            android.hardware.radio.sim.CardStatus cardStatus) {
-        IccCardStatus iccCardStatus = new IccCardStatus();
-        iccCardStatus.setCardState(cardStatus.cardState);
-        iccCardStatus.setUniversalPinState(cardStatus.universalPinState);
-        iccCardStatus.mGsmUmtsSubscriptionAppIndex = cardStatus.gsmUmtsSubscriptionAppIndex;
-        iccCardStatus.mCdmaSubscriptionAppIndex = cardStatus.cdmaSubscriptionAppIndex;
-        iccCardStatus.mImsSubscriptionAppIndex = cardStatus.imsSubscriptionAppIndex;
-        iccCardStatus.atr = cardStatus.atr;
-        iccCardStatus.iccid = cardStatus.iccid;
-        iccCardStatus.eid = cardStatus.eid;
-
-        int numApplications = Math.min(cardStatus.applications.length,
-                com.android.internal.telephony.uicc.IccCardStatus.CARD_MAX_APPS);
-        iccCardStatus.mApplications = new IccCardApplicationStatus[numApplications];
-        for (int i = 0; i < numApplications; i++) {
-            android.hardware.radio.sim.AppStatus rilAppStatus = cardStatus.applications[i];
-            IccCardApplicationStatus appStatus = new IccCardApplicationStatus();
-            appStatus.app_type = appStatus.AppTypeFromRILInt(rilAppStatus.appType);
-            appStatus.app_state = appStatus.AppStateFromRILInt(rilAppStatus.appState);
-            appStatus.perso_substate = appStatus.PersoSubstateFromRILInt(
-                    rilAppStatus.persoSubstate);
-            appStatus.aid = rilAppStatus.aidPtr;
-            appStatus.app_label = rilAppStatus.appLabelPtr;
-            appStatus.pin1_replaced = rilAppStatus.pin1Replaced;
-            appStatus.pin1 = appStatus.PinStateFromRILInt(rilAppStatus.pin1);
-            appStatus.pin2 = appStatus.PinStateFromRILInt(rilAppStatus.pin2);
-            iccCardStatus.mApplications[i] = appStatus;
-        }
-        IccSlotPortMapping slotPortMapping = new IccSlotPortMapping();
-        slotPortMapping.mPhysicalSlotIndex = cardStatus.slotMap.physicalSlotId;
-        slotPortMapping.mPortIndex = cardStatus.slotMap.portId;
-        iccCardStatus.mSlotPortMapping = slotPortMapping;
-        return iccCardStatus;
-    }
-
-    /**
-     * Convert PhonebookCapacity defined in radio/1.6/types.hal to AdnCapacity
-     * @param pbCap PhonebookCapacity defined in radio/1.6/types.hal
-     * @return The converted AdnCapacity
-     */
-    public static AdnCapacity convertHalPhonebookCapacity(
-            android.hardware.radio.V1_6.PhonebookCapacity pbCap) {
-        if (pbCap != null) {
-            return new AdnCapacity(pbCap.maxAdnRecords, pbCap.usedAdnRecords, pbCap.maxEmailRecords,
-                    pbCap.usedEmailRecords, pbCap.maxAdditionalNumberRecords,
-                    pbCap.usedAdditionalNumberRecords, pbCap.maxNameLen, pbCap.maxNumberLen,
-                    pbCap.maxEmailLen, pbCap.maxAdditionalNumberLen);
-        }
-        return null;
-    }
-
-    /**
-     * Convert PhonebookCapacity defined in PhonebookCapacity.aidl to AdnCapacity
-     * @param pbCap PhonebookCapacity defined in PhonebookCapacity.aidl
-     * @return The converted AdnCapacity
-     */
-    public static AdnCapacity convertHalPhonebookCapacity(
-            android.hardware.radio.sim.PhonebookCapacity pbCap) {
-        if (pbCap != null) {
-            return new AdnCapacity(pbCap.maxAdnRecords, pbCap.usedAdnRecords, pbCap.maxEmailRecords,
-                    pbCap.usedEmailRecords, pbCap.maxAdditionalNumberRecords,
-                    pbCap.usedAdditionalNumberRecords, pbCap.maxNameLen, pbCap.maxNumberLen,
-                    pbCap.maxEmailLen, pbCap.maxAdditionalNumberLen);
-        }
-        return null;
-    }
-
-    /**
-     * Convert PhonebookRecordInfo defined in radio/1.6/types.hal to SimPhonebookRecord
-     * @param recInfo PhonebookRecordInfo defined in radio/1.6/types.hal
-     * @return The converted SimPhonebookRecord
-     */
-    public static SimPhonebookRecord convertHalPhonebookRecordInfo(
-            android.hardware.radio.V1_6.PhonebookRecordInfo recInfo) {
-        String[] emails = recInfo.emails == null ? null
-                : recInfo.emails.toArray(new String[recInfo.emails.size()]);
-        String[] numbers = recInfo.additionalNumbers == null ? null
-                : recInfo.additionalNumbers.toArray(new String[recInfo.additionalNumbers.size()]);
-        return new SimPhonebookRecord(recInfo.recordId, recInfo.name, recInfo.number, emails,
-                numbers);
-    }
-
-    /**
-     * Convert PhonebookRecordInfo defined in PhonebookRecordInfo.aidl to SimPhonebookRecord
-     * @param recInfo PhonebookRecordInfo defined in PhonebookRecordInfo.aidl
-     * @return The converted SimPhonebookRecord
-     */
-    public static SimPhonebookRecord convertHalPhonebookRecordInfo(
-            android.hardware.radio.sim.PhonebookRecordInfo recInfo) {
-        return new SimPhonebookRecord(recInfo.recordId, recInfo.name, recInfo.number,
-                recInfo.emails, recInfo.additionalNumbers);
-    }
-
-    /**
-     * Convert to PhonebookRecordInfo defined in radio/1.6/types.hal
-     * @param record SimPhonebookRecord to convert
-     * @return The converted PhonebookRecordInfo defined in radio/1.6/types.hal
-     */
-    public static android.hardware.radio.V1_6.PhonebookRecordInfo convertToHalPhonebookRecordInfo(
-            SimPhonebookRecord record) {
-        if (record != null) {
-            return record.toPhonebookRecordInfo();
-        }
-        return null;
-    }
-
-    /**
-     * Convert to PhonebookRecordInfo.aidl
-     * @param record SimPhonebookRecord to convert
-     * @return The converted PhonebookRecordInfo
-     */
-    public static android.hardware.radio.sim.PhonebookRecordInfo
-            convertToHalPhonebookRecordInfoAidl(SimPhonebookRecord record) {
-        if (record != null) {
-            return record.toPhonebookRecordInfoAidl();
-        }
-        return new android.hardware.radio.sim.PhonebookRecordInfo();
-    }
-
-    /**
-     * Convert array of SimSlotStatus to IccSlotStatus
-     * @param o object that represents array/list of SimSlotStatus
-     * @return ArrayList of IccSlotStatus
-     */
-    public static ArrayList<IccSlotStatus> convertHalSlotStatus(Object o) {
-        ArrayList<IccSlotStatus> response = new ArrayList<>();
-        try {
-            final android.hardware.radio.config.SimSlotStatus[] halSlotStatusArray =
-                    (android.hardware.radio.config.SimSlotStatus[]) o;
-            for (android.hardware.radio.config.SimSlotStatus slotStatus : halSlotStatusArray) {
-                IccSlotStatus iccSlotStatus = new IccSlotStatus();
-                iccSlotStatus.setCardState(slotStatus.cardState);
-                int portCount = slotStatus.portInfo.length;
-                iccSlotStatus.mSimPortInfos = new IccSimPortInfo[portCount];
-                for (int i = 0; i < portCount; i++) {
-                    IccSimPortInfo simPortInfo = new IccSimPortInfo();
-                    simPortInfo.mIccId = slotStatus.portInfo[i].iccId;
-                    // If port is not active, set invalid logical slot index(-1) irrespective of
-                    // the modem response. For more info, check http://b/209035150
-                    simPortInfo.mLogicalSlotIndex = slotStatus.portInfo[i].portActive
-                            ? slotStatus.portInfo[i].logicalSlotId : -1;
-                    simPortInfo.mPortActive = slotStatus.portInfo[i].portActive;
-                    iccSlotStatus.mSimPortInfos[i] = simPortInfo;
-                }
-                iccSlotStatus.atr = slotStatus.atr;
-                iccSlotStatus.eid = slotStatus.eid;
-                response.add(iccSlotStatus);
-            }
-            return response;
-        } catch (ClassCastException ignore) { }
-        try {
-            final ArrayList<android.hardware.radio.config.V1_2.SimSlotStatus>
-                    halSlotStatusArray =
-                    (ArrayList<android.hardware.radio.config.V1_2.SimSlotStatus>) o;
-            for (android.hardware.radio.config.V1_2.SimSlotStatus slotStatus :
-                    halSlotStatusArray) {
-                IccSlotStatus iccSlotStatus = new IccSlotStatus();
-                iccSlotStatus.setCardState(slotStatus.base.cardState);
-                // Old HAL versions does not support MEP, so only one port is available.
-                iccSlotStatus.mSimPortInfos = new IccSimPortInfo[1];
-                IccSimPortInfo simPortInfo = new IccSimPortInfo();
-                simPortInfo.mIccId = slotStatus.base.iccid;
-                simPortInfo.mPortActive = (slotStatus.base.slotState == IccSlotStatus.STATE_ACTIVE);
-                // If port/slot is not active, set invalid logical slot index(-1) irrespective of
-                // the modem response. For more info, check http://b/209035150
-                simPortInfo.mLogicalSlotIndex = simPortInfo.mPortActive
-                        ? slotStatus.base.logicalSlotId : -1;
-                iccSlotStatus.mSimPortInfos[TelephonyManager.DEFAULT_PORT_INDEX] = simPortInfo;
-                iccSlotStatus.atr = slotStatus.base.atr;
-                iccSlotStatus.eid = slotStatus.eid;
-                response.add(iccSlotStatus);
-            }
-            return response;
-        } catch (ClassCastException ignore) { }
-        try {
-            final ArrayList<android.hardware.radio.config.V1_0.SimSlotStatus>
-                    halSlotStatusArray =
-                    (ArrayList<android.hardware.radio.config.V1_0.SimSlotStatus>) o;
-            for (android.hardware.radio.config.V1_0.SimSlotStatus slotStatus :
-                    halSlotStatusArray) {
-                IccSlotStatus iccSlotStatus = new IccSlotStatus();
-                iccSlotStatus.setCardState(slotStatus.cardState);
-                // Old HAL versions does not support MEP, so only one port is available.
-                iccSlotStatus.mSimPortInfos = new IccSimPortInfo[1];
-                IccSimPortInfo simPortInfo = new IccSimPortInfo();
-                simPortInfo.mIccId = slotStatus.iccid;
-                simPortInfo.mPortActive = (slotStatus.slotState == IccSlotStatus.STATE_ACTIVE);
-                // If port/slot is not active, set invalid logical slot index(-1) irrespective of
-                // the modem response. For more info, check http://b/209035150
-                simPortInfo.mLogicalSlotIndex = simPortInfo.mPortActive
-                        ? slotStatus.logicalSlotId : -1;
-                iccSlotStatus.mSimPortInfos[TelephonyManager.DEFAULT_PORT_INDEX] = simPortInfo;
-                iccSlotStatus.atr = slotStatus.atr;
-                response.add(iccSlotStatus);
-            }
-            return response;
-        } catch (ClassCastException ignore) { }
-        return response;
-    }
-
-    /**
-     * Convert List<UiccSlotMapping> list to SlotPortMapping[]
-     * @param slotMapping List<UiccSlotMapping> of slots mapping
-     * @return SlotPortMapping[] of slots mapping
-     */
-    public static android.hardware.radio.config.SlotPortMapping[] convertSimSlotsMapping(
-            List<UiccSlotMapping> slotMapping) {
-        android.hardware.radio.config.SlotPortMapping[] res =
-                new android.hardware.radio.config.SlotPortMapping[slotMapping.size()];
-        for (UiccSlotMapping mapping : slotMapping) {
-            int logicalSlotIdx = mapping.getLogicalSlotIndex();
-            res[logicalSlotIdx] = new android.hardware.radio.config.SlotPortMapping();
-            res[logicalSlotIdx].physicalSlotId = mapping.getPhysicalSlotIndex();
-            res[logicalSlotIdx].portId = mapping.getPortIndex();
-        }
-        return res;
-    }
-
-    /** Convert a list of UiccSlotMapping to an ArrayList<Integer>.*/
-    public static ArrayList<Integer> convertSlotMappingToList(
-            List<UiccSlotMapping> slotMapping) {
-        int[] physicalSlots = new int[slotMapping.size()];
-        for (UiccSlotMapping mapping : slotMapping) {
-            physicalSlots[mapping.getLogicalSlotIndex()] = mapping.getPhysicalSlotIndex();
-        }
-        return primitiveArrayToArrayList(physicalSlots);
-    }
-
-
-    /**
-     * Convert PhoneCapability to telephony PhoneCapability.
-     * @param deviceNrCapabilities device's nr capability array
-     * @param o PhoneCapability to convert
-     * @return converted PhoneCapability
-     */
-    public static PhoneCapability convertHalPhoneCapability(int[] deviceNrCapabilities, Object o) {
-        int maxActiveVoiceCalls = 0;
-        int maxActiveData = 0;
-        boolean validationBeforeSwitchSupported = false;
-        List<ModemInfo> logicalModemList = new ArrayList<>();
-        if (o instanceof android.hardware.radio.config.PhoneCapability) {
-            final android.hardware.radio.config.PhoneCapability phoneCapability =
-                    (android.hardware.radio.config.PhoneCapability) o;
-            maxActiveData = phoneCapability.maxActiveData;
-            validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported;
-            for (int modemId : phoneCapability.logicalModemIds) {
-                logicalModemList.add(new ModemInfo(modemId));
-            }
-        } else if (o instanceof android.hardware.radio.config.V1_1.PhoneCapability) {
-            final android.hardware.radio.config.V1_1.PhoneCapability phoneCapability =
-                    (android.hardware.radio.config.V1_1.PhoneCapability) o;
-            maxActiveData = phoneCapability.maxActiveData;
-            validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported;
-            for (android.hardware.radio.config.V1_1.ModemInfo modemInfo :
-                    phoneCapability.logicalModemList) {
-                logicalModemList.add(new ModemInfo(modemInfo.modemId));
-            }
-        }
-        return new PhoneCapability(maxActiveVoiceCalls, maxActiveData, logicalModemList,
-                validationBeforeSwitchSupported, deviceNrCapabilities);
-    }
-
-    /** Append the data to the end of an ArrayList */
-    public static void appendPrimitiveArrayToArrayList(byte[] src, ArrayList<Byte> dst) {
-        for (byte b : src) {
-            dst.add(b);
-        }
-    }
-
-    /** Convert a primitive byte array to an ArrayList<Integer>. */
-    public static ArrayList<Byte> primitiveArrayToArrayList(byte[] arr) {
-        ArrayList<Byte> arrayList = new ArrayList<>(arr.length);
-        for (byte b : arr) {
-            arrayList.add(b);
-        }
-        return arrayList;
-    }
-
-    /** Convert a primitive int array to an ArrayList<Integer>. */
-    public static ArrayList<Integer> primitiveArrayToArrayList(int[] arr) {
-        ArrayList<Integer> arrayList = new ArrayList<>(arr.length);
-        for (int i : arr) {
-            arrayList.add(i);
-        }
-        return arrayList;
-    }
-
-    /** Convert a primitive String array to an ArrayList<String>. */
-    public static ArrayList<String> primitiveArrayToArrayList(String[] arr) {
-        return new ArrayList<>(Arrays.asList(arr));
-    }
-
-    /** Convert an ArrayList of Bytes to an exactly-sized primitive array */
-    public static byte[] arrayListToPrimitiveArray(ArrayList<Byte> bytes) {
-        byte[] ret = new byte[bytes.size()];
-        for (int i = 0; i < ret.length; i++) {
-            ret[i] = bytes.get(i);
-        }
-        return ret;
-    }
-
-    /** Convert null to an empty String */
-    public static String convertNullToEmptyString(String string) {
-        return string != null ? string : "";
-    }
-
-    /**
-     * Convert setup data reason to string.
-     *
-     * @param reason The reason for setup data call.
-     * @return The reason in string format.
-     */
-    public static String setupDataReasonToString(@SetupDataReason int reason) {
-        switch (reason) {
-            case DataService.REQUEST_REASON_NORMAL:
-                return "NORMAL";
-            case DataService.REQUEST_REASON_HANDOVER:
-                return "HANDOVER";
-            case DataService.REQUEST_REASON_UNKNOWN:
-                return "UNKNOWN";
-            default:
-                return "UNKNOWN(" + reason + ")";
-        }
-    }
-
-    /**
-     * Convert deactivate data reason to string.
-     *
-     * @param reason The reason for deactivate data call.
-     * @return The reason in string format.
-     */
-    public static String deactivateDataReasonToString(@DeactivateDataReason int reason) {
-        switch (reason) {
-            case DataService.REQUEST_REASON_NORMAL:
-                return "NORMAL";
-            case DataService.REQUEST_REASON_HANDOVER:
-                return "HANDOVER";
-            case DataService.REQUEST_REASON_SHUTDOWN:
-                return "SHUTDOWN";
-            case DataService.REQUEST_REASON_UNKNOWN:
-                return "UNKNOWN";
-            default:
-                return "UNKNOWN(" + reason + ")";
-        }
-    }
-
-    /**
-     * RIL request to String
-     * @param request request
-     * @return The converted String request
-     */
-    public static String requestToString(int request) {
-        switch(request) {
-            case RIL_REQUEST_GET_SIM_STATUS:
-                return "GET_SIM_STATUS";
-            case RIL_REQUEST_ENTER_SIM_PIN:
-                return "ENTER_SIM_PIN";
-            case RIL_REQUEST_ENTER_SIM_PUK:
-                return "ENTER_SIM_PUK";
-            case RIL_REQUEST_ENTER_SIM_PIN2:
-                return "ENTER_SIM_PIN2";
-            case RIL_REQUEST_ENTER_SIM_PUK2:
-                return "ENTER_SIM_PUK2";
-            case RIL_REQUEST_CHANGE_SIM_PIN:
-                return "CHANGE_SIM_PIN";
-            case RIL_REQUEST_CHANGE_SIM_PIN2:
-                return "CHANGE_SIM_PIN2";
-            case RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION:
-                return "ENTER_NETWORK_DEPERSONALIZATION";
-            case RIL_REQUEST_GET_CURRENT_CALLS:
-                return "GET_CURRENT_CALLS";
-            case RIL_REQUEST_DIAL:
-                return "DIAL";
-            case RIL_REQUEST_GET_IMSI:
-                return "GET_IMSI";
-            case RIL_REQUEST_HANGUP:
-                return "HANGUP";
-            case RIL_REQUEST_HANGUP_WAITING_OR_BACKGROUND:
-                return "HANGUP_WAITING_OR_BACKGROUND";
-            case RIL_REQUEST_HANGUP_FOREGROUND_RESUME_BACKGROUND:
-                return "HANGUP_FOREGROUND_RESUME_BACKGROUND";
-            case RIL_REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE:
-                return "REQUEST_SWITCH_WAITING_OR_HOLDING_AND_ACTIVE";
-            case RIL_REQUEST_CONFERENCE:
-                return "CONFERENCE";
-            case RIL_REQUEST_UDUB:
-                return "UDUB";
-            case RIL_REQUEST_LAST_CALL_FAIL_CAUSE:
-                return "LAST_CALL_FAIL_CAUSE";
-            case RIL_REQUEST_SIGNAL_STRENGTH:
-                return "SIGNAL_STRENGTH";
-            case RIL_REQUEST_VOICE_REGISTRATION_STATE:
-                return "VOICE_REGISTRATION_STATE";
-            case RIL_REQUEST_DATA_REGISTRATION_STATE:
-                return "DATA_REGISTRATION_STATE";
-            case RIL_REQUEST_OPERATOR:
-                return "OPERATOR";
-            case RIL_REQUEST_RADIO_POWER:
-                return "RADIO_POWER";
-            case RIL_REQUEST_DTMF:
-                return "DTMF";
-            case RIL_REQUEST_SEND_SMS:
-                return "SEND_SMS";
-            case RIL_REQUEST_SEND_SMS_EXPECT_MORE:
-                return "SEND_SMS_EXPECT_MORE";
-            case RIL_REQUEST_SETUP_DATA_CALL:
-                return "SETUP_DATA_CALL";
-            case RIL_REQUEST_SIM_IO:
-                return "SIM_IO";
-            case RIL_REQUEST_SEND_USSD:
-                return "SEND_USSD";
-            case RIL_REQUEST_CANCEL_USSD:
-                return "CANCEL_USSD";
-            case RIL_REQUEST_GET_CLIR:
-                return "GET_CLIR";
-            case RIL_REQUEST_SET_CLIR:
-                return "SET_CLIR";
-            case RIL_REQUEST_QUERY_CALL_FORWARD_STATUS:
-                return "QUERY_CALL_FORWARD_STATUS";
-            case RIL_REQUEST_SET_CALL_FORWARD:
-                return "SET_CALL_FORWARD";
-            case RIL_REQUEST_QUERY_CALL_WAITING:
-                return "QUERY_CALL_WAITING";
-            case RIL_REQUEST_SET_CALL_WAITING:
-                return "SET_CALL_WAITING";
-            case RIL_REQUEST_SMS_ACKNOWLEDGE:
-                return "SMS_ACKNOWLEDGE";
-            case RIL_REQUEST_GET_IMEI:
-                return "GET_IMEI";
-            case RIL_REQUEST_GET_IMEISV:
-                return "GET_IMEISV";
-            case RIL_REQUEST_ANSWER:
-                return "ANSWER";
-            case RIL_REQUEST_DEACTIVATE_DATA_CALL:
-                return "DEACTIVATE_DATA_CALL";
-            case RIL_REQUEST_QUERY_FACILITY_LOCK:
-                return "QUERY_FACILITY_LOCK";
-            case RIL_REQUEST_SET_FACILITY_LOCK:
-                return "SET_FACILITY_LOCK";
-            case RIL_REQUEST_CHANGE_BARRING_PASSWORD:
-                return "CHANGE_BARRING_PASSWORD";
-            case RIL_REQUEST_QUERY_NETWORK_SELECTION_MODE:
-                return "QUERY_NETWORK_SELECTION_MODE";
-            case RIL_REQUEST_SET_NETWORK_SELECTION_AUTOMATIC:
-                return "SET_NETWORK_SELECTION_AUTOMATIC";
-            case RIL_REQUEST_SET_NETWORK_SELECTION_MANUAL:
-                return "SET_NETWORK_SELECTION_MANUAL";
-            case RIL_REQUEST_QUERY_AVAILABLE_NETWORKS :
-                return "QUERY_AVAILABLE_NETWORKS ";
-            case RIL_REQUEST_DTMF_START:
-                return "DTMF_START";
-            case RIL_REQUEST_DTMF_STOP:
-                return "DTMF_STOP";
-            case RIL_REQUEST_BASEBAND_VERSION:
-                return "BASEBAND_VERSION";
-            case RIL_REQUEST_SEPARATE_CONNECTION:
-                return "SEPARATE_CONNECTION";
-            case RIL_REQUEST_SET_MUTE:
-                return "SET_MUTE";
-            case RIL_REQUEST_GET_MUTE:
-                return "GET_MUTE";
-            case RIL_REQUEST_QUERY_CLIP:
-                return "QUERY_CLIP";
-            case RIL_REQUEST_LAST_DATA_CALL_FAIL_CAUSE:
-                return "LAST_DATA_CALL_FAIL_CAUSE";
-            case RIL_REQUEST_DATA_CALL_LIST:
-                return "DATA_CALL_LIST";
-            case RIL_REQUEST_RESET_RADIO:
-                return "RESET_RADIO";
-            case RIL_REQUEST_OEM_HOOK_RAW:
-                return "OEM_HOOK_RAW";
-            case RIL_REQUEST_OEM_HOOK_STRINGS:
-                return "OEM_HOOK_STRINGS";
-            case RIL_REQUEST_SCREEN_STATE:
-                return "SCREEN_STATE";
-            case RIL_REQUEST_SET_SUPP_SVC_NOTIFICATION:
-                return "SET_SUPP_SVC_NOTIFICATION";
-            case RIL_REQUEST_WRITE_SMS_TO_SIM:
-                return "WRITE_SMS_TO_SIM";
-            case RIL_REQUEST_DELETE_SMS_ON_SIM:
-                return "DELETE_SMS_ON_SIM";
-            case RIL_REQUEST_SET_BAND_MODE:
-                return "SET_BAND_MODE";
-            case RIL_REQUEST_QUERY_AVAILABLE_BAND_MODE:
-                return "QUERY_AVAILABLE_BAND_MODE";
-            case RIL_REQUEST_STK_GET_PROFILE:
-                return "STK_GET_PROFILE";
-            case RIL_REQUEST_STK_SET_PROFILE:
-                return "STK_SET_PROFILE";
-            case RIL_REQUEST_STK_SEND_ENVELOPE_COMMAND:
-                return "STK_SEND_ENVELOPE_COMMAND";
-            case RIL_REQUEST_STK_SEND_TERMINAL_RESPONSE:
-                return "STK_SEND_TERMINAL_RESPONSE";
-            case RIL_REQUEST_STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM:
-                return "STK_HANDLE_CALL_SETUP_REQUESTED_FROM_SIM";
-            case RIL_REQUEST_EXPLICIT_CALL_TRANSFER:
-                return "EXPLICIT_CALL_TRANSFER";
-            case RIL_REQUEST_SET_PREFERRED_NETWORK_TYPE:
-                return "SET_PREFERRED_NETWORK_TYPE";
-            case RIL_REQUEST_GET_PREFERRED_NETWORK_TYPE:
-                return "GET_PREFERRED_NETWORK_TYPE";
-            case RIL_REQUEST_GET_NEIGHBORING_CELL_IDS:
-                return "GET_NEIGHBORING_CELL_IDS";
-            case RIL_REQUEST_SET_LOCATION_UPDATES:
-                return "SET_LOCATION_UPDATES";
-            case RIL_REQUEST_CDMA_SET_SUBSCRIPTION_SOURCE:
-                return "CDMA_SET_SUBSCRIPTION_SOURCE";
-            case RIL_REQUEST_CDMA_SET_ROAMING_PREFERENCE:
-                return "CDMA_SET_ROAMING_PREFERENCE";
-            case RIL_REQUEST_CDMA_QUERY_ROAMING_PREFERENCE:
-                return "CDMA_QUERY_ROAMING_PREFERENCE";
-            case RIL_REQUEST_SET_TTY_MODE:
-                return "SET_TTY_MODE";
-            case RIL_REQUEST_QUERY_TTY_MODE:
-                return "QUERY_TTY_MODE";
-            case RIL_REQUEST_CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE:
-                return "CDMA_SET_PREFERRED_VOICE_PRIVACY_MODE";
-            case RIL_REQUEST_CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE:
-                return "CDMA_QUERY_PREFERRED_VOICE_PRIVACY_MODE";
-            case RIL_REQUEST_CDMA_FLASH:
-                return "CDMA_FLASH";
-            case RIL_REQUEST_CDMA_BURST_DTMF:
-                return "CDMA_BURST_DTMF";
-            case RIL_REQUEST_CDMA_VALIDATE_AND_WRITE_AKEY:
-                return "CDMA_VALIDATE_AND_WRITE_AKEY";
-            case RIL_REQUEST_CDMA_SEND_SMS:
-                return "CDMA_SEND_SMS";
-            case RIL_REQUEST_CDMA_SMS_ACKNOWLEDGE:
-                return "CDMA_SMS_ACKNOWLEDGE";
-            case RIL_REQUEST_GSM_GET_BROADCAST_CONFIG:
-                return "GSM_GET_BROADCAST_CONFIG";
-            case RIL_REQUEST_GSM_SET_BROADCAST_CONFIG:
-                return "GSM_SET_BROADCAST_CONFIG";
-            case RIL_REQUEST_GSM_BROADCAST_ACTIVATION:
-                return "GSM_BROADCAST_ACTIVATION";
-            case RIL_REQUEST_CDMA_GET_BROADCAST_CONFIG:
-                return "CDMA_GET_BROADCAST_CONFIG";
-            case RIL_REQUEST_CDMA_SET_BROADCAST_CONFIG:
-                return "CDMA_SET_BROADCAST_CONFIG";
-            case RIL_REQUEST_CDMA_BROADCAST_ACTIVATION:
-                return "CDMA_BROADCAST_ACTIVATION";
-            case RIL_REQUEST_CDMA_SUBSCRIPTION:
-                return "CDMA_SUBSCRIPTION";
-            case RIL_REQUEST_CDMA_WRITE_SMS_TO_RUIM:
-                return "CDMA_WRITE_SMS_TO_RUIM";
-            case RIL_REQUEST_CDMA_DELETE_SMS_ON_RUIM:
-                return "CDMA_DELETE_SMS_ON_RUIM";
-            case RIL_REQUEST_DEVICE_IDENTITY:
-                return "DEVICE_IDENTITY";
-            case RIL_REQUEST_EXIT_EMERGENCY_CALLBACK_MODE:
-                return "EXIT_EMERGENCY_CALLBACK_MODE";
-            case RIL_REQUEST_GET_SMSC_ADDRESS:
-                return "GET_SMSC_ADDRESS";
-            case RIL_REQUEST_SET_SMSC_ADDRESS:
-                return "SET_SMSC_ADDRESS";
-            case RIL_REQUEST_REPORT_SMS_MEMORY_STATUS:
-                return "REPORT_SMS_MEMORY_STATUS";
-            case RIL_REQUEST_REPORT_STK_SERVICE_IS_RUNNING:
-                return "REPORT_STK_SERVICE_IS_RUNNING";
-            case RIL_REQUEST_CDMA_GET_SUBSCRIPTION_SOURCE:
-                return "CDMA_GET_SUBSCRIPTION_SOURCE";
-            case RIL_REQUEST_ISIM_AUTHENTICATION:
-                return "ISIM_AUTHENTICATION";
-            case RIL_REQUEST_ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU:
-                return "ACKNOWLEDGE_INCOMING_GSM_SMS_WITH_PDU";
-            case RIL_REQUEST_STK_SEND_ENVELOPE_WITH_STATUS:
-                return "STK_SEND_ENVELOPE_WITH_STATUS";
-            case RIL_REQUEST_VOICE_RADIO_TECH:
-                return "VOICE_RADIO_TECH";
-            case RIL_REQUEST_GET_CELL_INFO_LIST:
-                return "GET_CELL_INFO_LIST";
-            case RIL_REQUEST_SET_UNSOL_CELL_INFO_LIST_RATE:
-                return "SET_CELL_INFO_LIST_RATE";
-            case RIL_REQUEST_SET_INITIAL_ATTACH_APN:
-                return "SET_INITIAL_ATTACH_APN";
-            case RIL_REQUEST_IMS_REGISTRATION_STATE:
-                return "IMS_REGISTRATION_STATE";
-            case RIL_REQUEST_IMS_SEND_SMS:
-                return "IMS_SEND_SMS";
-            case RIL_REQUEST_SIM_TRANSMIT_APDU_BASIC:
-                return "SIM_TRANSMIT_APDU_BASIC";
-            case RIL_REQUEST_SIM_OPEN_CHANNEL:
-                return "SIM_OPEN_CHANNEL";
-            case RIL_REQUEST_SIM_CLOSE_CHANNEL:
-                return "SIM_CLOSE_CHANNEL";
-            case RIL_REQUEST_SIM_TRANSMIT_APDU_CHANNEL:
-                return "SIM_TRANSMIT_APDU_CHANNEL";
-            case RIL_REQUEST_NV_READ_ITEM:
-                return "NV_READ_ITEM";
-            case RIL_REQUEST_NV_WRITE_ITEM:
-                return "NV_WRITE_ITEM";
-            case RIL_REQUEST_NV_WRITE_CDMA_PRL:
-                return "NV_WRITE_CDMA_PRL";
-            case RIL_REQUEST_NV_RESET_CONFIG:
-                return "NV_RESET_CONFIG";
-            case RIL_REQUEST_SET_UICC_SUBSCRIPTION:
-                return "SET_UICC_SUBSCRIPTION";
-            case RIL_REQUEST_ALLOW_DATA:
-                return "ALLOW_DATA";
-            case RIL_REQUEST_GET_HARDWARE_CONFIG:
-                return "GET_HARDWARE_CONFIG";
-            case RIL_REQUEST_SIM_AUTHENTICATION:
-                return "SIM_AUTHENTICATION";
-            case RIL_REQUEST_GET_DC_RT_INFO:
-                return "GET_DC_RT_INFO";
-            case RIL_REQUEST_SET_DC_RT_INFO_RATE:
-                return "SET_DC_RT_INFO_RATE";
-            case RIL_REQUEST_SET_DATA_PROFILE:
-                return "SET_DATA_PROFILE";
-            case RIL_REQUEST_SHUTDOWN:
-                return "SHUTDOWN";
-            case RIL_REQUEST_GET_RADIO_CAPABILITY:
-                return "GET_RADIO_CAPABILITY";
-            case RIL_REQUEST_SET_RADIO_CAPABILITY:
-                return "SET_RADIO_CAPABILITY";
-            case RIL_REQUEST_START_LCE:
-                return "START_LCE";
-            case RIL_REQUEST_STOP_LCE:
-                return "STOP_LCE";
-            case RIL_REQUEST_PULL_LCEDATA:
-                return "PULL_LCEDATA";
-            case RIL_REQUEST_GET_ACTIVITY_INFO:
-                return "GET_ACTIVITY_INFO";
-            case RIL_REQUEST_SET_ALLOWED_CARRIERS:
-                return "SET_ALLOWED_CARRIERS";
-            case RIL_REQUEST_GET_ALLOWED_CARRIERS:
-                return "GET_ALLOWED_CARRIERS";
-            case RIL_REQUEST_SEND_DEVICE_STATE:
-                return "SEND_DEVICE_STATE";
-            case RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER:
-                return "SET_UNSOLICITED_RESPONSE_FILTER";
-            case RIL_REQUEST_SET_SIM_CARD_POWER:
-                return "SET_SIM_CARD_POWER";
-            case RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION:
-                return "SET_CARRIER_INFO_IMSI_ENCRYPTION";
-            case RIL_REQUEST_START_NETWORK_SCAN:
-                return "START_NETWORK_SCAN";
-            case RIL_REQUEST_STOP_NETWORK_SCAN:
-                return "STOP_NETWORK_SCAN";
-            case RIL_REQUEST_START_KEEPALIVE:
-                return "START_KEEPALIVE";
-            case RIL_REQUEST_STOP_KEEPALIVE:
-                return "STOP_KEEPALIVE";
-            case RIL_REQUEST_ENABLE_MODEM:
-                return "ENABLE_MODEM";
-            case RIL_REQUEST_GET_MODEM_STATUS:
-                return "GET_MODEM_STATUS";
-            case RIL_REQUEST_CDMA_SEND_SMS_EXPECT_MORE:
-                return "CDMA_SEND_SMS_EXPECT_MORE";
-            case RIL_REQUEST_GET_SIM_PHONEBOOK_CAPACITY:
-                return "GET_SIM_PHONEBOOK_CAPACITY";
-            case RIL_REQUEST_GET_SIM_PHONEBOOK_RECORDS:
-                return "GET_SIM_PHONEBOOK_RECORDS";
-            case RIL_REQUEST_UPDATE_SIM_PHONEBOOK_RECORD:
-                return "UPDATE_SIM_PHONEBOOK_RECORD";
-            case RIL_REQUEST_GET_SLOT_STATUS:
-                return "GET_SLOT_STATUS";
-            case RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING:
-                return "SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING";
-            case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA:
-                return "SET_SIGNAL_STRENGTH_REPORTING_CRITERIA";
-            case RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA:
-                return "SET_LINK_CAPACITY_REPORTING_CRITERIA";
-            case RIL_REQUEST_SET_PREFERRED_DATA_MODEM:
-                return "SET_PREFERRED_DATA_MODEM";
-            case RIL_REQUEST_EMERGENCY_DIAL:
-                return "EMERGENCY_DIAL";
-            case RIL_REQUEST_GET_PHONE_CAPABILITY:
-                return "GET_PHONE_CAPABILITY";
-            case RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG:
-                return "SWITCH_DUAL_SIM_CONFIG";
-            case RIL_REQUEST_ENABLE_UICC_APPLICATIONS:
-                return "ENABLE_UICC_APPLICATIONS";
-            case RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT:
-                return "GET_UICC_APPLICATIONS_ENABLEMENT";
-            case RIL_REQUEST_SET_SYSTEM_SELECTION_CHANNELS:
-                return "SET_SYSTEM_SELECTION_CHANNELS";
-            case RIL_REQUEST_GET_BARRING_INFO:
-                return "GET_BARRING_INFO";
-            case RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION:
-                return "ENTER_SIM_DEPERSONALIZATION";
-            case RIL_REQUEST_ENABLE_NR_DUAL_CONNECTIVITY:
-                return "ENABLE_NR_DUAL_CONNECTIVITY";
-            case RIL_REQUEST_IS_NR_DUAL_CONNECTIVITY_ENABLED:
-                return "IS_NR_DUAL_CONNECTIVITY_ENABLED";
-            case RIL_REQUEST_ALLOCATE_PDU_SESSION_ID:
-                return "ALLOCATE_PDU_SESSION_ID";
-            case RIL_REQUEST_RELEASE_PDU_SESSION_ID:
-                return "RELEASE_PDU_SESSION_ID";
-            case RIL_REQUEST_START_HANDOVER:
-                return "START_HANDOVER";
-            case RIL_REQUEST_CANCEL_HANDOVER:
-                return "CANCEL_HANDOVER";
-            case RIL_REQUEST_GET_SYSTEM_SELECTION_CHANNELS:
-                return "GET_SYSTEM_SELECTION_CHANNELS";
-            case RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES:
-                return "GET_HAL_DEVICE_CAPABILITIES";
-            case RIL_REQUEST_SET_DATA_THROTTLING:
-                return "SET_DATA_THROTTLING";
-            case RIL_REQUEST_SET_ALLOWED_NETWORK_TYPES_BITMAP:
-                return "SET_ALLOWED_NETWORK_TYPES_BITMAP";
-            case RIL_REQUEST_GET_ALLOWED_NETWORK_TYPES_BITMAP:
-                return "GET_ALLOWED_NETWORK_TYPES_BITMAP";
-            case RIL_REQUEST_GET_SLICING_CONFIG:
-                return "GET_SLICING_CONFIG";
-            case RIL_REQUEST_ENABLE_VONR:
-                return "ENABLE_VONR";
-            case RIL_REQUEST_IS_VONR_ENABLED:
-                return "IS_VONR_ENABLED";
-            case RIL_REQUEST_SET_USAGE_SETTING:
-                return "SET_USAGE_SETTING";
-            case RIL_REQUEST_GET_USAGE_SETTING:
-                return "GET_USAGE_SETTING";
-            default:
-                return "<unknown request " + request + ">";
-        }
-    }
-
-    /**
-     * RIL response to String
-     * @param response response
-     * @return The converted String response
-     */
-    public static String responseToString(int response) {
-        switch (response) {
-            case RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED:
-                return "UNSOL_RESPONSE_RADIO_STATE_CHANGED";
-            case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
-                return "UNSOL_RESPONSE_CALL_STATE_CHANGED";
-            case RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED:
-                return "UNSOL_RESPONSE_NETWORK_STATE_CHANGED";
-            case RIL_UNSOL_RESPONSE_NEW_SMS:
-                return "UNSOL_RESPONSE_NEW_SMS";
-            case RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT:
-                return "UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT";
-            case RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM:
-                return "UNSOL_RESPONSE_NEW_SMS_ON_SIM";
-            case RIL_UNSOL_ON_USSD:
-                return "UNSOL_ON_USSD";
-            case RIL_UNSOL_ON_USSD_REQUEST:
-                return "UNSOL_ON_USSD_REQUEST";
-            case RIL_UNSOL_NITZ_TIME_RECEIVED:
-                return "UNSOL_NITZ_TIME_RECEIVED";
-            case RIL_UNSOL_SIGNAL_STRENGTH:
-                return "UNSOL_SIGNAL_STRENGTH";
-            case RIL_UNSOL_DATA_CALL_LIST_CHANGED:
-                return "UNSOL_DATA_CALL_LIST_CHANGED";
-            case RIL_UNSOL_SUPP_SVC_NOTIFICATION:
-                return "UNSOL_SUPP_SVC_NOTIFICATION";
-            case RIL_UNSOL_STK_SESSION_END:
-                return "UNSOL_STK_SESSION_END";
-            case RIL_UNSOL_STK_PROACTIVE_COMMAND:
-                return "UNSOL_STK_PROACTIVE_COMMAND";
-            case RIL_UNSOL_STK_EVENT_NOTIFY:
-                return "UNSOL_STK_EVENT_NOTIFY";
-            case RIL_UNSOL_STK_CALL_SETUP:
-                return "UNSOL_STK_CALL_SETUP";
-            case RIL_UNSOL_SIM_SMS_STORAGE_FULL:
-                return "UNSOL_SIM_SMS_STORAGE_FULL";
-            case RIL_UNSOL_SIM_REFRESH:
-                return "UNSOL_SIM_REFRESH";
-            case RIL_UNSOL_CALL_RING:
-                return "UNSOL_CALL_RING";
-            case RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED:
-                return "UNSOL_RESPONSE_SIM_STATUS_CHANGED";
-            case RIL_UNSOL_RESPONSE_CDMA_NEW_SMS:
-                return "UNSOL_RESPONSE_CDMA_NEW_SMS";
-            case RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS:
-                return "UNSOL_RESPONSE_NEW_BROADCAST_SMS";
-            case RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL:
-                return "UNSOL_CDMA_RUIM_SMS_STORAGE_FULL";
-            case RIL_UNSOL_RESTRICTED_STATE_CHANGED:
-                return "UNSOL_RESTRICTED_STATE_CHANGED";
-            case RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE:
-                return "UNSOL_ENTER_EMERGENCY_CALLBACK_MODE";
-            case RIL_UNSOL_CDMA_CALL_WAITING:
-                return "UNSOL_CDMA_CALL_WAITING";
-            case RIL_UNSOL_CDMA_OTA_PROVISION_STATUS:
-                return "UNSOL_CDMA_OTA_PROVISION_STATUS";
-            case RIL_UNSOL_CDMA_INFO_REC:
-                return "UNSOL_CDMA_INFO_REC";
-            case RIL_UNSOL_OEM_HOOK_RAW:
-                return "UNSOL_OEM_HOOK_RAW";
-            case RIL_UNSOL_RINGBACK_TONE:
-                return "UNSOL_RINGBACK_TONE";
-            case RIL_UNSOL_RESEND_INCALL_MUTE:
-                return "UNSOL_RESEND_INCALL_MUTE";
-            case RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED:
-                return "UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED";
-            case RIL_UNSOL_CDMA_PRL_CHANGED:
-                return "UNSOL_CDMA_PRL_CHANGED";
-            case RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE:
-                return "UNSOL_EXIT_EMERGENCY_CALLBACK_MODE";
-            case RIL_UNSOL_RIL_CONNECTED:
-                return "UNSOL_RIL_CONNECTED";
-            case RIL_UNSOL_VOICE_RADIO_TECH_CHANGED:
-                return "UNSOL_VOICE_RADIO_TECH_CHANGED";
-            case RIL_UNSOL_CELL_INFO_LIST:
-                return "UNSOL_CELL_INFO_LIST";
-            case RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED:
-                return "UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED";
-            case RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED:
-                return "UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED";
-            case RIL_UNSOL_SRVCC_STATE_NOTIFY:
-                return "UNSOL_SRVCC_STATE_NOTIFY";
-            case RIL_UNSOL_HARDWARE_CONFIG_CHANGED:
-                return "UNSOL_HARDWARE_CONFIG_CHANGED";
-            case RIL_UNSOL_DC_RT_INFO_CHANGED:
-                return "UNSOL_DC_RT_INFO_CHANGED";
-            case RIL_UNSOL_RADIO_CAPABILITY:
-                return "UNSOL_RADIO_CAPABILITY";
-            case RIL_UNSOL_ON_SS:
-                return "UNSOL_ON_SS";
-            case RIL_UNSOL_STK_CC_ALPHA_NOTIFY:
-                return "UNSOL_STK_CC_ALPHA_NOTIFY";
-            case RIL_UNSOL_LCEDATA_RECV:
-                return "UNSOL_LCE_INFO_RECV";
-            case RIL_UNSOL_PCO_DATA:
-                return "UNSOL_PCO_DATA";
-            case RIL_UNSOL_MODEM_RESTART:
-                return "UNSOL_MODEM_RESTART";
-            case RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION:
-                return "UNSOL_CARRIER_INFO_IMSI_ENCRYPTION";
-            case RIL_UNSOL_NETWORK_SCAN_RESULT:
-                return "UNSOL_NETWORK_SCAN_RESULT";
-            case RIL_UNSOL_KEEPALIVE_STATUS:
-                return "UNSOL_KEEPALIVE_STATUS";
-            case RIL_UNSOL_UNTHROTTLE_APN:
-                return "UNSOL_UNTHROTTLE_APN";
-            case RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_CHANGED:
-                return "UNSOL_RESPONSE_SIM_PHONEBOOK_CHANGED";
-            case RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_RECORDS_RECEIVED:
-                return "UNSOL_RESPONSE_SIM_PHONEBOOK_RECORDS_RECEIVED";
-            case RIL_UNSOL_ICC_SLOT_STATUS:
-                return "UNSOL_ICC_SLOT_STATUS";
-            case RIL_UNSOL_PHYSICAL_CHANNEL_CONFIG:
-                return "UNSOL_PHYSICAL_CHANNEL_CONFIG";
-            case RIL_UNSOL_EMERGENCY_NUMBER_LIST:
-                return "UNSOL_EMERGENCY_NUMBER_LIST";
-            case RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED:
-                return "UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED";
-            case RIL_UNSOL_REGISTRATION_FAILED:
-                return "UNSOL_REGISTRATION_FAILED";
-            case RIL_UNSOL_BARRING_INFO_CHANGED:
-                return "UNSOL_BARRING_INFO_CHANGED";
-            default:
-                return "<unknown response>";
-        }
-    }
-
-    /**
-     * Create capabilities based off of the radio hal version and feature set configurations.
-     * @param radioHalVersion radio hal version
-     * @param modemReducedFeatureSet1 reduced feature set
-     * @return set of capabilities
-     */
-    @VisibleForTesting
-    public static Set<String> getCaps(HalVersion radioHalVersion, boolean modemReducedFeatureSet1) {
-        final Set<String> caps = new HashSet<>();
-
-        if (radioHalVersion.equals(RIL.RADIO_HAL_VERSION_UNKNOWN)) {
-            // If the Radio HAL is UNKNOWN, no capabilities will present themselves.
-            loge("Radio Hal Version is UNKNOWN!");
-        }
-
-        logd("Radio Hal Version = " + radioHalVersion.toString());
-        if (radioHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            caps.add(CAPABILITY_USES_ALLOWED_NETWORK_TYPES_BITMASK);
-            logd("CAPABILITY_USES_ALLOWED_NETWORK_TYPES_BITMASK");
-
-            if (!modemReducedFeatureSet1) {
-                caps.add(CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE);
-                logd("CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE");
-                caps.add(CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE);
-                logd("CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE");
-                caps.add(CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING);
-                logd("CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING");
-                caps.add(CAPABILITY_SLICING_CONFIG_SUPPORTED);
-                logd("CAPABILITY_SLICING_CONFIG_SUPPORTED");
-                caps.add(CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
-                logd("CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED");
-            } else {
-                caps.add(CAPABILITY_SIM_PHONEBOOK_IN_MODEM);
-                logd("CAPABILITY_SIM_PHONEBOOK_IN_MODEM");
-            }
-        }
-        return caps;
-    }
-
-    private static boolean isPrimitiveOrWrapper(Class c) {
-        return c.isPrimitive() || WRAPPER_CLASSES.contains(c);
-    }
-
-    /**
-     * Return a general String representation of a class
-     * @param o The object to convert to String
-     * @return A string containing all public non-static local variables of a class
-     */
-    public static String convertToString(Object o) {
-        boolean toStringExists = false;
-        try {
-            toStringExists = o.getClass().getMethod("toString").getDeclaringClass() != Object.class;
-        } catch (NoSuchMethodException e) {
-            loge(e.toString());
-        }
-        if (toStringExists || isPrimitiveOrWrapper(o.getClass()) || o instanceof ArrayList) {
-            return o.toString();
-        }
-        if (o.getClass().isArray()) {
-            // Special handling for arrays
-            StringBuilder sb = new StringBuilder("[");
-            boolean added = false;
-            if (isPrimitiveOrWrapper(o.getClass().getComponentType())) {
-                for (int i = 0; i < Array.getLength(o); i++) {
-                    sb.append(convertToString(Array.get(o, i))).append(", ");
-                    added = true;
-                }
-            } else {
-                for (Object element : (Object[]) o) {
-                    sb.append(convertToString(element)).append(", ");
-                    added = true;
-                }
-            }
-            if (added) {
-                // Remove extra ,
-                sb.delete(sb.length() - 2, sb.length());
-            }
-            sb.append("]");
-            return sb.toString();
-        }
-        StringBuilder sb = new StringBuilder(o.getClass().getSimpleName());
-        sb.append("{");
-        Field[] fields = o.getClass().getDeclaredFields();
-        int tag = -1;
-        try {
-            tag = (int) o.getClass().getDeclaredMethod("getTag").invoke(o);
-        } catch (IllegalAccessException | InvocationTargetException e) {
-            loge(e.toString());
-        } catch (NoSuchMethodException ignored) {
-            // Ignored since only unions have the getTag method
-        }
-        if (tag != -1) {
-            // Special handling for unions
-            String tagName = null;
-            try {
-                Method method = o.getClass().getDeclaredMethod("_tagString", int.class);
-                method.setAccessible(true);
-                tagName = (String) method.invoke(o, tag);
-            } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
-                loge(e.toString());
-            }
-            if (tagName != null) {
-                sb.append(tagName);
-                sb.append("=");
-                // From tag, create method name getTag
-                String getTagMethod = "get" + tagName.substring(0, 1).toUpperCase(Locale.ROOT)
-                        + tagName.substring(1);
-                Object val = null;
-                try {
-                    val = o.getClass().getDeclaredMethod(getTagMethod).invoke(o);
-                } catch (NoSuchMethodException | IllegalAccessException
-                        | InvocationTargetException e) {
-                    loge(e.toString());
-                }
-                if (val != null) {
-                    sb.append(convertToString(val));
-                }
-            }
-        } else {
-            boolean added = false;
-            for (Field field : fields) {
-                // Ignore static variables
-                if (Modifier.isStatic(field.getModifiers())) continue;
-                sb.append(field.getName()).append("=");
-                Object val = null;
-                try {
-                    val = field.get(o);
-                } catch (IllegalAccessException e) {
-                    loge(e.toString());
-                }
-                if (val == null) continue;
-                sb.append(convertToString(val)).append(", ");
-                added = true;
-            }
-            if (added) {
-                // Remove extra ,
-                sb.delete(sb.length() - 2, sb.length());
-            }
-        }
-        sb.append("}");
-        return sb.toString();
-    }
-
-    private static void logd(String log) {
-        Rlog.d("RILUtils", log);
-    }
-
-    private static void loge(String log) {
-        Rlog.e("RILUtils", log);
-    }
-}
diff --git a/src/java/com/android/internal/telephony/RadioBugDetector.java b/src/java/com/android/internal/telephony/RadioBugDetector.java
index bc4ddfd..9fe0172 100644
--- a/src/java/com/android/internal/telephony/RadioBugDetector.java
+++ b/src/java/com/android/internal/telephony/RadioBugDetector.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.telephony;
 
-import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
-
 import android.content.Context;
 import android.hardware.radio.V1_0.RadioError;
 import android.provider.Settings;
@@ -134,13 +132,10 @@
                     RADIO_BUG_REPETITIVE_WAKELOCK_TIMEOUT_ERROR;
             String message = "Repeated radio error " + mRadioBugStatus + " on slot " + mSlotId;
             Rlog.d(TAG, message);
-
-            Phone phone = PhoneFactory.getPhone(mSlotId);
-            int carrierId = phone == null ? UNKNOWN_CARRIER_ID : phone.getCarrierId();
             // Using fixed UUID to avoid duplicate bugreport notification
             AnomalyReporter.reportAnomaly(
                     UUID.fromString("d264ead0-3f05-11ea-b77f-2e728ce88125"),
-                    message, carrierId);
+                    message);
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/RadioConfig.java b/src/java/com/android/internal/telephony/RadioConfig.java
index 9ac03b1..32b24fe 100644
--- a/src/java/com/android/internal/telephony/RadioConfig.java
+++ b/src/java/com/android/internal/telephony/RadioConfig.java
@@ -29,18 +29,21 @@
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG;
 
 import android.content.Context;
+import android.hardware.radio.V1_0.RadioResponseInfo;
+import android.hardware.radio.V1_0.RadioResponseType;
+import android.hardware.radio.config.V1_0.IRadioConfig;
+import android.hardware.radio.config.V1_1.ModemsConfig;
 import android.os.AsyncResult;
 import android.os.Handler;
-import android.os.IBinder;
+import android.os.HwBinder;
 import android.os.Message;
 import android.os.Registrant;
 import android.os.RemoteException;
-import android.os.ServiceManager;
 import android.os.WorkSource;
 import android.telephony.TelephonyManager;
-import android.telephony.UiccSlotMapping;
 import android.util.SparseArray;
 
+import com.android.internal.telephony.uicc.IccSlotStatus;
 import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
@@ -55,39 +58,59 @@
 public class RadioConfig extends Handler {
     private static final String TAG = "RadioConfig";
     private static final boolean DBG = true;
-    private static final boolean VDBG = false; //STOPSHIP if true
-    private static final Object sLock = new Object();
+    private static final boolean VDBG = false;   //STOPSHIP if true
 
-    static final int EVENT_HIDL_SERVICE_DEAD = 1;
-    static final int EVENT_AIDL_SERVICE_DEAD = 2;
-    static final HalVersion RADIO_CONFIG_HAL_VERSION_UNKNOWN = new HalVersion(-1, -1);
-    static final HalVersion RADIO_CONFIG_HAL_VERSION_1_0 = new HalVersion(1, 0);
-    static final HalVersion RADIO_CONFIG_HAL_VERSION_1_1 = new HalVersion(1, 1);
-    static final HalVersion RADIO_CONFIG_HAL_VERSION_1_3 = new HalVersion(1, 3);
-    static final HalVersion RADIO_CONFIG_HAL_VERSION_2_0 = new HalVersion(2, 0);
+    private static final int EVENT_SERVICE_DEAD = 1;
+
+    private static final HalVersion RADIO_CONFIG_HAL_VERSION_UNKNOWN = new HalVersion(-1, -1);
+
+    private static final HalVersion RADIO_CONFIG_HAL_VERSION_1_0 = new HalVersion(1, 0);
+
+    private static final HalVersion RADIO_CONFIG_HAL_VERSION_1_1 = new HalVersion(1, 1);
+
+    private static final HalVersion RADIO_CONFIG_HAL_VERSION_1_3 = new HalVersion(1, 3);
 
     private final boolean mIsMobileNetworkSupported;
-    private final SparseArray<RILRequest> mRequestList = new SparseArray<>();
+    private volatile IRadioConfig mRadioConfigProxy = null;
+    // IRadioConfig version
+    private HalVersion mRadioConfigVersion = RADIO_CONFIG_HAL_VERSION_UNKNOWN;
+    private final ServiceDeathRecipient mServiceDeathRecipient;
+    private final AtomicLong mRadioConfigProxyCookie = new AtomicLong(0);
+    private final RadioConfigResponse mRadioConfigResponse;
+    private final RadioConfigIndication mRadioConfigIndication;
+    private final SparseArray<RILRequest> mRequestList = new SparseArray<RILRequest>();
     /* default work source which will blame phone process */
     private final WorkSource mDefaultWorkSource;
     private final int[] mDeviceNrCapabilities;
-    private final AtomicLong mRadioConfigProxyCookie = new AtomicLong(0);
-    private final RadioConfigProxy mRadioConfigProxy;
-    private MockModem mMockModem;
-    private static Context sContext;
-
     private static RadioConfig sRadioConfig;
+    private static final Object sLock = new Object();
 
     protected Registrant mSimSlotStatusRegistrant;
 
+    final class ServiceDeathRecipient implements HwBinder.DeathRecipient {
+        @Override
+        public void serviceDied(long cookie) {
+            // Deal with service going away
+            logd("serviceDied");
+            sendMessage(obtainMessage(EVENT_SERVICE_DEAD, cookie));
+        }
+    }
+
     private boolean isMobileDataCapable(Context context) {
         final TelephonyManager tm = context.getSystemService(TelephonyManager.class);
-        return tm != null && tm.isDataCapable();
+        if (tm == null) {
+            return false;
+        }
+        return tm.isDataCapable();
     }
 
     private RadioConfig(Context context, HalVersion radioHalVersion) {
         mIsMobileNetworkSupported = isMobileDataCapable(context);
-        mRadioConfigProxy = new RadioConfigProxy(this, radioHalVersion);
+
+        mRadioConfigResponse = new RadioConfigResponse(this, radioHalVersion);
+        mRadioConfigIndication = new RadioConfigIndication(this);
+        mServiceDeathRecipient = new ServiceDeathRecipient();
+
         mDefaultWorkSource = new WorkSource(context.getApplicationInfo().uid,
                 context.getPackageName());
 
@@ -131,7 +154,6 @@
             if (sRadioConfig != null) {
                 throw new RuntimeException("RadioConfig.make() should only be called once");
             }
-            sContext = c;
             sRadioConfig = new RadioConfig(c, radioHalVersion);
             return sRadioConfig;
         }
@@ -139,16 +161,14 @@
 
     @Override
     public void handleMessage(Message message) {
-        if (message.what == EVENT_HIDL_SERVICE_DEAD) {
-            logd("handleMessage: EVENT_HIDL_SERVICE_DEAD cookie = " + message.obj
-                    + " mRadioConfigProxyCookie = " + mRadioConfigProxyCookie.get());
-            if ((long) message.obj == mRadioConfigProxyCookie.get()) {
-                resetProxyAndRequestList("EVENT_HIDL_SERVICE_DEAD", null);
-            }
-        } else if (message.what == EVENT_AIDL_SERVICE_DEAD) {
-            logd("handleMessage: EVENT_AIDL_SERVICE_DEAD mRadioConfigProxyCookie = "
-                    + mRadioConfigProxyCookie.get());
-            resetProxyAndRequestList("EVENT_AIDL_SERVICE_DEAD", null);
+        switch (message.what) {
+            case EVENT_SERVICE_DEAD:
+                logd("handleMessage: EVENT_SERVICE_DEAD cookie = " + message.obj
+                        + " mRadioConfigProxyCookie = " + mRadioConfigProxyCookie.get());
+                if ((long) message.obj == mRadioConfigProxyCookie.get()) {
+                    resetProxyAndRequestList("EVENT_SERVICE_DEAD", null);
+                }
+                break;
         }
     }
 
@@ -168,7 +188,7 @@
             for (int i = 0; i < count; i++) {
                 rr = mRequestList.valueAt(i);
                 if (DBG && loggable) {
-                    logd(i + ": [" + rr.mSerial + "] " + RILUtils.requestToString(rr.mRequest));
+                    logd(i + ": [" + rr.mSerial + "] " + requestToString(rr.mRequest));
                 }
                 rr.onError(error, null);
                 rr.release();
@@ -179,7 +199,7 @@
 
     private void resetProxyAndRequestList(String caller, Exception e) {
         loge(caller + ": " + e);
-        mRadioConfigProxy.clear();
+        mRadioConfigProxy = null;
 
         // increment the cookie so that death notification can be ignored
         mRadioConfigProxyCookie.incrementAndGet();
@@ -191,13 +211,8 @@
         getRadioConfigProxy(null);
     }
 
-    /**
-     * Returns a holder that has either:
-     * - getV1() -> {@link android.hardware.radio.config.V1_0.IRadioConfig}
-     * - getV2() -> {@link android.hardware.radio.config.IRadioConfig}
-     * that returns corresponding hal implementation
-     */
-    public RadioConfigProxy getRadioConfigProxy(Message result) {
+    /** Returns a {@link IRadioConfig} instance or null if the service is not available. */
+    public IRadioConfig getRadioConfigProxy(Message result) {
         if (!mIsMobileNetworkSupported) {
             if (VDBG) logd("getRadioConfigProxy: Not calling getService(): wifi-only");
             if (result != null) {
@@ -205,139 +220,72 @@
                         CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
                 result.sendToTarget();
             }
-            mRadioConfigProxy.clear();
-            return mRadioConfigProxy;
+            return null;
         }
 
-        if (!mRadioConfigProxy.isEmpty()) {
+        if (mRadioConfigProxy != null) {
             return mRadioConfigProxy;
         }
 
         updateRadioConfigProxy();
 
-        if (mRadioConfigProxy.isEmpty() && result != null) {
-            AsyncResult.forMessage(
-                    result, null, CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
-            result.sendToTarget();
+        if (mRadioConfigProxy == null) {
+            if (result != null) {
+                AsyncResult.forMessage(result, null,
+                        CommandException.fromRilErrno(RADIO_NOT_AVAILABLE));
+                result.sendToTarget();
+            }
         }
 
         return mRadioConfigProxy;
     }
 
-    /**
-     * Request to enable/disable the mock modem service.
-     * This is invoked from shell commands during CTS testing only.
-     *
-     * @param serviceName the service name we want to bind to
-     */
-    public boolean setModemService(String serviceName) {
-        boolean serviceBound = true;
-
-        if (serviceName != null) {
-            logd("Overriding connected service to MockModemService");
-            mMockModem = null;
-
-            mMockModem = new MockModem(sContext, serviceName);
-            if (mMockModem == null) {
-                loge("MockModem creation failed.");
-                return false;
-            }
-
-            mMockModem.bindToMockModemService(MockModem.RADIOCONFIG_SERVICE);
-
-            int retryCount = 0;
-            IBinder binder;
-            do {
-                binder = mMockModem.getServiceBinder(MockModem.RADIOCONFIG_SERVICE);
-
-                retryCount++;
-                if (binder == null) {
-                    logd("Retry(" + retryCount + ") Mock RadioConfig");
-                    try {
-                        Thread.sleep(MockModem.BINDER_RETRY_MILLIS);
-                    } catch (InterruptedException e) {
-                    }
-                }
-            } while ((binder == null) && (retryCount < MockModem.BINDER_MAX_RETRY));
-
-            if (binder == null) {
-                loge("Mock RadioConfig bind fail");
-                serviceBound = false;
-            }
-
-            if (serviceBound) resetProxyAndRequestList("EVENT_HIDL_SERVICE_DEAD", null);
-        }
-
-        if ((serviceName == null) || (!serviceBound)) {
-            if (serviceBound) logd("Unbinding to mock RadioConfig service");
-
-            if (mMockModem != null) {
-                mMockModem = null;
-                resetProxyAndRequestList("EVENT_AIDL_SERVICE_DEAD", null);
-            }
-        }
-
-        return serviceBound;
-    }
-
     private void updateRadioConfigProxy() {
-        IBinder service;
-        if (mMockModem == null) {
-            service = ServiceManager.waitForDeclaredService(
-                android.hardware.radio.config.IRadioConfig.DESCRIPTOR + "/default");
-        } else {
-            // Binds to Mock RadioConfig Service
-            service = mMockModem.getServiceBinder(MockModem.RADIOCONFIG_SERVICE);
-        }
+        try {
 
-        if (service != null) {
-            mRadioConfigProxy.setAidl(
-                    RADIO_CONFIG_HAL_VERSION_2_0,
-                    android.hardware.radio.config.IRadioConfig.Stub.asInterface(service));
-        }
-
-        if (mRadioConfigProxy.isEmpty()) {
+            // Try to get service from different versions.
             try {
-                mRadioConfigProxy.setHidl(RADIO_CONFIG_HAL_VERSION_1_3,
-                        android.hardware.radio.config.V1_3.IRadioConfig.getService(true));
-            } catch (RemoteException | NoSuchElementException e) {
-                mRadioConfigProxy.clear();
-                loge("getHidlRadioConfigProxy1_3: RadioConfigProxy getService: " + e);
+                mRadioConfigProxy = android.hardware.radio.config.V1_3.IRadioConfig.getService(
+                        true);
+                mRadioConfigVersion = RADIO_CONFIG_HAL_VERSION_1_3;
+            } catch (NoSuchElementException e) {
             }
-        }
 
-        if (mRadioConfigProxy.isEmpty()) {
-            try {
-                mRadioConfigProxy.setHidl(RADIO_CONFIG_HAL_VERSION_1_1,
-                        android.hardware.radio.config.V1_1.IRadioConfig.getService(true));
-            } catch (RemoteException | NoSuchElementException e) {
-                mRadioConfigProxy.clear();
-                loge("getHidlRadioConfigProxy1_1: RadioConfigProxy getService | linkToDeath: " + e);
+
+            if (mRadioConfigProxy == null) {
+                // Try to get service from different versions.
+                try {
+                    mRadioConfigProxy = android.hardware.radio.config.V1_1.IRadioConfig.getService(
+                            true);
+                    mRadioConfigVersion = RADIO_CONFIG_HAL_VERSION_1_1;
+                } catch (NoSuchElementException e) {
+                }
             }
-        }
 
-        if (mRadioConfigProxy.isEmpty()) {
-            try {
-                mRadioConfigProxy.setHidl(RADIO_CONFIG_HAL_VERSION_1_0,
-                        android.hardware.radio.config.V1_0.IRadioConfig.getService(true));
-            } catch (RemoteException | NoSuchElementException e) {
-                mRadioConfigProxy.clear();
-                loge("getHidlRadioConfigProxy1_0: RadioConfigProxy getService | linkToDeath: " + e);
+            if (mRadioConfigProxy == null) {
+                try {
+                    mRadioConfigProxy = android.hardware.radio.config.V1_0
+                            .IRadioConfig.getService(true);
+                    mRadioConfigVersion = RADIO_CONFIG_HAL_VERSION_1_0;
+                } catch (NoSuchElementException e) {
+                }
             }
-        }
 
-        if (!mRadioConfigProxy.isEmpty()) {
-            try {
-                mRadioConfigProxy.linkToDeath(mRadioConfigProxyCookie.incrementAndGet());
-                mRadioConfigProxy.setResponseFunctions(this);
+            if (mRadioConfigProxy == null) {
+                loge("getRadioConfigProxy: mRadioConfigProxy == null");
                 return;
-            } catch (RemoteException e) {
-                mRadioConfigProxy.clear();
-                loge("RadioConfigProxy: failed to linkToDeath() or setResponseFunction()");
             }
-        }
 
-        loge("getRadioConfigProxy: mRadioConfigProxy == null");
+            // Link to death recipient and set response. If fails, set proxy to null and return.
+            mRadioConfigProxy.linkToDeath(mServiceDeathRecipient,
+                    mRadioConfigProxyCookie.incrementAndGet());
+            mRadioConfigProxy.setResponseFunctions(mRadioConfigResponse,
+                    mRadioConfigIndication);
+        } catch (RemoteException | RuntimeException e) {
+            mRadioConfigProxy = null;
+            loge("getRadioConfigProxy: RadioConfigProxy setResponseFunctions: " + e);
+            return;
+        }
     }
 
     private RILRequest obtainRequest(int request, Message result, WorkSource workSource) {
@@ -366,36 +314,12 @@
      * @param responseInfo RadioResponseInfo received in response callback
      * @return RILRequest corresponding to the response
      */
-    public RILRequest processResponse(android.hardware.radio.RadioResponseInfo responseInfo) {
+    public RILRequest processResponse(RadioResponseInfo responseInfo) {
         int serial = responseInfo.serial;
         int error = responseInfo.error;
         int type = responseInfo.type;
 
-        if (type != android.hardware.radio.RadioResponseType.SOLICITED) {
-            loge("processResponse: Unexpected response type " + type);
-        }
-
-        RILRequest rr = findAndRemoveRequestFromList(serial);
-        if (rr == null) {
-            loge("processResponse: Unexpected response! serial: " + serial + " error: " + error);
-            return null;
-        }
-
-        return rr;
-    }
-
-    /**
-     * This is a helper function to be called when a RadioConfigResponse callback is called.
-     * It finds and returns RILRequest corresponding to the response if one is found.
-     * @param responseInfo RadioResponseInfo received in response callback
-     * @return RILRequest corresponding to the response
-     */
-    public RILRequest processResponse(android.hardware.radio.V1_0.RadioResponseInfo responseInfo) {
-        int serial = responseInfo.serial;
-        int error = responseInfo.error;
-        int type = responseInfo.type;
-
-        if (type != android.hardware.radio.RadioResponseType.SOLICITED) {
+        if (type != RadioResponseType.SOLICITED) {
             loge("processResponse: Unexpected response type " + type);
         }
 
@@ -419,7 +343,8 @@
         int serial = responseInfo.serial;
         int error = responseInfo.error;
         int type = responseInfo.type;
-        if (type != android.hardware.radio.RadioResponseType.SOLICITED) {
+
+        if (type != RadioResponseType.SOLICITED) {
             loge("processResponse: Unexpected response type " + type);
         }
 
@@ -436,17 +361,19 @@
      * Wrapper function for IRadioConfig.getSimSlotsStatus().
      */
     public void getSimSlotsStatus(Message result) {
-        RadioConfigProxy proxy = getRadioConfigProxy(result);
-        if (proxy.isEmpty()) return;
+        IRadioConfig radioConfigProxy = getRadioConfigProxy(result);
+        if (radioConfigProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_GET_SLOT_STATUS, result, mDefaultWorkSource);
 
-        RILRequest rr = obtainRequest(RIL_REQUEST_GET_SLOT_STATUS, result, mDefaultWorkSource);
-        if (DBG) {
-            logd(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-        }
-        try {
-            proxy.getSimSlotStatus(rr.mSerial);
-        } catch (RemoteException | RuntimeException e) {
-            resetProxyAndRequestList("getSimSlotsStatus", e);
+            if (DBG) {
+                logd(rr.serialString() + "> " + requestToString(rr.mRequest));
+            }
+
+            try {
+                radioConfigProxy.getSimSlotsStatus(rr.mSerial);
+            } catch (RemoteException | RuntimeException e) {
+                resetProxyAndRequestList("getSimSlotsStatus", e);
+            }
         }
     }
 
@@ -454,9 +381,6 @@
      * Wrapper function for IRadioConfig.setPreferredDataModem(int modemId).
      */
     public void setPreferredDataModem(int modemId, Message result) {
-        RadioConfigProxy proxy = getRadioConfigProxy(null);
-        if (proxy.isEmpty()) return;
-
         if (!isSetPreferredDataCommandSupported()) {
             if (result != null) {
                 AsyncResult.forMessage(result, null,
@@ -468,11 +392,14 @@
 
         RILRequest rr = obtainRequest(RIL_REQUEST_SET_PREFERRED_DATA_MODEM,
                 result, mDefaultWorkSource);
+
         if (DBG) {
-            logd(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+            logd(rr.serialString() + "> " + requestToString(rr.mRequest));
         }
+
         try {
-            proxy.setPreferredDataModem(rr.mSerial, modemId);
+            ((android.hardware.radio.config.V1_1.IRadioConfig) mRadioConfigProxy)
+                    .setPreferredDataModem(rr.mSerial, (byte) modemId);
         } catch (RemoteException | RuntimeException e) {
             resetProxyAndRequestList("setPreferredDataModem", e);
         }
@@ -482,10 +409,8 @@
      * Wrapper function for IRadioConfig.getPhoneCapability().
      */
     public void getPhoneCapability(Message result) {
-        RadioConfigProxy proxy = getRadioConfigProxy(null);
-        if (proxy.isEmpty()) return;
-
-        if (proxy.getVersion().less(RADIO_CONFIG_HAL_VERSION_1_1)) {
+        IRadioConfig radioConfigProxy = getRadioConfigProxy(null);
+        if (radioConfigProxy == null || mRadioConfigVersion.less(RADIO_CONFIG_HAL_VERSION_1_1)) {
             if (result != null) {
                 AsyncResult.forMessage(result, null,
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
@@ -495,11 +420,14 @@
         }
 
         RILRequest rr = obtainRequest(RIL_REQUEST_GET_PHONE_CAPABILITY, result, mDefaultWorkSource);
+
         if (DBG) {
-            logd(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
+            logd(rr.serialString() + "> " + requestToString(rr.mRequest));
         }
+
         try {
-            proxy.getPhoneCapability(rr.mSerial);
+            ((android.hardware.radio.config.V1_1.IRadioConfig) mRadioConfigProxy)
+                    .getPhoneCapability(rr.mSerial);
         } catch (RemoteException | RuntimeException e) {
             resetProxyAndRequestList("getPhoneCapability", e);
         }
@@ -512,60 +440,92 @@
      * See PhoneSwitcher for more details.
      */
     public boolean isSetPreferredDataCommandSupported() {
-        RadioConfigProxy proxy = getRadioConfigProxy(null);
-        return !proxy.isEmpty() && proxy.getVersion().greaterOrEqual(RADIO_CONFIG_HAL_VERSION_1_1);
+        IRadioConfig radioConfigProxy = getRadioConfigProxy(null);
+        return radioConfigProxy != null && mRadioConfigVersion
+                .greaterOrEqual(RADIO_CONFIG_HAL_VERSION_1_1);
     }
 
     /**
      * Wrapper function for IRadioConfig.setSimSlotsMapping(int32_t serial, vec<uint32_t> slotMap).
      */
-    public void setSimSlotsMapping(List<UiccSlotMapping> slotMapping, Message result) {
-        RadioConfigProxy proxy = getRadioConfigProxy(result);
-        if (proxy.isEmpty()) return;
+    public void setSimSlotsMapping(int[] physicalSlots, Message result) {
+        IRadioConfig radioConfigProxy = getRadioConfigProxy(result);
+        if (radioConfigProxy != null) {
+            RILRequest rr = obtainRequest(RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING, result,
+                    mDefaultWorkSource);
 
-        RILRequest rr = obtainRequest(RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING, result,
-                mDefaultWorkSource);
-        if (DBG) {
-            logd(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest) + " "
-                    + slotMapping);
+            if (DBG) {
+                logd(rr.serialString() + "> " + requestToString(rr.mRequest)
+                        + " " + Arrays.toString(physicalSlots));
+            }
+
+            try {
+                radioConfigProxy.setSimSlotsMapping(rr.mSerial,
+                        primitiveArrayToArrayList(physicalSlots));
+            } catch (RemoteException | RuntimeException e) {
+                resetProxyAndRequestList("setSimSlotsMapping", e);
+            }
         }
-        try {
-            proxy.setSimSlotsMapping(rr.mSerial, slotMapping);
-        } catch (RemoteException | RuntimeException e) {
-            resetProxyAndRequestList("setSimSlotsMapping", e);
+    }
+
+    private static ArrayList<Integer> primitiveArrayToArrayList(int[] arr) {
+        ArrayList<Integer> arrayList = new ArrayList<>(arr.length);
+        for (int i : arr) {
+            arrayList.add(i);
+        }
+        return arrayList;
+    }
+
+    static String requestToString(int request) {
+        switch (request) {
+            case RIL_REQUEST_GET_PHONE_CAPABILITY:
+                return "GET_PHONE_CAPABILITY";
+            case RIL_REQUEST_GET_SLOT_STATUS:
+                return "GET_SLOT_STATUS";
+            case RIL_REQUEST_SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING:
+                return "SET_LOGICAL_TO_PHYSICAL_SLOT_MAPPING";
+            case RIL_REQUEST_SET_PREFERRED_DATA_MODEM:
+                return "SET_PREFERRED_DATA_MODEM";
+            case RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG:
+                return "SWITCH_DUAL_SIM_CONFIG";
+            case RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES:
+                return "GET_HAL_DEVICE_CAPABILITIES";
+            default:
+                return "<unknown request " + request + ">";
         }
     }
 
     /**
-     * Wrapper function for using IRadioConfig.setNumOfLiveModems(int32_t serial,
-     * byte numOfLiveModems) to switch between single-sim and multi-sim.
+     * Wrapper function for using IRadioConfig.setModemsConfig(int32_t serial,
+     * ModemsConfig modemsConfig) to switch between single-sim and multi-sim.
      */
-    public void setNumOfLiveModems(int numOfLiveModems, Message result) {
-        RadioConfigProxy proxy = getRadioConfigProxy(result);
-        if (proxy.isEmpty()) return;
+    public void setModemsConfig(int numOfLiveModems, Message result) {
+        IRadioConfig radioConfigProxy = getRadioConfigProxy(result);
+        if (radioConfigProxy != null
+                && mRadioConfigVersion.greaterOrEqual(RADIO_CONFIG_HAL_VERSION_1_1)) {
+            android.hardware.radio.config.V1_1.IRadioConfig radioConfigProxy11 =
+                    (android.hardware.radio.config.V1_1.IRadioConfig) radioConfigProxy;
+            RILRequest rr = obtainRequest(RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG,
+                    result, mDefaultWorkSource);
 
-        if (proxy.getVersion().less(RADIO_CONFIG_HAL_VERSION_1_1)) {
-            if (result != null) {
-                AsyncResult.forMessage(
-                        result, null, CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                result.sendToTarget();
+            if (DBG) {
+                logd(rr.serialString() + "> " + requestToString(rr.mRequest)
+                        + ", numOfLiveModems = " + numOfLiveModems);
             }
-            return;
-        }
 
-        RILRequest rr = obtainRequest(RIL_REQUEST_SWITCH_DUAL_SIM_CONFIG,
-                result, mDefaultWorkSource);
-        if (DBG) {
-            logd(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest)
-                    + ", numOfLiveModems = " + numOfLiveModems);
-        }
-        try {
-            proxy.setNumOfLiveModems(rr.mSerial, numOfLiveModems);
-        } catch (RemoteException | RuntimeException e) {
-            resetProxyAndRequestList("setNumOfLiveModems", e);
+            try {
+                ModemsConfig modemsConfig = new ModemsConfig();
+                modemsConfig.numOfLiveModems = (byte) numOfLiveModems;
+                radioConfigProxy11.setModemsConfig(rr.mSerial, modemsConfig);
+            } catch (RemoteException | RuntimeException e) {
+                resetProxyAndRequestList("setModemsConfig", e);
+            }
         }
     }
 
+    // TODO: not needed for now, but if we don't want to use System Properties any more,
+    // we need to implement a wrapper function for getModemsConfig as well
+
     /**
      * Register a handler to get SIM slot status changed notifications.
      */
@@ -587,10 +547,26 @@
      * Gets the hal capabilities from the device.
      */
     public void getHalDeviceCapabilities(Message result) {
-        RadioConfigProxy proxy = getRadioConfigProxy(Message.obtain(result));
-        if (proxy.isEmpty()) return;
+        IRadioConfig radioConfigProxy = getRadioConfigProxy(Message.obtain(result));
+        if (radioConfigProxy != null
+                && mRadioConfigVersion.greaterOrEqual(RADIO_CONFIG_HAL_VERSION_1_3)) {
+            android.hardware.radio.config.V1_3.IRadioConfig radioConfigProxy13 =
+                    (android.hardware.radio.config.V1_3.IRadioConfig) radioConfigProxy;
+            RILRequest rr = obtainRequest(RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES,
+                    result, mDefaultWorkSource);
 
-        if (proxy.getVersion().less(RADIO_CONFIG_HAL_VERSION_1_3)) {
+            if (DBG) {
+                logd(rr.serialString() + "> " + requestToString(rr.mRequest));
+            }
+
+            try {
+                mRadioConfigVersion = RADIO_CONFIG_HAL_VERSION_1_3;
+                radioConfigProxy13.getHalDeviceCapabilities(rr.mSerial);
+
+            } catch (RemoteException | RuntimeException e) {
+                resetProxyAndRequestList("getHalDeviceCapabilities", e);
+            }
+        } else {
             if (result != null) {
                 if (DBG) {
                     logd("RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES > REQUEST_NOT_SUPPORTED");
@@ -598,7 +574,7 @@
                 AsyncResult.forMessage(result,
                         /* Send response such that all capabilities are supported (depending on
                            the hal version of course.) */
-                        proxy.getFullCapabilitySet(),
+                        mRadioConfigResponse.getFullCapabilitySet(),
                         CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
                 result.sendToTarget();
             } else {
@@ -607,18 +583,6 @@
                             + "on complete message not set.");
                 }
             }
-            return;
-        }
-
-        RILRequest rr = obtainRequest(RIL_REQUEST_GET_HAL_DEVICE_CAPABILITIES,
-                result, mDefaultWorkSource);
-        if (DBG) {
-            logd(rr.serialString() + "> " + RILUtils.requestToString(rr.mRequest));
-        }
-        try {
-            proxy.getHalDeviceCapabilities(rr.mSerial);
-        } catch (RemoteException | RuntimeException e) {
-            resetProxyAndRequestList("getHalDeviceCapabilities", e);
         }
     }
 
@@ -629,6 +593,37 @@
         return mDeviceNrCapabilities;
     }
 
+    static ArrayList<IccSlotStatus> convertHalSlotStatus(
+            ArrayList<android.hardware.radio.config.V1_0.SimSlotStatus> halSlotStatusList) {
+        ArrayList<IccSlotStatus> response = new ArrayList<IccSlotStatus>(halSlotStatusList.size());
+        for (android.hardware.radio.config.V1_0.SimSlotStatus slotStatus : halSlotStatusList) {
+            IccSlotStatus iccSlotStatus = new IccSlotStatus();
+            iccSlotStatus.setCardState(slotStatus.cardState);
+            iccSlotStatus.setSlotState(slotStatus.slotState);
+            iccSlotStatus.logicalSlotIndex = slotStatus.logicalSlotId;
+            iccSlotStatus.atr = slotStatus.atr;
+            iccSlotStatus.iccid = slotStatus.iccid;
+            response.add(iccSlotStatus);
+        }
+        return response;
+    }
+
+    static ArrayList<IccSlotStatus> convertHalSlotStatus_1_2(
+            ArrayList<android.hardware.radio.config.V1_2.SimSlotStatus> halSlotStatusList) {
+        ArrayList<IccSlotStatus> response = new ArrayList<IccSlotStatus>(halSlotStatusList.size());
+        for (android.hardware.radio.config.V1_2.SimSlotStatus slotStatus : halSlotStatusList) {
+            IccSlotStatus iccSlotStatus = new IccSlotStatus();
+            iccSlotStatus.setCardState(slotStatus.base.cardState);
+            iccSlotStatus.setSlotState(slotStatus.base.slotState);
+            iccSlotStatus.logicalSlotIndex = slotStatus.base.logicalSlotId;
+            iccSlotStatus.atr = slotStatus.base.atr;
+            iccSlotStatus.iccid = slotStatus.base.iccid;
+            iccSlotStatus.eid = slotStatus.eid;
+            response.add(iccSlotStatus);
+        }
+        return response;
+    }
+
     private static void logd(String log) {
         Rlog.d(TAG, log);
     }
diff --git a/src/java/com/android/internal/telephony/RadioConfigIndicationHidl.java b/src/java/com/android/internal/telephony/RadioConfigIndication.java
similarity index 71%
rename from src/java/com/android/internal/telephony/RadioConfigIndicationHidl.java
rename to src/java/com/android/internal/telephony/RadioConfigIndication.java
index 23a676b..639272c 100644
--- a/src/java/com/android/internal/telephony/RadioConfigIndicationHidl.java
+++ b/src/java/com/android/internal/telephony/RadioConfigIndication.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony;
 
+import android.hardware.radio.config.V1_2.IRadioConfigIndication;
 import android.os.AsyncResult;
 
 import com.android.internal.telephony.uicc.IccSlotStatus;
@@ -24,15 +25,13 @@
 import java.util.ArrayList;
 
 /**
- * This class is the HIDL implementation of IRadioConfigIndication interface.
+ * This class is the implementation of IRadioConfigIndication interface.
  */
-public class RadioConfigIndicationHidl extends
-        android.hardware.radio.config.V1_2.IRadioConfigIndication.Stub {
-    private static final String TAG = "RadioConfigIndicationHidl";
-
+public class RadioConfigIndication extends IRadioConfigIndication.Stub {
     private final RadioConfig mRadioConfig;
+    private static final String TAG = "RadioConfigIndication";
 
-    public RadioConfigIndicationHidl(RadioConfig radioConfig) {
+    public RadioConfigIndication(RadioConfig radioConfig) {
         mRadioConfig = radioConfig;
     }
 
@@ -41,8 +40,8 @@
      */
     public void simSlotsStatusChanged(int indicationType,
             ArrayList<android.hardware.radio.config.V1_0.SimSlotStatus> slotStatus) {
-        ArrayList<IccSlotStatus> ret = RILUtils.convertHalSlotStatus(slotStatus);
-        logd("[UNSL]< UNSOL_SIM_SLOT_STATUS_CHANGED " + ret.toString());
+        ArrayList<IccSlotStatus> ret = RadioConfig.convertHalSlotStatus(slotStatus);
+        Rlog.d(TAG, "[UNSL]< " + " UNSOL_SIM_SLOT_STATUS_CHANGED " + ret.toString());
         if (mRadioConfig.mSimSlotStatusRegistrant != null) {
             mRadioConfig.mSimSlotStatusRegistrant.notifyRegistrant(
                     new AsyncResult(null, ret, null));
@@ -54,15 +53,11 @@
      */
     public void simSlotsStatusChanged_1_2(int indicationType,
             ArrayList<android.hardware.radio.config.V1_2.SimSlotStatus> slotStatus) {
-        ArrayList<IccSlotStatus> ret = RILUtils.convertHalSlotStatus(slotStatus);
-        logd("[UNSL]< UNSOL_SIM_SLOT_STATUS_CHANGED " + ret.toString());
+        ArrayList<IccSlotStatus> ret = RadioConfig.convertHalSlotStatus_1_2(slotStatus);
+        Rlog.d(TAG, "[UNSL]< " + " UNSOL_SIM_SLOT_STATUS_CHANGED " + ret.toString());
         if (mRadioConfig.mSimSlotStatusRegistrant != null) {
             mRadioConfig.mSimSlotStatusRegistrant.notifyRegistrant(
                     new AsyncResult(null, ret, null));
         }
     }
-
-    private static void logd(String log) {
-        Rlog.d(TAG, log);
-    }
 }
diff --git a/src/java/com/android/internal/telephony/RadioConfigIndicationAidl.java b/src/java/com/android/internal/telephony/RadioConfigIndicationAidl.java
deleted file mode 100644
index 851a8ef..0000000
--- a/src/java/com/android/internal/telephony/RadioConfigIndicationAidl.java
+++ /dev/null
@@ -1,66 +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 com.android.internal.telephony;
-
-import android.os.AsyncResult;
-
-import com.android.internal.telephony.uicc.IccSlotStatus;
-import com.android.telephony.Rlog;
-
-import java.util.ArrayList;
-
-/**
- * This class is the AIDL implementation of IRadioConfigIndication interface.
- */
-public class RadioConfigIndicationAidl extends
-        android.hardware.radio.config.IRadioConfigIndication.Stub {
-    private static final String TAG = "RadioConfigIndicationAidl";
-
-    private final RadioConfig mRadioConfig;
-
-    public RadioConfigIndicationAidl(RadioConfig radioConfig) {
-        mRadioConfig = radioConfig;
-    }
-
-    /**
-     * Unsolicited indication for slot status changed
-     */
-    @Override
-    public void simSlotsStatusChanged(
-            int type, android.hardware.radio.config.SimSlotStatus[] slotStatus) {
-        ArrayList<IccSlotStatus> ret = RILUtils.convertHalSlotStatus(slotStatus);
-        logd("[UNSL]< UNSOL_SIM_SLOT_STATUS_CHANGED " + ret.toString());
-        if (mRadioConfig.mSimSlotStatusRegistrant != null) {
-            mRadioConfig.mSimSlotStatusRegistrant.notifyRegistrant(
-                    new AsyncResult(null, ret, null));
-        }
-    }
-
-    private static void logd(String log) {
-        Rlog.d(TAG, log);
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return android.hardware.radio.config.IRadioConfigIndication.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return android.hardware.radio.config.IRadioConfigIndication.VERSION;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/RadioConfigProxy.java b/src/java/com/android/internal/telephony/RadioConfigProxy.java
deleted file mode 100644
index a8601f1..0000000
--- a/src/java/com/android/internal/telephony/RadioConfigProxy.java
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.os.HwBinder;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.telephony.UiccSlotMapping;
-
-import com.android.telephony.Rlog;
-
-import java.util.List;
-import java.util.Set;
-
-/**
- * RadioConfig proxy class that abstracts the underlying RadioConfig service implementation to
- * downstream users.
- */
-public class RadioConfigProxy {
-    private final HalVersion mRadioHalVersion;
-    private final RadioConfigHidlServiceDeathRecipient mRadioConfigHidlServiceDeathRecipient;
-    private final RadioConfigAidlServiceDeathRecipient mRadioConfigAidlServiceDeathRecipient;
-
-    private volatile android.hardware.radio.config.V1_0.IRadioConfig mHidlRadioConfigProxy = null;
-    private volatile android.hardware.radio.config.IRadioConfig mAidlRadioConfigProxy = null;
-
-    private HalVersion mRadioConfigHalVersion = RadioConfig.RADIO_CONFIG_HAL_VERSION_UNKNOWN;
-    private boolean mIsAidl;
-
-    public RadioConfigProxy(RadioConfig radioConfig, HalVersion radioHalVersion) {
-        mRadioHalVersion = radioHalVersion;
-        mRadioConfigAidlServiceDeathRecipient =
-                new RadioConfigAidlServiceDeathRecipient(radioConfig);
-        mRadioConfigHidlServiceDeathRecipient =
-                new RadioConfigHidlServiceDeathRecipient(radioConfig);
-    }
-
-    /**
-     * Set IRadioConfig as the HIDL implementation for RadioConfigProxy
-     *
-     * @param radioConfigHalVersion RadioConfig HAL version
-     * @param radioConfig IRadioConfig implementation
-     */
-    public void setHidl(
-            HalVersion radioConfigHalVersion,
-            android.hardware.radio.config.V1_0.IRadioConfig radioConfig) {
-        mRadioConfigHalVersion = radioConfigHalVersion;
-        mHidlRadioConfigProxy = radioConfig;
-        mIsAidl = false;
-        mRadioConfigHidlServiceDeathRecipient.setService(radioConfig);
-    }
-
-    /**
-     * Get HIDL IRadioConfig V1_0
-     * @return IRadioConfigV1_0
-     */
-    public android.hardware.radio.config.V1_0.IRadioConfig getHidl10() {
-        return mHidlRadioConfigProxy;
-    }
-
-    /**
-     * Get HIDL IRadioConfig V1_1
-     * @return IRadioConfigV1_1
-     */
-    public android.hardware.radio.config.V1_1.IRadioConfig getHidl11() {
-        return (android.hardware.radio.config.V1_1.IRadioConfig) mHidlRadioConfigProxy;
-    }
-
-    /**
-     * Get HIDL IRadioConfig V1_3
-     * @return IRadioConfigV1_3
-     */
-    public android.hardware.radio.config.V1_3.IRadioConfig getHidl13() {
-        return (android.hardware.radio.config.V1_3.IRadioConfig) mHidlRadioConfigProxy;
-    }
-
-    /**
-     * Set IRadioConfig as the AIDL implementation for RadioConfigProxy
-     *
-     * @param radioConfigHalVersion RadioConfig HAL version
-     * @param radioConfig IRadioConfig implementation
-     */
-    public void setAidl(
-            HalVersion radioConfigHalVersion,
-            android.hardware.radio.config.IRadioConfig radioConfig) {
-        mRadioConfigHalVersion = radioConfigHalVersion;
-        mAidlRadioConfigProxy = radioConfig;
-        mIsAidl = true;
-        mRadioConfigAidlServiceDeathRecipient.setService(radioConfig.asBinder());
-    }
-
-    /**
-     * Get the AIDL implementation of RadioConfigProxy
-     *
-     * @return IRadio implementation
-     */
-    public android.hardware.radio.config.IRadioConfig getAidl() {
-        return mAidlRadioConfigProxy;
-    }
-
-    /** Reset RadioConfigProxy */
-    public void clear() {
-        mRadioConfigHalVersion = RadioConfig.RADIO_CONFIG_HAL_VERSION_UNKNOWN;
-        mHidlRadioConfigProxy = null;
-        mAidlRadioConfigProxy = null;
-        mRadioConfigHidlServiceDeathRecipient.clear();
-        mRadioConfigAidlServiceDeathRecipient.clear();
-    }
-
-    /**
-     * Wrapper for service's linkToDeath()
-     */
-    public void linkToDeath(long cookie) throws RemoteException {
-        if (isAidl()) {
-            mRadioConfigAidlServiceDeathRecipient.linkToDeath((int) cookie);
-        } else {
-            mRadioConfigHidlServiceDeathRecipient.linkToDeath(cookie);
-        }
-    }
-
-    /**
-     * Check whether an implementation exists for this service
-     *
-     * @return false if there is neither a HIDL nor AIDL implementation
-     */
-    public boolean isEmpty() {
-        return mAidlRadioConfigProxy == null && mHidlRadioConfigProxy == null;
-    }
-
-    /**
-     * Whether RadioConfigProxy is an AIDL or HIDL implementation
-     *
-     * @return true if AIDL, false if HIDL
-     */
-    public boolean isAidl() {
-        return mIsAidl;
-    }
-
-    /**
-     * Return RadioConfig HAL version used by this instance
-     * @return RadioConfig HAL Version
-     */
-    public HalVersion getVersion() {
-        return mRadioConfigHalVersion;
-    }
-
-    /**
-     * Set the response functions for RadioConfig instance
-     * @param radioConfig main RadioConfig instance
-     * @throws RemoteException
-     */
-    public void setResponseFunctions(RadioConfig radioConfig) throws RemoteException {
-        if (isEmpty()) return;
-
-        if (isAidl()) {
-            mAidlRadioConfigProxy.setResponseFunctions(
-                    new RadioConfigResponseAidl(radioConfig, mRadioHalVersion),
-                    new RadioConfigIndicationAidl(radioConfig));
-        } else {
-            mHidlRadioConfigProxy.setResponseFunctions(
-                    new RadioConfigResponseHidl(radioConfig, mRadioHalVersion),
-                    new RadioConfigIndicationHidl(radioConfig));
-        }
-    }
-
-    /**
-     * Get capabilities based off of the radio hal version and feature set configurations
-     * @return Set string capabilities
-     */
-    public Set<String> getFullCapabilitySet() {
-        return RILUtils.getCaps(mRadioHalVersion, false);
-    }
-
-    /**
-     * Wrapper function for IRadioConfig.getSimSlotsStatus().
-     */
-    public void getSimSlotStatus(int serial) throws RemoteException {
-        if (isAidl()) {
-            getAidl().getSimSlotsStatus(serial);
-        } else {
-            getHidl10().getSimSlotsStatus(serial);
-        }
-    }
-
-    /**
-     * Wrapper function for IRadioConfig.setPreferredDataModem(int modemId).
-     */
-    public void setPreferredDataModem(int serial, int modemId) throws RemoteException {
-        if (isAidl()) {
-            getAidl().setPreferredDataModem(serial, (byte) modemId);
-        } else {
-            getHidl11().setPreferredDataModem(serial, (byte) modemId);
-        }
-    }
-
-    /**
-     * Wrapper function for IRadioConfig.getPhoneCapability().
-     */
-    public void getPhoneCapability(int serial) throws RemoteException {
-        if (isAidl()) {
-            getAidl().getPhoneCapability(serial);
-        } else {
-            getHidl11().getPhoneCapability(serial);
-        }
-    }
-
-    /**
-     * Wrapper function for IRadioConfig.setSimSlotsMapping(int32_t serial,
-     * vec<SlotPortMapping> portMap).
-     */
-    public void setSimSlotsMapping(int serial, List<UiccSlotMapping> slotMapping)
-            throws RemoteException {
-        if (isAidl()) {
-            getAidl().setSimSlotsMapping(serial, RILUtils.convertSimSlotsMapping(slotMapping));
-        } else {
-            getHidl10().setSimSlotsMapping(serial,
-                    RILUtils.convertSlotMappingToList(slotMapping));
-        }
-    }
-
-    /**
-     * Wrapper function for using IRadioConfig.setNumOfLiveModems(int32_t serial,
-     * byte numOfLiveModems) to switch between single-sim and multi-sim.
-     */
-    public void setNumOfLiveModems(int serial, int numOfLiveModems) throws RemoteException {
-        if (isAidl()) {
-            getAidl().setNumOfLiveModems(serial, (byte) numOfLiveModems);
-        } else {
-            android.hardware.radio.config.V1_1.ModemsConfig modemsConfig =
-                    new android.hardware.radio.config.V1_1.ModemsConfig();
-            modemsConfig.numOfLiveModems = (byte) numOfLiveModems;
-            getHidl11().setModemsConfig(serial, modemsConfig);
-        }
-    }
-
-    /**
-     * Gets the hal capabilities from the device.
-     */
-    public void getHalDeviceCapabilities(int serial) throws RemoteException {
-        if (isAidl()) {
-            getAidl().getHalDeviceCapabilities(serial);
-        } else {
-            getHidl13().getHalDeviceCapabilities(serial);
-        }
-    }
-
-    /**
-     * Death Recipient for HIDL binder (if any) of RadioConfig.
-     */
-    private static class RadioConfigHidlServiceDeathRecipient implements HwBinder.DeathRecipient {
-        private static final String TAG = "RadioConfigHidlSDR";
-
-        private final RadioConfig mRadioConfig;
-        private android.hardware.radio.config.V1_0.IRadioConfig mService;
-
-        RadioConfigHidlServiceDeathRecipient(RadioConfig radioConfig) {
-            mRadioConfig = radioConfig;
-        }
-
-        public void setService(android.hardware.radio.config.V1_0.IRadioConfig service) {
-            mService = service;
-        }
-
-        public void linkToDeath(long cookie) throws RemoteException {
-            mService.linkToDeath(this, cookie);
-        }
-
-        public void clear() {
-            mService = null;
-        }
-
-        @Override
-        public void serviceDied(long cookie) {
-            // Deal with service going away
-            Rlog.e(TAG, "serviceDied");
-            mRadioConfig.sendMessage(
-                    mRadioConfig.obtainMessage(RadioConfig.EVENT_HIDL_SERVICE_DEAD, cookie));
-        }
-    }
-
-    /**
-     * DeathRecipient for AIDL binder service (if any) of RadioConfig
-     */
-    private static class RadioConfigAidlServiceDeathRecipient implements IBinder.DeathRecipient {
-        private static final String TAG = "RadioConfigAidlSDR";
-
-        private final RadioConfig mRadioConfig;
-
-        private IBinder mService;
-
-        RadioConfigAidlServiceDeathRecipient(RadioConfig radioConfig) {
-            mRadioConfig = radioConfig;
-        }
-
-        public void setService(IBinder service) {
-            mService = service;
-        }
-
-        public void linkToDeath(int cookie) throws RemoteException {
-            mService.linkToDeath(this, cookie);
-        }
-
-        public void clear() {
-            mService = null;
-        }
-
-        /**
-         * Unlink from RadioConfig if any.
-         */
-        public synchronized void unlinkToDeath() {
-            if (mService != null) {
-                mService.unlinkToDeath(this, 0);
-                mService = null;
-            }
-        }
-
-        @Override
-        public void binderDied() {
-            Rlog.e(TAG, "service died.");
-            unlinkToDeath();
-            mRadioConfig.sendMessage(
-                    mRadioConfig.obtainMessage(RadioConfig.EVENT_AIDL_SERVICE_DEAD));
-        }
-    }
-}
diff --git a/src/java/com/android/internal/telephony/RadioConfigResponse.java b/src/java/com/android/internal/telephony/RadioConfigResponse.java
new file mode 100644
index 0000000..3829c16
--- /dev/null
+++ b/src/java/com/android/internal/telephony/RadioConfigResponse.java
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+import static android.telephony.TelephonyManager
+        .CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE;
+import static android.telephony.TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED;
+import static android.telephony.TelephonyManager.CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE;
+import static android.telephony.TelephonyManager.CAPABILITY_SIM_PHONEBOOK_IN_MODEM;
+import static android.telephony.TelephonyManager.CAPABILITY_SLICING_CONFIG_SUPPORTED;
+import static android.telephony.TelephonyManager.CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING;
+import static android.telephony.TelephonyManager.CAPABILITY_USES_ALLOWED_NETWORK_TYPES_BITMASK;
+import static android.telephony.TelephonyManager.RadioInterfaceCapability;
+
+import android.hardware.radio.V1_0.RadioError;
+import android.hardware.radio.V1_0.RadioResponseInfo;
+import android.hardware.radio.config.V1_1.ModemsConfig;
+import android.hardware.radio.config.V1_3.IRadioConfigResponse;
+import android.telephony.ModemInfo;
+import android.telephony.PhoneCapability;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.telephony.uicc.IccSlotStatus;
+import com.android.telephony.Rlog;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class is the implementation of IRadioConfigResponse interface.
+ */
+public class RadioConfigResponse extends IRadioConfigResponse.Stub {
+    private static final String TAG = "RadioConfigResponse";
+
+    private final RadioConfig mRadioConfig;
+    private final HalVersion mRadioHalVersion;
+
+    public RadioConfigResponse(RadioConfig radioConfig, HalVersion radioHalVersion) {
+        mRadioConfig = radioConfig;
+        mRadioHalVersion = radioHalVersion;
+    }
+
+    /**
+     * Response function for IRadioConfig.getSimSlotsStatus().
+     */
+    public void getSimSlotsStatusResponse(RadioResponseInfo responseInfo,
+            ArrayList<android.hardware.radio.config.V1_0.SimSlotStatus> slotStatus) {
+        RILRequest rr = mRadioConfig.processResponse(responseInfo);
+
+        if (rr != null) {
+            ArrayList<IccSlotStatus> ret = RadioConfig.convertHalSlotStatus(slotStatus);
+            if (responseInfo.error == RadioError.NONE) {
+                // send response
+                RadioResponse.sendMessageResponse(rr.mResult, ret);
+                Rlog.d(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest) + " " + ret.toString());
+            } else {
+                rr.onError(responseInfo.error, ret);
+                Rlog.e(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest) + " error "
+                        + responseInfo.error);
+            }
+
+        } else {
+            Rlog.e(TAG, "getSimSlotsStatusResponse: Error " + responseInfo.toString());
+        }
+    }
+
+    /**
+     * Response function for IRadioConfig.getSimSlotsStatus().
+     */
+    public void getSimSlotsStatusResponse_1_2(RadioResponseInfo responseInfo,
+            ArrayList<android.hardware.radio.config.V1_2.SimSlotStatus> slotStatus) {
+        RILRequest rr = mRadioConfig.processResponse(responseInfo);
+
+        if (rr != null) {
+            ArrayList<IccSlotStatus> ret = RadioConfig.convertHalSlotStatus_1_2(slotStatus);
+            if (responseInfo.error == RadioError.NONE) {
+                // send response
+                RadioResponse.sendMessageResponse(rr.mResult, ret);
+                Rlog.d(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest) + " " + ret.toString());
+            } else {
+                rr.onError(responseInfo.error, ret);
+                Rlog.e(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest) + " error "
+                        + responseInfo.error);
+            }
+        } else {
+            Rlog.e(TAG, "getSimSlotsStatusResponse_1_2: Error " + responseInfo.toString());
+        }
+    }
+
+    /**
+     * Response function for IRadioConfig.setSimSlotsMapping().
+     */
+    public void setSimSlotsMappingResponse(RadioResponseInfo responseInfo) {
+        RILRequest rr = mRadioConfig.processResponse(responseInfo);
+
+        if (rr != null) {
+            if (responseInfo.error == RadioError.NONE) {
+                // send response
+                RadioResponse.sendMessageResponse(rr.mResult, null);
+                Rlog.d(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest));
+            } else {
+                rr.onError(responseInfo.error, null);
+                Rlog.e(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest) + " error "
+                        + responseInfo.error);
+            }
+        } else {
+            Rlog.e(TAG, "setSimSlotsMappingResponse: Error " + responseInfo.toString());
+        }
+    }
+
+    private PhoneCapability convertHalPhoneCapability(
+            android.hardware.radio.config.V1_1.PhoneCapability phoneCapability) {
+        // TODO b/121394331: clean up V1_1.PhoneCapability fields.
+        int maxActiveVoiceCalls = 0;
+        int maxActiveData = phoneCapability.maxActiveData;
+        boolean validationBeforeSwitchSupported = phoneCapability.isInternetLingeringSupported;
+        List<ModemInfo> logicalModemList = new ArrayList();
+
+        for (android.hardware.radio.config.V1_1.ModemInfo
+                modemInfo : phoneCapability.logicalModemList) {
+            logicalModemList.add(new ModemInfo(modemInfo.modemId));
+        }
+
+        return new PhoneCapability(maxActiveVoiceCalls, maxActiveData, logicalModemList,
+                validationBeforeSwitchSupported, mRadioConfig.getDeviceNrCapabilities());
+    }
+    /**
+     * Response function for IRadioConfig.getPhoneCapability().
+     */
+    public void getPhoneCapabilityResponse(RadioResponseInfo responseInfo,
+            android.hardware.radio.config.V1_1.PhoneCapability phoneCapability) {
+        RILRequest rr = mRadioConfig.processResponse(responseInfo);
+
+        if (rr != null) {
+            PhoneCapability ret = convertHalPhoneCapability(phoneCapability);
+            if (responseInfo.error == RadioError.NONE) {
+                // send response
+                RadioResponse.sendMessageResponse(rr.mResult, ret);
+                Rlog.d(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest) + " " + ret.toString());
+            } else {
+                rr.onError(responseInfo.error, ret);
+                Rlog.e(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest) + " error "
+                        + responseInfo.error);
+            }
+        } else {
+            Rlog.e(TAG, "getPhoneCapabilityResponse: Error " + responseInfo.toString());
+        }
+    }
+
+    /**
+     * Response function for IRadioConfig.setPreferredDataModem().
+     */
+    public void setPreferredDataModemResponse(RadioResponseInfo responseInfo) {
+        RILRequest rr = mRadioConfig.processResponse(responseInfo);
+
+        if (rr != null) {
+            if (responseInfo.error == RadioError.NONE) {
+                // send response
+                RadioResponse.sendMessageResponse(rr.mResult, null);
+                Rlog.d(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest));
+            } else {
+                rr.onError(responseInfo.error, null);
+                Rlog.e(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest) + " error "
+                        + responseInfo.error);
+            }
+        } else {
+            Rlog.e(TAG, "setPreferredDataModemResponse: Error " + responseInfo.toString());
+        }
+    }
+
+    /**
+     * Response function for IRadioConfig.setModemsConfigResponse()
+     * Currently this is being used as the callback for RadioConfig.setModemsConfig() method
+     */
+    public void setModemsConfigResponse(RadioResponseInfo responseInfo) {
+        RILRequest rr = mRadioConfig.processResponse(responseInfo);
+
+        if (rr != null) {
+            if (responseInfo.error == RadioError.NONE) {
+                // send response
+                RadioResponse.sendMessageResponse(rr.mResult, rr.mRequest);
+                Rlog.d(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest));
+            } else {
+                rr.onError(responseInfo.error, null);
+                Rlog.e(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest) + " error "
+                        + responseInfo.error);
+            }
+        } else {
+            Rlog.e(TAG, "setModemsConfigResponse: Error " + responseInfo.toString());
+        }
+    }
+
+    /**
+     * Response function for IRadioConfig.getModemsConfigResponse()
+     */
+    public void getModemsConfigResponse(RadioResponseInfo responseInfo, ModemsConfig modemsConfig) {
+        RILRequest rr = mRadioConfig.processResponse(responseInfo);
+
+        if (rr != null) {
+            if (responseInfo.error == RadioError.NONE) {
+                // send response
+                RadioResponse.sendMessageResponse(rr.mResult, modemsConfig);
+                Rlog.d(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest));
+            } else {
+                rr.onError(responseInfo.error, modemsConfig);
+                Rlog.e(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest) + " error "
+                        + responseInfo.error);
+            }
+        } else {
+            Rlog.e(TAG, "getModemsConfigResponse: Error " + responseInfo.toString());
+        }
+    }
+
+    /**
+     * Response function IRadioConfig.getHalDeviceCapabilities()
+     */
+    public void getHalDeviceCapabilitiesResponse(
+            android.hardware.radio.V1_6.RadioResponseInfo responseInfo,
+            boolean modemReducedFeatureSet1) {
+
+        // convert hal device capabilities to RadioInterfaceCapabilities
+
+        RILRequest rr = mRadioConfig.processResponse_1_6(responseInfo);
+        if (rr != null) {
+            // The response is compatible with Radio 1.6, it means the modem
+            // supports setAllowedNetworkTypeBitmap.
+
+            final Set<String> ret = getCaps(mRadioHalVersion, modemReducedFeatureSet1);
+
+            if (responseInfo.error == RadioError.NONE) {
+                // send response
+                RadioResponse.sendMessageResponse(rr.mResult, ret);
+                Rlog.d(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest));
+            } else {
+                rr.onError(responseInfo.error, ret);
+                Rlog.e(TAG, rr.serialString() + "< "
+                        + mRadioConfig.requestToString(rr.mRequest) + " error "
+                        + responseInfo.error);
+            }
+        } else {
+            Rlog.e(TAG, "getHalDeviceCapabilities: Error " + responseInfo.toString());
+        }
+    }
+
+    /**
+     * Returns all capabilities supported in the most recent radio hal version.
+     * <p/>
+     * Used in the {@link RILConstants.REQUEST_NOT_SUPPORTED} case.
+     *
+     * @return all capabilities
+     */
+    @RadioInterfaceCapability
+    public Set<String> getFullCapabilitySet() {
+        return getCaps(mRadioHalVersion, false);
+    }
+
+    /**
+     * Create capabilities based off of the radio hal version and feature set configurations.
+     */
+    @VisibleForTesting
+    public static Set<String> getCaps(HalVersion radioHalVersion,
+            boolean modemReducedFeatureSet1) {
+        final Set<String> caps = new HashSet<>();
+
+        if (radioHalVersion.equals(RIL.RADIO_HAL_VERSION_UNKNOWN)) {
+            // If the Radio HAL is UNKNOWN, no capabilities will present themselves.
+            Rlog.e(TAG, "Radio Hal Version is UNKNOWN!");
+        }
+
+        Rlog.d(TAG, "Radio Hal Version = " + radioHalVersion.toString());
+        if (radioHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
+            caps.add(CAPABILITY_USES_ALLOWED_NETWORK_TYPES_BITMASK);
+            Rlog.d(TAG, "CAPABILITY_USES_ALLOWED_NETWORK_TYPES_BITMASK");
+
+            if (!modemReducedFeatureSet1) {
+                caps.add(CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE);
+                Rlog.d(TAG, "CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE");
+                caps.add(CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE);
+                Rlog.d(TAG, "CAPABILITY_NR_DUAL_CONNECTIVITY_CONFIGURATION_AVAILABLE");
+                caps.add(CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING);
+                Rlog.d(TAG, "CAPABILITY_THERMAL_MITIGATION_DATA_THROTTLING");
+                caps.add(CAPABILITY_SLICING_CONFIG_SUPPORTED);
+                Rlog.d(TAG, "CAPABILITY_SLICING_CONFIG_SUPPORTED");
+                caps.add(CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
+                Rlog.d(TAG, "CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED");
+            } else {
+                caps.add(CAPABILITY_SIM_PHONEBOOK_IN_MODEM);
+                Rlog.d(TAG, "CAPABILITY_SIM_PHONEBOOK_IN_MODEM");
+            }
+        }
+        return caps;
+    }
+}
diff --git a/src/java/com/android/internal/telephony/RadioConfigResponseAidl.java b/src/java/com/android/internal/telephony/RadioConfigResponseAidl.java
deleted file mode 100644
index 2049654..0000000
--- a/src/java/com/android/internal/telephony/RadioConfigResponseAidl.java
+++ /dev/null
@@ -1,227 +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 com.android.internal.telephony;
-
-import android.os.RemoteException;
-import android.telephony.PhoneCapability;
-
-import com.android.internal.telephony.uicc.IccSlotStatus;
-import com.android.telephony.Rlog;
-
-import java.util.ArrayList;
-import java.util.Set;
-
-/**
- * This class is the AIDL implementation of IRadioConfigResponse interface.
- */
-public class RadioConfigResponseAidl extends
-        android.hardware.radio.config.IRadioConfigResponse.Stub {
-    private static final String TAG = "RadioConfigResponseAidl";
-
-    private final RadioConfig mRadioConfig;
-    private final HalVersion mHalVersion;
-
-    public RadioConfigResponseAidl(RadioConfig radioConfig, HalVersion halVersion) {
-        mRadioConfig = radioConfig;
-        mHalVersion = halVersion;
-    }
-
-    /**
-     * Response function IRadioConfig.getHalDeviceCapabilities()
-     */
-    @Override
-    public void getHalDeviceCapabilitiesResponse(
-            android.hardware.radio.RadioResponseInfo info,
-            boolean modemReducedFeatureSet1) throws RemoteException {
-        // convert hal device capabilities to RadioInterfaceCapabilities
-        RILRequest rr = mRadioConfig.processResponse(info);
-        if (rr != null) {
-            final Set<String> ret = RILUtils.getCaps(mHalVersion, modemReducedFeatureSet1);
-            if (info.error == android.hardware.radio.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-                logd(rr, RILUtils.requestToString(rr.mRequest));
-            } else {
-                rr.onError(info.error, ret);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("getHalDeviceCapabilities: Error " + info.toString());
-        }
-    }
-
-    /**
-     * Response function for IRadioConfig.getNumOfLiveModemsResponse()
-     */
-    @Override
-    public void getNumOfLiveModemsResponse(
-            android.hardware.radio.RadioResponseInfo info, byte numOfLiveModems)
-            throws RemoteException {
-        RILRequest rr = mRadioConfig.processResponse(info);
-        if (rr != null) {
-            if (info.error == android.hardware.radio.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, numOfLiveModems);
-                logd(rr, RILUtils.requestToString(rr.mRequest));
-            } else {
-                rr.onError(info.error, numOfLiveModems);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("getNumOfLiveModemsResponse: Error " + info.toString());
-        }
-    }
-
-    /**
-     * Response function for IRadioConfig.getPhoneCapability().
-     */
-    @Override
-    public void getPhoneCapabilityResponse(
-            android.hardware.radio.RadioResponseInfo info,
-            android.hardware.radio.config.PhoneCapability phoneCapability)
-            throws RemoteException {
-        RILRequest rr = mRadioConfig.processResponse(info);
-        if (rr != null) {
-            PhoneCapability ret = RILUtils.convertHalPhoneCapability(
-                    mRadioConfig.getDeviceNrCapabilities(), phoneCapability);
-            if (info.error == android.hardware.radio.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-                logd(rr, RILUtils.requestToString(rr.mRequest) + " " + ret.toString());
-            } else {
-                rr.onError(info.error, ret);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("getPhoneCapabilityResponse: Error " + info.toString());
-        }
-    }
-
-    /**
-     * Response function for IRadioConfig.getSimSlotsStatus().
-     */
-    @Override
-    public void getSimSlotsStatusResponse(
-            android.hardware.radio.RadioResponseInfo info,
-            android.hardware.radio.config.SimSlotStatus[] slotStatus)
-            throws RemoteException {
-        RILRequest rr = mRadioConfig.processResponse(info);
-        if (rr != null) {
-            ArrayList<IccSlotStatus> ret = RILUtils.convertHalSlotStatus(slotStatus);
-            if (info.error == android.hardware.radio.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-                logd(rr, RILUtils.requestToString(rr.mRequest) + " " + ret.toString());
-            } else {
-                rr.onError(info.error, ret);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("getSimSlotsStatusResponse: Error " + info.toString());
-        }
-    }
-
-    /**
-     * Response function for IRadioConfig.setNumOfLiveModemsResponse()
-     * Currently this is being used as the callback for RadioConfig.setNumOfLiveModems() method
-     */
-    @Override
-    public void setNumOfLiveModemsResponse(
-            android.hardware.radio.RadioResponseInfo info) throws RemoteException {
-        RILRequest rr = mRadioConfig.processResponse(info);
-        if (rr != null) {
-            if (info.error == android.hardware.radio.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, rr.mRequest);
-                logd(rr, RILUtils.requestToString(rr.mRequest));
-            } else {
-                rr.onError(info.error, null);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("setModemsConfigResponse: Error " + info.toString());
-        }
-    }
-
-    /**
-     * Response function for IRadioConfig.setPreferredDataModem().
-     */
-    @Override
-    public void setPreferredDataModemResponse(
-            android.hardware.radio.RadioResponseInfo info) throws RemoteException {
-        RILRequest rr = mRadioConfig.processResponse(info);
-        if (rr != null) {
-            if (info.error == android.hardware.radio.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, null);
-                logd(rr, RILUtils.requestToString(rr.mRequest));
-            } else {
-                rr.onError(info.error, null);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("setPreferredDataModemResponse: Error " + info.toString());
-        }
-    }
-
-    /**
-     * Response function for IRadioConfig.setSimSlotsMapping().
-     */
-    @Override
-    public void setSimSlotsMappingResponse(
-            android.hardware.radio.RadioResponseInfo info) throws RemoteException {
-        RILRequest rr = mRadioConfig.processResponse(info);
-        if (rr != null) {
-            if (info.error == android.hardware.radio.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, null);
-                logd(rr, RILUtils.requestToString(rr.mRequest));
-            } else {
-                rr.onError(info.error, null);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("setSimSlotsMappingResponse: Error " + info.toString());
-        }
-    }
-
-    private static void logd(String log) {
-        Rlog.d(TAG, log);
-    }
-
-    private static void loge(String log) {
-        Rlog.e(TAG, log);
-    }
-
-    private static void logd(RILRequest rr, String log) {
-        logd(rr.serialString() + "< " + log);
-    }
-
-    private static void loge(RILRequest rr, String log) {
-        loge(rr.serialString() + "< " + log);
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return android.hardware.radio.config.IRadioConfigResponse.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return android.hardware.radio.config.IRadioConfigResponse.VERSION;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/RadioConfigResponseHidl.java b/src/java/com/android/internal/telephony/RadioConfigResponseHidl.java
deleted file mode 100644
index a6ae258..0000000
--- a/src/java/com/android/internal/telephony/RadioConfigResponseHidl.java
+++ /dev/null
@@ -1,244 +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 com.android.internal.telephony;
-
-import android.os.RemoteException;
-import android.telephony.PhoneCapability;
-
-import com.android.internal.telephony.uicc.IccSlotStatus;
-import com.android.telephony.Rlog;
-
-import java.util.ArrayList;
-import java.util.Set;
-
-/**
- * This class is the AIDL implementation of IRadioConfigResponse interface.
- */
-public class RadioConfigResponseHidl extends
-        android.hardware.radio.config.V1_3.IRadioConfigResponse.Stub {
-    private static final String TAG = "RadioConfigResponse";
-
-    private final RadioConfig mRadioConfig;
-    private final HalVersion mHalVersion;
-
-    public RadioConfigResponseHidl(RadioConfig radioConfig, HalVersion halVersion) {
-        mRadioConfig = radioConfig;
-        mHalVersion = halVersion;
-    }
-
-    /**
-     * Response function for IRadioConfig.getSimSlotsStatus().
-     */
-    @Override
-    public void getSimSlotsStatusResponse(
-            android.hardware.radio.V1_0.RadioResponseInfo info,
-            ArrayList<android.hardware.radio.config.V1_0.SimSlotStatus> slotStatus)
-            throws RemoteException {
-        RILRequest rr = mRadioConfig.processResponse(info);
-
-        if (rr != null) {
-            ArrayList<IccSlotStatus> ret = RILUtils.convertHalSlotStatus(slotStatus);
-            if (info.error == android.hardware.radio.V1_0.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-                logd(rr, RILUtils.requestToString(rr.mRequest) + " " + ret.toString());
-            } else {
-                rr.onError(info.error, ret);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("getSimSlotsStatusResponse: Error " + info.toString());
-        }
-    }
-
-    /**
-     * Response function for IRadioConfig.setSimSlotsMapping().
-     */
-    @Override
-    public void setSimSlotsMappingResponse(android.hardware.radio.V1_0.RadioResponseInfo info)
-            throws RemoteException {
-        RILRequest rr = mRadioConfig.processResponse(info);
-        if (rr != null) {
-            if (info.error == android.hardware.radio.V1_0.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, null);
-                logd(rr, RILUtils.requestToString(rr.mRequest));
-            } else {
-                rr.onError(info.error, null);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("setSimSlotsMappingResponse: Error " + info.toString());
-        }
-    }
-
-    /**
-     * Response function for IRadioConfig.getPhoneCapability().
-     */
-    @Override
-    public void getPhoneCapabilityResponse(android.hardware.radio.V1_0.RadioResponseInfo info,
-            android.hardware.radio.config.V1_1.PhoneCapability phoneCapability)
-            throws RemoteException {
-        RILRequest rr = mRadioConfig.processResponse(info);
-        if (rr != null) {
-            PhoneCapability ret = RILUtils.convertHalPhoneCapability(
-                    mRadioConfig.getDeviceNrCapabilities(), phoneCapability);
-            if (info.error == android.hardware.radio.V1_0.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-                logd(rr, RILUtils.requestToString(rr.mRequest) + " " + ret.toString());
-            } else {
-                rr.onError(info.error, ret);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("getPhoneCapabilityResponse: Error " + info.toString());
-        }
-    }
-
-    /**
-     * Response function for IRadioConfig.setPreferredDataModem().
-     */
-    @Override
-    public void setPreferredDataModemResponse(
-            android.hardware.radio.V1_0.RadioResponseInfo info) throws RemoteException {
-        RILRequest rr = mRadioConfig.processResponse(info);
-        if (rr != null) {
-            if (info.error == android.hardware.radio.V1_0.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, null);
-                logd(rr, RILUtils.requestToString(rr.mRequest));
-            } else {
-                rr.onError(info.error, null);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("setPreferredDataModemResponse: Error " + info.toString());
-        }
-    }
-
-    /**
-     * Response function for IRadioConfig.setModemsConfigResponse()
-     * Currently this is being used as the callback for RadioConfig.setModemsConfig() method
-     */
-    @Override
-    public void setModemsConfigResponse(android.hardware.radio.V1_0.RadioResponseInfo info)
-            throws RemoteException {
-        RILRequest rr = mRadioConfig.processResponse(info);
-        if (rr != null) {
-            if (info.error == android.hardware.radio.V1_0.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, rr.mRequest);
-                logd(rr, RILUtils.requestToString(rr.mRequest));
-            } else {
-                rr.onError(info.error, null);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("setModemsConfigResponse: Error " + info.toString());
-        }
-    }
-
-    /**
-     * Response function for IRadioConfig.getModemsConfigResponse()
-     */
-    @Override
-    public void getModemsConfigResponse(android.hardware.radio.V1_0.RadioResponseInfo info,
-            android.hardware.radio.config.V1_1.ModemsConfig modemsConfig)
-            throws RemoteException {
-        RILRequest rr = mRadioConfig.processResponse(info);
-        if (rr != null) {
-            if (info.error == android.hardware.radio.V1_0.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, modemsConfig);
-                logd(rr, RILUtils.requestToString(rr.mRequest));
-            } else {
-                rr.onError(info.error, modemsConfig);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("getModemsConfigResponse: Error " + info.toString());
-        }
-    }
-
-    /**
-     * Response function for IRadioConfig.getSimSlotsStatus().
-     */
-    @Override
-    public void getSimSlotsStatusResponse_1_2(
-            android.hardware.radio.V1_0.RadioResponseInfo info,
-            ArrayList<android.hardware.radio.config.V1_2.SimSlotStatus> slotStatus)
-            throws RemoteException {
-        RILRequest rr = mRadioConfig.processResponse(info);
-        if (rr != null) {
-            ArrayList<IccSlotStatus> ret = RILUtils.convertHalSlotStatus(slotStatus);
-            if (info.error == android.hardware.radio.V1_0.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-                logd(rr, RILUtils.requestToString(rr.mRequest) + " " + ret.toString());
-            } else {
-                rr.onError(info.error, ret);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("getSimSlotsStatusResponse_1_2: Error " + info.toString());
-        }
-    }
-
-    /**
-     * Response function IRadioConfig.getHalDeviceCapabilities()
-     */
-    @Override
-    public void getHalDeviceCapabilitiesResponse(
-            android.hardware.radio.V1_6.RadioResponseInfo info, boolean modemReducedFeatureSet1)
-            throws RemoteException {
-        // convert hal device capabilities to RadioInterfaceCapabilities
-        RILRequest rr = mRadioConfig.processResponse_1_6(info);
-        if (rr != null) {
-            // The response is compatible with Radio 1.6, it means the modem
-            // supports setAllowedNetworkTypeBitmap.
-            final Set<String> ret = RILUtils.getCaps(mHalVersion,
-                    modemReducedFeatureSet1);
-            if (info.error == android.hardware.radio.V1_0.RadioError.NONE) {
-                // send response
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-                logd(rr, RILUtils.requestToString(rr.mRequest));
-            } else {
-                rr.onError(info.error, ret);
-                loge(rr, RILUtils.requestToString(rr.mRequest) + " error " + info.error);
-            }
-        } else {
-            loge("getHalDeviceCapabilities: Error " + info.toString());
-        }
-    }
-
-    private static void logd(String log) {
-        Rlog.d(TAG, log);
-    }
-
-    private static void loge(String log) {
-        Rlog.e(TAG, log);
-    }
-
-    private static void logd(RILRequest rr, String log) {
-        logd(rr.serialString() + "< " + log);
-    }
-
-    private static void loge(RILRequest rr, String log) {
-        loge(rr.serialString() + "< " + log);
-    }
-}
diff --git a/src/java/com/android/internal/telephony/RadioDataProxy.java b/src/java/com/android/internal/telephony/RadioDataProxy.java
deleted file mode 100644
index cbc762a..0000000
--- a/src/java/com/android/internal/telephony/RadioDataProxy.java
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.net.KeepalivePacketData;
-import android.net.LinkProperties;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.RemoteException;
-import android.telephony.Rlog;
-import android.telephony.ServiceState;
-import android.telephony.data.DataProfile;
-import android.telephony.data.DataService;
-import android.telephony.data.NetworkSliceInfo;
-import android.telephony.data.TrafficDescriptor;
-
-import java.net.Inet4Address;
-import java.net.Inet6Address;
-import java.net.InetAddress;
-import java.util.ArrayList;
-
-/**
- * A holder for IRadioData. Use getHidl to get IRadio 1.0 and call the HIDL implementations or
- * getAidl to get IRadioData and call the AIDL implementations of the HAL APIs.
- */
-public class RadioDataProxy extends RadioServiceProxy {
-    private static final String TAG = "RadioDataProxy";
-    private volatile android.hardware.radio.data.IRadioData mDataProxy = null;
-
-    /**
-     * Set IRadioData as the AIDL implementation for RadioServiceProxy
-     * @param halVersion Radio HAL version
-     * @param data IRadioData implementation
-     */
-    public void setAidl(HalVersion halVersion, android.hardware.radio.data.IRadioData data) {
-        mHalVersion = halVersion;
-        mDataProxy = data;
-        mIsAidl = true;
-        Rlog.d(TAG, "AIDL initialized");
-    }
-
-    /**
-     * Get the AIDL implementation of RadioDataProxy
-     * @return IRadioData implementation
-     */
-    public android.hardware.radio.data.IRadioData getAidl() {
-        return mDataProxy;
-    }
-
-    /**
-     * Reset RadioDataProxy
-     */
-    @Override
-    public void clear() {
-        super.clear();
-        mDataProxy = null;
-    }
-
-    /**
-     * Check whether a RadioData implementation exists
-     * @return true if there is neither a HIDL nor AIDL implementation
-     */
-    @Override
-    public boolean isEmpty() {
-        return mRadioProxy == null && mDataProxy == null;
-    }
-
-    /**
-     * Call IRadioData#allocatePduSessionId
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void allocatePduSessionId(int serial) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (isAidl()) {
-            mDataProxy.allocatePduSessionId(serial);
-        } else {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).allocatePduSessionId(serial);
-        }
-    }
-
-    /**
-     * Call IRadioData#cancelHandover
-     * @param serial Serial number of request
-     * @param callId Identifier associated with the data call
-     * @throws RemoteException
-     */
-    public void cancelHandover(int serial, int callId) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (isAidl()) {
-            mDataProxy.cancelHandover(serial, callId);
-        } else {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).cancelHandover(serial, callId);
-        }
-    }
-
-    /**
-     * Call IRadioData#deactivateDataCall
-     * @param serial Serial number of request
-     * @param cid The connection ID
-     * @param reason Data disconnect reason
-     * @throws RemoteException
-     */
-    public void deactivateDataCall(int serial, int cid, int reason) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mDataProxy.deactivateDataCall(serial, cid, reason);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_2)) {
-            ((android.hardware.radio.V1_2.IRadio) mRadioProxy).deactivateDataCall_1_2(
-                    serial, cid, reason);
-        } else {
-            mRadioProxy.deactivateDataCall(serial, cid,
-                    reason == DataService.REQUEST_REASON_SHUTDOWN);
-        }
-    }
-
-    /**
-     * Call IRadioData#getDataCallList
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getDataCallList(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mDataProxy.getDataCallList(serial);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getDataCallList_1_6(serial);
-        } else {
-            mRadioProxy.getDataCallList(serial);
-        }
-    }
-
-    /**
-     * Call IRadioData#getSlicingConfig
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getSlicingConfig(int serial) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (isAidl()) {
-            mDataProxy.getSlicingConfig(serial);
-        } else {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getSlicingConfig(serial);
-        }
-    }
-
-    /**
-     * Call IRadioData#releasePduSessionId
-     * @param serial Serial number of request
-     * @param id PDU session ID to release
-     * @throws RemoteException
-     */
-    public void releasePduSessionId(int serial, int id) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (isAidl()) {
-            mDataProxy.releasePduSessionId(serial, id);
-        } else {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).releasePduSessionId(serial, id);
-        }
-    }
-
-    /**
-     * Call IRadioData#responseAcknowledgement
-     * @throws RemoteException
-     */
-    @Override
-    public void responseAcknowledgement() throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mDataProxy.responseAcknowledgement();
-        } else {
-            mRadioProxy.responseAcknowledgement();
-        }
-    }
-
-    /**
-     * Call IRadioData#setDataAllowed
-     * @param serial Serial number of request
-     * @param allow Whether to allow or disallow data calls
-     * @throws RemoteException
-     */
-    public void setDataAllowed(int serial, boolean allow) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mDataProxy.setDataAllowed(serial, allow);
-        } else {
-            mRadioProxy.setDataAllowed(serial, allow);
-        }
-    }
-
-    /**
-     * Call IRadioData#setDataProfile
-     * @param serial Serial number of request
-     * @param profiles Array of DataProfiles to set
-     * @param isRoaming Whether or not the device is roaming
-     * @throws RemoteException
-     */
-    public void setDataProfile(int serial, DataProfile[] profiles, boolean isRoaming)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            android.hardware.radio.data.DataProfileInfo[] dpis =
-                    new android.hardware.radio.data.DataProfileInfo[profiles.length];
-            for (int i = 0; i < profiles.length; i++) {
-                dpis[i] = RILUtils.convertToHalDataProfile(profiles[i]);
-            }
-            mDataProxy.setDataProfile(serial, dpis);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            ArrayList<android.hardware.radio.V1_5.DataProfileInfo> dpis = new ArrayList<>();
-            for (DataProfile dp : profiles) {
-                dpis.add(RILUtils.convertToHalDataProfile15(dp));
-            }
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).setDataProfile_1_5(serial, dpis);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_4)) {
-            ArrayList<android.hardware.radio.V1_4.DataProfileInfo> dpis = new ArrayList<>();
-            for (DataProfile dp : profiles) {
-                dpis.add(RILUtils.convertToHalDataProfile14(dp));
-            }
-            ((android.hardware.radio.V1_4.IRadio) mRadioProxy).setDataProfile_1_4(serial, dpis);
-        } else {
-            ArrayList<android.hardware.radio.V1_0.DataProfileInfo> dpis = new ArrayList<>();
-            for (DataProfile dp : profiles) {
-                if (dp.isPersistent()) {
-                    dpis.add(RILUtils.convertToHalDataProfile10(dp));
-                }
-            }
-            if (!dpis.isEmpty()) {
-                mRadioProxy.setDataProfile(serial, dpis, isRoaming);
-            }
-        }
-    }
-
-    /**
-     * Call IRadioData#setDataThrottling
-     * @param serial Serial number of request
-     * @param dataThrottlingAction DataThrottlingAction as defined in DataThrottlingAction.aidl
-     * @param completionDurationMillis Window in ms in which the requested throttling action has to
-     *                                 be achieved.
-     * @throws RemoteException
-     */
-    public void setDataThrottling(int serial, byte dataThrottlingAction,
-            long completionDurationMillis) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (isAidl()) {
-            mDataProxy.setDataThrottling(serial, dataThrottlingAction, completionDurationMillis);
-        } else {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).setDataThrottling(serial,
-                    dataThrottlingAction, completionDurationMillis);
-        }
-    }
-
-    /**
-     * Call IRadioData#setInitialAttachApn
-     * @param serial Serial number of request
-     * @param dataProfile Data profile containing APN settings
-     * @param isRoaming Whether or not the device is roaming
-     * @throws RemoteException
-     */
-    public void setInitialAttachApn(int serial, DataProfile dataProfile, boolean isRoaming)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mDataProxy.setInitialAttachApn(serial, RILUtils.convertToHalDataProfile(dataProfile));
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).setInitialAttachApn_1_5(serial,
-                    RILUtils.convertToHalDataProfile15(dataProfile));
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_4)) {
-            ((android.hardware.radio.V1_4.IRadio) mRadioProxy).setInitialAttachApn_1_4(serial,
-                    RILUtils.convertToHalDataProfile14(dataProfile));
-        } else {
-            mRadioProxy.setInitialAttachApn(serial, RILUtils.convertToHalDataProfile10(dataProfile),
-                    dataProfile.isPersistent(), isRoaming);
-        }
-    }
-
-    /**
-     * Call IRadioData#setupDataCall
-     * @param serial Serial number of request
-     * @param phoneId Phone ID of the requestor
-     * @param accessNetwork Access network to setup the data call
-     * @param dataProfileInfo Data profile info
-     * @param isRoaming Whether or not the device is roaming
-     * @param roamingAllowed Whether or not data roaming is allowed by the user
-     * @param reason Request reason
-     * @param linkProperties LinkProperties containing address and DNS info
-     * @param pduSessionId The PDU session ID to be used for this data call
-     * @param sliceInfo SliceInfo to be used for the data connection when a handover occurs from
-     *                  EPDG to 5G
-     * @param trafficDescriptor TrafficDescriptor for which the data connection needs to be
-     *                          established
-     * @param matchAllRuleAllowed Whether or not the default match-all URSP rule for this request
-     *                            is allowed
-     * @throws RemoteException
-     */
-    public void setupDataCall(int serial, int phoneId, int accessNetwork,
-            DataProfile dataProfileInfo, boolean isRoaming, boolean roamingAllowed, int reason,
-            LinkProperties linkProperties, int pduSessionId, NetworkSliceInfo sliceInfo,
-            TrafficDescriptor trafficDescriptor, boolean matchAllRuleAllowed)
-            throws RemoteException {
-        if (isEmpty()) return;
-        ArrayList<String> addresses = new ArrayList<>();
-        ArrayList<String> dnses = new ArrayList<>();
-        String[] dnsesArr = null;
-        if (linkProperties != null) {
-            for (InetAddress address : linkProperties.getAddresses()) {
-                addresses.add(address.getHostAddress());
-            }
-            dnsesArr = new String[linkProperties.getDnsServers().size()];
-            for (int i = 0; i < linkProperties.getDnsServers().size(); i++) {
-                dnses.add(linkProperties.getDnsServers().get(i).getHostAddress());
-                dnsesArr[i] = linkProperties.getDnsServers().get(i).getHostAddress();
-            }
-        } else {
-            dnsesArr = new String[0];
-        }
-        if (isAidl()) {
-            // Create a new DataProfile to set the TrafficDescriptor
-            DataProfile dp = new DataProfile.Builder()
-                    .setType(dataProfileInfo.getType())
-                    .setPreferred(dataProfileInfo.isPreferred())
-                    .setTrafficDescriptor(trafficDescriptor)
-                    .setApnSetting(dataProfileInfo.getApnSetting())
-                    .build();
-            mDataProxy.setupDataCall(serial, accessNetwork, RILUtils.convertToHalDataProfile(dp),
-                    roamingAllowed, reason, RILUtils.convertToHalLinkProperties(linkProperties),
-                    dnsesArr, pduSessionId, RILUtils.convertToHalSliceInfoAidl(sliceInfo),
-                    matchAllRuleAllowed);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).setupDataCall_1_6(serial,
-                    accessNetwork, RILUtils.convertToHalDataProfile15(dataProfileInfo),
-                    roamingAllowed, reason, RILUtils.convertToHalLinkProperties15(linkProperties),
-                    dnses, pduSessionId, RILUtils.convertToHalSliceInfo(sliceInfo),
-                    RILUtils.convertToHalTrafficDescriptor(trafficDescriptor),
-                    matchAllRuleAllowed);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).setupDataCall_1_5(serial,
-                    accessNetwork, RILUtils.convertToHalDataProfile15(dataProfileInfo),
-                    roamingAllowed, reason, RILUtils.convertToHalLinkProperties15(linkProperties),
-                    dnses);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_4)) {
-            ((android.hardware.radio.V1_4.IRadio) mRadioProxy).setupDataCall_1_4(serial,
-                    accessNetwork, RILUtils.convertToHalDataProfile14(dataProfileInfo),
-                    roamingAllowed, reason, addresses, dnses);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_2)) {
-            ((android.hardware.radio.V1_2.IRadio) mRadioProxy).setupDataCall_1_2(serial,
-                    accessNetwork, RILUtils.convertToHalDataProfile10(dataProfileInfo),
-                    dataProfileInfo.isPersistent(), roamingAllowed, isRoaming, reason, addresses,
-                    dnses);
-        } else {
-            // Getting data RAT here is just a workaround to support the older 1.0 vendor RIL.
-            // The new data service interface passes access network type instead of RAT for
-            // setup data request. It is impossible to convert access network type back to RAT here,
-            // so we directly get the data RAT from phone.
-            int dataRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
-            Phone phone = PhoneFactory.getPhone(phoneId);
-            if (phone != null) {
-                ServiceState ss = phone.getServiceState();
-                if (ss != null) {
-                    dataRat = ss.getRilDataRadioTechnology();
-                }
-            }
-            mRadioProxy.setupDataCall(serial, dataRat,
-                    RILUtils.convertToHalDataProfile10(dataProfileInfo),
-                    dataProfileInfo.isPersistent(), roamingAllowed, isRoaming);
-        }
-    }
-
-    /**
-     * Call IRadioData#startHandover
-     * @param serial Serial number of request
-     * @param callId Identifier of the data call
-     * @throws RemoteException
-     */
-    public void startHandover(int serial, int callId) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (isAidl()) {
-            mDataProxy.startHandover(serial, callId);
-        } else {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).startHandover(serial, callId);
-        }
-    }
-
-    /**
-     * Call IRadioData#startKeepalive
-     * @param serial Serial number of request
-     * @param contextId Context ID for the data call
-     * @param packetData Keepalive packet data
-     * @param intervalMillis Max keepalive interval in ms
-     * @param result Result to return in case of invalid arguments
-     * @throws RemoteException
-     */
-    public void startKeepalive(int serial, int contextId, KeepalivePacketData packetData,
-            int intervalMillis, Message result) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_1)) return;
-        if (isAidl()) {
-            android.hardware.radio.data.KeepaliveRequest req =
-                    new android.hardware.radio.data.KeepaliveRequest();
-            req.cid = contextId;
-
-            if (packetData.getDstAddress() instanceof Inet4Address) {
-                req.type = android.hardware.radio.data.KeepaliveRequest.TYPE_NATT_IPV4;
-            } else if (packetData.getDstAddress() instanceof Inet6Address) {
-                req.type = android.hardware.radio.data.KeepaliveRequest.TYPE_NATT_IPV6;
-            } else {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(RILConstants.INVALID_ARGUMENTS));
-                result.sendToTarget();
-                return;
-            }
-
-            final InetAddress srcAddress = packetData.getSrcAddress();
-            final InetAddress dstAddress = packetData.getDstAddress();
-            byte[] sourceAddress = new byte[srcAddress.getAddress().length];
-            for (int i = 0; i < sourceAddress.length; i++) {
-                sourceAddress[i] = srcAddress.getAddress()[i];
-            }
-            req.sourceAddress = sourceAddress;
-            req.sourcePort = packetData.getSrcPort();
-            byte[] destinationAddress = new byte[dstAddress.getAddress().length];
-            for (int i = 0; i < destinationAddress.length; i++) {
-                destinationAddress[i] = dstAddress.getAddress()[i];
-            }
-            req.destinationAddress = destinationAddress;
-            req.destinationPort = packetData.getDstPort();
-            req.maxKeepaliveIntervalMillis = intervalMillis;
-
-            mDataProxy.startKeepalive(serial, req);
-        } else {
-            android.hardware.radio.V1_1.KeepaliveRequest req =
-                    new android.hardware.radio.V1_1.KeepaliveRequest();
-
-            req.cid = contextId;
-
-            if (packetData.getDstAddress() instanceof Inet4Address) {
-                req.type = android.hardware.radio.V1_1.KeepaliveType.NATT_IPV4;
-            } else if (packetData.getDstAddress() instanceof Inet6Address) {
-                req.type = android.hardware.radio.V1_1.KeepaliveType.NATT_IPV6;
-            } else {
-                AsyncResult.forMessage(result, null,
-                        CommandException.fromRilErrno(RILConstants.INVALID_ARGUMENTS));
-                result.sendToTarget();
-                return;
-            }
-
-            final InetAddress srcAddress = packetData.getSrcAddress();
-            final InetAddress dstAddress = packetData.getDstAddress();
-            RILUtils.appendPrimitiveArrayToArrayList(
-                    srcAddress.getAddress(), req.sourceAddress);
-            req.sourcePort = packetData.getSrcPort();
-            RILUtils.appendPrimitiveArrayToArrayList(
-                    dstAddress.getAddress(), req.destinationAddress);
-            req.destinationPort = packetData.getDstPort();
-            req.maxKeepaliveIntervalMillis = intervalMillis;
-
-            ((android.hardware.radio.V1_1.IRadio) mRadioProxy).startKeepalive(serial, req);
-        }
-    }
-
-    /**
-     * Call IRadioData#stopKeepalive
-     * @param serial Serial number of request
-     * @param sessionHandle The handle that was provided by startKeepaliveResponse
-     * @throws RemoteException
-     */
-    public void stopKeepalive(int serial, int sessionHandle) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_1)) return;
-        if (isAidl()) {
-            mDataProxy.stopKeepalive(serial, sessionHandle);
-        } else {
-            ((android.hardware.radio.V1_1.IRadio) mRadioProxy).stopKeepalive(serial, sessionHandle);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/telephony/RadioIndication.java b/src/java/com/android/internal/telephony/RadioIndication.java
index c7244be..d18efdc 100644
--- a/src/java/com/android/internal/telephony/RadioIndication.java
+++ b/src/java/com/android/internal/telephony/RadioIndication.java
@@ -16,14 +16,11 @@
 
 package com.android.internal.telephony;
 
-import static android.telephony.TelephonyManager.UNKNOWN_CARRIER_ID;
-
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CALL_RING;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_CALL_WAITING;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_INFO_REC;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_OTA_PROVISION_STATUS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_PRL_CHANGED;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CELL_INFO_LIST;
@@ -72,6 +69,7 @@
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UNTHROTTLE_APN;
 import static com.android.internal.telephony.RILConstants.RIL_UNSOL_VOICE_RADIO_TECH_CHANGED;
+import static com.android.internal.telephony.RILConstants.RIL_UNSOl_CDMA_PRL_CHANGED;
 
 import android.hardware.radio.V1_0.CdmaCallWaiting;
 import android.hardware.radio.V1_0.CdmaInformationRecord;
@@ -88,12 +86,14 @@
 import android.hardware.radio.V1_0.SsInfoData;
 import android.hardware.radio.V1_0.StkCcUnsolSsResult;
 import android.hardware.radio.V1_0.SuppSvcNotification;
+import android.hardware.radio.V1_2.CellConnectionStatus;
 import android.hardware.radio.V1_6.IRadioIndication;
 import android.hardware.radio.V1_6.PhonebookRecordInfo;
 import android.hardware.radio.V1_6.PhysicalChannelConfig.Band;
 import android.os.AsyncResult;
 import android.os.RemoteException;
 import android.sysprop.TelephonyProperties;
+import android.telephony.Annotation.RadioPowerState;
 import android.telephony.AnomalyReporter;
 import android.telephony.BarringInfo;
 import android.telephony.CellIdentity;
@@ -105,13 +105,15 @@
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SmsMessage;
+import android.telephony.TelephonyManager;
 import android.telephony.data.DataCallResponse;
 import android.telephony.emergency.EmergencyNumber;
 import android.text.TextUtils;
 
 import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
 import com.android.internal.telephony.cdma.CdmaInformationRecords;
-import com.android.internal.telephony.data.KeepaliveStatus;
+import com.android.internal.telephony.cdma.SmsMessageConverter;
+import com.android.internal.telephony.dataconnection.KeepaliveStatus;
 import com.android.internal.telephony.gsm.SsData;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
 import com.android.internal.telephony.uicc.IccRefreshResponse;
@@ -136,9 +138,9 @@
      * @param radioState android.hardware.radio.V1_0.RadioState
      */
     public void radioStateChanged(int indicationType, int radioState) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        int state = RILUtils.convertHalRadioState(radioState);
+        int state = getRadioStateFromInt(radioState);
         if (RIL.RILJ_LOGD) {
             mRil.unsljLogMore(RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, "radioStateChanged: " +
                     state);
@@ -148,7 +150,7 @@
     }
 
     public void callStateChanged(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED);
 
@@ -160,7 +162,7 @@
      * @param indicationType RadioIndicationType
      */
     public void networkStateChanged(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED);
 
@@ -168,9 +170,9 @@
     }
 
     public void newSms(int indicationType, ArrayList<Byte> pdu) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        byte[] pduArray = RILUtils.arrayListToPrimitiveArray(pdu);
+        byte[] pduArray = RIL.arrayListToPrimitiveArray(pdu);
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS);
 
         SmsMessageBase smsb = com.android.internal.telephony.gsm.SmsMessage.createFromPdu(pduArray);
@@ -181,9 +183,9 @@
     }
 
     public void newSmsStatusReport(int indicationType, ArrayList<Byte> pdu) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        byte[] pduArray = RILUtils.arrayListToPrimitiveArray(pdu);
+        byte[] pduArray = RIL.arrayListToPrimitiveArray(pdu);
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT);
 
         if (mRil.mSmsStatusRegistrant != null) {
@@ -192,7 +194,7 @@
     }
 
     public void newSmsOnSim(int indicationType, int recordNumber) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM);
 
@@ -202,7 +204,7 @@
     }
 
     public void onUssd(int indicationType, int ussdModeType, String msg) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogMore(RIL_UNSOL_ON_USSD, "" + ussdModeType);
 
@@ -216,7 +218,7 @@
     }
 
     public void nitzTimeReceived(int indicationType, String nitzTime, long receivedTime) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_NITZ_TIME_RECEIVED, nitzTime);
 
@@ -241,9 +243,9 @@
 
     public void currentSignalStrength(int indicationType,
                                       android.hardware.radio.V1_0.SignalStrength signalStrength) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        SignalStrength ssInitial = RILUtils.convertHalSignalStrength(signalStrength);
+        SignalStrength ssInitial = new SignalStrength(signalStrength);
 
         SignalStrength ss = mRil.fixupSignalStrength10(ssInitial);
         // Note this is set to "verbose" because it happens frequently
@@ -259,9 +261,9 @@
      */
     public void currentLinkCapacityEstimate(int indicationType,
                                             android.hardware.radio.V1_2.LinkCapacityEstimate lce) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        List<LinkCapacityEstimate> response = RILUtils.convertHalLceData(lce);
+        List<LinkCapacityEstimate> response = RIL.convertHalLceData(lce, mRil);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_LCEDATA_RECV, response);
 
@@ -275,9 +277,9 @@
      */
     public void currentLinkCapacityEstimate_1_6(int indicationType,
             android.hardware.radio.V1_6.LinkCapacityEstimate lce) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        List<LinkCapacityEstimate> response = RILUtils.convertHalLceData(lce);
+        List<LinkCapacityEstimate> response = RIL.convertHalLceData(lce, mRil);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_LCEDATA_RECV, response);
 
@@ -291,9 +293,9 @@
      */
     public void currentSignalStrength_1_2(int indicationType,
                                       android.hardware.radio.V1_2.SignalStrength signalStrength) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        SignalStrength ss = RILUtils.convertHalSignalStrength(signalStrength);
+        SignalStrength ss = new SignalStrength(signalStrength);
         // Note this is set to "verbose" because it happens frequently
         if (RIL.RILJ_LOGV) mRil.unsljLogvRet(RIL_UNSOL_SIGNAL_STRENGTH, ss);
 
@@ -308,9 +310,9 @@
     public void currentSignalStrength_1_4(int indicationType,
             android.hardware.radio.V1_4.SignalStrength signalStrength) {
 
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        SignalStrength ss = RILUtils.convertHalSignalStrength(signalStrength);
+        SignalStrength ss = new SignalStrength(signalStrength);
 
         if (RIL.RILJ_LOGV) mRil.unsljLogvRet(RIL_UNSOL_SIGNAL_STRENGTH, ss);
 
@@ -325,9 +327,9 @@
     public void currentSignalStrength_1_6(int indicationType,
             android.hardware.radio.V1_6.SignalStrength signalStrength) {
 
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        SignalStrength ss = RILUtils.convertHalSignalStrength(signalStrength);
+        SignalStrength ss = new SignalStrength(signalStrength);
 
         if (RIL.RILJ_LOGV) mRil.unsljLogvRet(RIL_UNSOL_SIGNAL_STRENGTH, ss);
 
@@ -341,7 +343,7 @@
      */
     public void currentPhysicalChannelConfigs_1_4(int indicationType,
             ArrayList<android.hardware.radio.V1_4.PhysicalChannelConfig> configs) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
         physicalChannelConfigsIndication(configs);
     }
 
@@ -350,7 +352,7 @@
      */
     public void currentPhysicalChannelConfigs_1_6(int indicationType,
             ArrayList<android.hardware.radio.V1_6.PhysicalChannelConfig> configs) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
         physicalChannelConfigsIndication(configs);
     }
 
@@ -359,7 +361,7 @@
      */
     public void currentPhysicalChannelConfigs(int indicationType,
             ArrayList<android.hardware.radio.V1_2.PhysicalChannelConfig> configs) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
         physicalChannelConfigsIndication(configs);
     }
 
@@ -368,7 +370,6 @@
      */
     public void currentEmergencyNumberList(int indicationType,
             ArrayList<android.hardware.radio.V1_4.EmergencyNumber> emergencyNumberList) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
         List<EmergencyNumber> response = new ArrayList<>(emergencyNumberList.size());
 
         for (android.hardware.radio.V1_4.EmergencyNumber emergencyNumberHal
@@ -422,7 +423,7 @@
     }
 
     public void suppSvcNotify(int indicationType, SuppSvcNotification suppSvcNotification) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         SuppServiceNotification notification = new SuppServiceNotification();
         notification.notificationType = suppSvcNotification.isMT ? 1 : 0;
@@ -439,7 +440,7 @@
     }
 
     public void stkSessionEnd(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_STK_SESSION_END);
 
@@ -449,7 +450,7 @@
     }
 
     public void stkProactiveCommand(int indicationType, String cmd) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_STK_PROACTIVE_COMMAND);
 
@@ -459,7 +460,7 @@
     }
 
     public void stkEventNotify(int indicationType, String cmd) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_STK_EVENT_NOTIFY);
 
@@ -469,7 +470,7 @@
     }
 
     public void stkCallSetup(int indicationType, long timeout) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_STK_CALL_SETUP, timeout);
 
@@ -479,7 +480,7 @@
     }
 
     public void simSmsStorageFull(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_SIM_SMS_STORAGE_FULL);
 
@@ -489,7 +490,7 @@
     }
 
     public void simRefresh(int indicationType, SimRefreshResult refreshResult) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         IccRefreshResponse response = new IccRefreshResponse();
         response.refreshResult = refreshResult.type;
@@ -502,7 +503,7 @@
     }
 
     public void callRing(int indicationType, boolean isGsm, CdmaSignalInfoRecord record) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         char response[] = null;
 
@@ -525,7 +526,7 @@
     }
 
     public void simStatusChanged(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED);
 
@@ -533,20 +534,22 @@
     }
 
     public void cdmaNewSms(int indicationType, CdmaSmsMessage msg) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_CDMA_NEW_SMS);
 
-        SmsMessage sms = new SmsMessage(RILUtils.convertHalCdmaSmsMessage(msg));
+        // todo: conversion from CdmaSmsMessage to SmsMessage should be contained in this class so
+        // that usage of auto-generated HAL classes is limited to this file
+        SmsMessage sms = SmsMessageConverter.newSmsMessageFromCdmaSmsMessage(msg);
         if (mRil.mCdmaSmsRegistrant != null) {
             mRil.mCdmaSmsRegistrant.notifyRegistrant(new AsyncResult(null, sms, null));
         }
     }
 
     public void newBroadcastSms(int indicationType, ArrayList<Byte> data) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        byte[] response = RILUtils.arrayListToPrimitiveArray(data);
+        byte response[] = RIL.arrayListToPrimitiveArray(data);
         if (RIL.RILJ_LOGD) {
             mRil.unsljLogvRet(RIL_UNSOL_RESPONSE_NEW_BROADCAST_SMS,
                     IccUtils.bytesToHexString(response));
@@ -558,7 +561,7 @@
     }
 
     public void cdmaRuimSmsStorageFull(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_CDMA_RUIM_SMS_STORAGE_FULL);
 
@@ -568,7 +571,7 @@
     }
 
     public void restrictedStateChanged(int indicationType, int state) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogvRet(RIL_UNSOL_RESTRICTED_STATE_CHANGED, state);
 
@@ -578,7 +581,7 @@
     }
 
     public void enterEmergencyCallbackMode(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE);
 
@@ -588,7 +591,7 @@
     }
 
     public void cdmaCallWaiting(int indicationType, CdmaCallWaiting callWaitingRecord) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         // todo: create a CdmaCallWaitingNotification constructor that takes in these fields to make
         // sure no fields are missing
@@ -612,7 +615,7 @@
     }
 
     public void cdmaOtaProvisionStatus(int indicationType, int status) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         int response[] = new int[1];
         response[0] = status;
@@ -624,7 +627,7 @@
 
     public void cdmaInfoRec(int indicationType,
                             android.hardware.radio.V1_0.CdmaInformationRecords records) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         int numberOfInfoRecs = records.infoRec.size();
         for (int i = 0; i < numberOfInfoRecs; i++) {
@@ -718,7 +721,7 @@
     }
 
     public void indicateRingbackTone(int indicationType, boolean start) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogvRet(RIL_UNSOL_RINGBACK_TONE, start);
 
@@ -726,7 +729,7 @@
     }
 
     public void resendIncallMute(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESEND_INCALL_MUTE);
 
@@ -734,7 +737,7 @@
     }
 
     public void cdmaSubscriptionSourceChanged(int indicationType, int cdmaSource) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         int response[] = new int[1];
         response[0] = cdmaSource;
@@ -746,19 +749,19 @@
     }
 
     public void cdmaPrlChanged(int indicationType, int version) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         int response[] = new int[1];
         response[0] = version;
 
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CDMA_PRL_CHANGED, response);
+        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOl_CDMA_PRL_CHANGED, response);
 
         mRil.mCdmaPrlChangedRegistrants.notifyRegistrants(
                 new AsyncResult (null, response, null));
     }
 
     public void exitEmergencyCallbackMode(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE);
 
@@ -766,7 +769,7 @@
     }
 
     public void rilConnected(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RIL_CONNECTED);
 
@@ -779,7 +782,7 @@
     }
 
     public void voiceRadioTechChanged(int indicationType, int rat) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         int response[] = new int[1];
         response[0] = rat;
@@ -792,48 +795,67 @@
 
     /** Get unsolicited message for cellInfoList */
     public void cellInfoList(int indicationType,
-            ArrayList<android.hardware.radio.V1_0.CellInfo> records) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
-        responseCellInfoList(records);
+                             ArrayList<android.hardware.radio.V1_0.CellInfo> records) {
+        mRil.processIndication(indicationType);
+
+        ArrayList<CellInfo> response = RIL.convertHalCellInfoList(records);
+
+        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CELL_INFO_LIST, response);
+
+        mRil.mRilCellInfoListRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
     }
 
     /** Get unsolicited message for cellInfoList using HAL V1_2 */
     public void cellInfoList_1_2(int indicationType,
-            ArrayList<android.hardware.radio.V1_2.CellInfo> records) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
-        responseCellInfoList(records);
+                                 ArrayList<android.hardware.radio.V1_2.CellInfo> records) {
+        mRil.processIndication(indicationType);
+
+        ArrayList<CellInfo> response = RIL.convertHalCellInfoList_1_2(records);
+
+        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CELL_INFO_LIST, response);
+
+        mRil.mRilCellInfoListRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
     }
 
     /** Get unsolicited message for cellInfoList using HAL V1_4 */
     public void cellInfoList_1_4(int indicationType,
-            ArrayList<android.hardware.radio.V1_4.CellInfo> records) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
-        responseCellInfoList(records);
+                                 ArrayList<android.hardware.radio.V1_4.CellInfo> records) {
+        mRil.processIndication(indicationType);
+
+        ArrayList<CellInfo> response = RIL.convertHalCellInfoList_1_4(records);
+
+        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CELL_INFO_LIST, response);
+
+        mRil.mRilCellInfoListRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
     }
 
     /** Get unsolicited message for cellInfoList using HAL V1_5 */
     public void cellInfoList_1_5(int indicationType,
             ArrayList<android.hardware.radio.V1_5.CellInfo> records) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
-        responseCellInfoList(records);
+        mRil.processIndication(indicationType);
+
+        ArrayList<CellInfo> response = RIL.convertHalCellInfoList_1_5(records);
+
+        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CELL_INFO_LIST, response);
+
+        mRil.mRilCellInfoListRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
     }
 
     /** Get unsolicited message for cellInfoList using HAL V1_5 */
     public void cellInfoList_1_6(int indicationType,
             ArrayList<android.hardware.radio.V1_6.CellInfo> records) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
-        responseCellInfoList(records);
-    }
+        mRil.processIndication(indicationType);
 
-    private void responseCellInfoList(ArrayList<? extends Object> records) {
-        ArrayList<CellInfo> response = RILUtils.convertHalCellInfoList((ArrayList<Object>) records);
+        ArrayList<CellInfo> response = RIL.convertHalCellInfoList_1_6(records);
+
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CELL_INFO_LIST, response);
+
         mRil.mRilCellInfoListRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
     }
 
     /** Get unsolicited message for uicc applications enablement changes. */
     public void uiccApplicationsEnablementChanged(int indicationType, boolean enabled) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) {
             mRil.unsljLogRet(RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED, enabled);
@@ -873,7 +895,7 @@
     }
 
     public void imsNetworkStateChanged(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_IMS_NETWORK_STATE_CHANGED);
 
@@ -881,7 +903,7 @@
     }
 
     public void subscriptionStatusChanged(int indicationType, boolean activate) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         int response[] = new int[1];
         response[0] = activate ? 1 : 0;
@@ -893,7 +915,7 @@
     }
 
     public void srvccStateNotify(int indicationType, int state) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         int response[] = new int[1];
         response[0] = state;
@@ -909,9 +931,9 @@
     public void hardwareConfigChanged(
             int indicationType,
             ArrayList<android.hardware.radio.V1_0.HardwareConfig> configs) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        ArrayList<HardwareConfig> response = RILUtils.convertHalHardwareConfigList(configs);
+        ArrayList<HardwareConfig> response = RIL.convertHalHwConfigList(configs, mRil);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_HARDWARE_CONFIG_CHANGED, response);
 
@@ -921,9 +943,9 @@
 
     public void radioCapabilityIndication(int indicationType,
                                           android.hardware.radio.V1_0.RadioCapability rc) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        RadioCapability response = RILUtils.convertHalRadioCapability(rc, mRil);
+        RadioCapability response = RIL.convertHalRadioCapability(rc, mRil);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_RADIO_CAPABILITY, response);
 
@@ -932,7 +954,7 @@
     }
 
     public void onSupplementaryServiceIndication(int indicationType, StkCcUnsolSsResult ss) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         int num;
         SsData ssData = new SsData();
@@ -980,7 +1002,7 @@
     }
 
     public void stkCallControlAlphaNotify(int indicationType, String alpha) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_STK_CC_ALPHA_NOTIFY, alpha);
 
@@ -990,9 +1012,9 @@
     }
 
     public void lceData(int indicationType, LceDataInfo lce) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        List<LinkCapacityEstimate> response = RILUtils.convertHalLceData(lce);
+        List<LinkCapacityEstimate> response = RIL.convertHalLceData(lce, mRil);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_LCEDATA_RECV, response);
 
@@ -1002,10 +1024,12 @@
     }
 
     public void pcoData(int indicationType, PcoDataInfo pco) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        PcoData response = new PcoData(pco.cid, pco.bearerProto, pco.pcoId,
-                RILUtils.arrayListToPrimitiveArray(pco.contents));
+        PcoData response = new PcoData(pco.cid,
+                pco.bearerProto,
+                pco.pcoId,
+                RIL.arrayListToPrimitiveArray(pco.contents));
 
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_PCO_DATA, response);
 
@@ -1013,7 +1037,7 @@
     }
 
     public void modemReset(int indicationType, String reason) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_MODEM_RESTART, reason);
 
@@ -1026,7 +1050,7 @@
      * @param indicationType RadioIndicationType
      */
     public void carrierInfoForImsiEncryption(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION, null);
 
@@ -1041,15 +1065,14 @@
      */
     public void keepaliveStatus(
             int indicationType, android.hardware.radio.V1_1.KeepaliveStatus halStatus) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) {
             mRil.unsljLogRet(RIL_UNSOL_KEEPALIVE_STATUS,
                     "handle=" + halStatus.sessionHandle + " code=" +  halStatus.code);
         }
 
-        KeepaliveStatus ks = new KeepaliveStatus(
-                halStatus.sessionHandle, halStatus.code);
+        KeepaliveStatus ks = new KeepaliveStatus(halStatus.sessionHandle, halStatus.code);
         mRil.mNattKeepaliveStatusRegistrants.notifyRegistrants(new AsyncResult(null, ks, null));
     }
 
@@ -1059,7 +1082,7 @@
      * @param indicationType RadioIndicationType
      */
     public void simPhonebookChanged(int indicationType) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) {
             mRil.unsljLog(RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_CHANGED);
@@ -1069,24 +1092,24 @@
     }
 
     /**
-     * Indicates the content of all the used records in the SIM phonebook.
+     * Indicates the content of all the used records in the SIM phonebook..
      * @param indicationType RadioIndicationType
-     * @param status Status of PbReceivedStatus
      * @param records Content of the SIM phonebook records
      */
     public void simPhonebookRecordsReceived(int indicationType, byte status,
             ArrayList<PhonebookRecordInfo> records) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        List<SimPhonebookRecord> simPhonebookRecords = new ArrayList<>();
+        List<SimPhonebookRecord> simPhonebookRecords = new ArrayList<SimPhonebookRecord>();
 
         for (PhonebookRecordInfo record : records) {
-            simPhonebookRecords.add(RILUtils.convertHalPhonebookRecordInfo(record));
+            simPhonebookRecords.add(new SimPhonebookRecord(record));
         }
 
         if (RIL.RILJ_LOGD) {
             mRil.unsljLogRet(RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_RECORDS_RECEIVED,
-                    "status = " + status + " received " + records.size() + " records");
+                    "status = " + status +
+                    " received " + records.size() + " records");
         }
 
         mRil.mSimPhonebookRecordsReceivedRegistrants.notifyRegistrants(
@@ -1108,15 +1131,15 @@
             android.hardware.radio.V1_5.CellIdentity cellIdentity, String chosenPlmn,
             @NetworkRegistrationInfo.Domain int domain,
             int causeCode, int additionalCauseCode) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
-        CellIdentity ci = RILUtils.convertHalCellIdentity(cellIdentity);
+        mRil.processIndication(indicationType);
+        CellIdentity ci = CellIdentity.create(cellIdentity);
         if (ci == null
                 || TextUtils.isEmpty(chosenPlmn)
                 || (domain & NetworkRegistrationInfo.DOMAIN_CS_PS) == 0
                 || (domain & ~NetworkRegistrationInfo.DOMAIN_CS_PS) != 0
                 || causeCode < 0 || additionalCauseCode < 0
                 || (causeCode == Integer.MAX_VALUE && additionalCauseCode == Integer.MAX_VALUE)) {
-            reportAnomaly(
+            AnomalyReporter.reportAnomaly(
                     UUID.fromString("f16e5703-6105-4341-9eb3-e68189156eb4"),
                             "Invalid registrationFailed indication");
 
@@ -1125,8 +1148,11 @@
         }
 
         mRil.mRegistrationFailedRegistrant.notifyRegistrant(
-                new AsyncResult(null, new RegistrationFailedEvent(ci, chosenPlmn, domain,
-                        causeCode, additionalCauseCode), null));
+                new AsyncResult(
+                        null,
+                        new RegistrationFailedEvent(ci, chosenPlmn, domain,
+                                causeCode, additionalCauseCode),
+                        null));
     }
 
     /**
@@ -1139,10 +1165,10 @@
     public void barringInfoChanged(int indicationType,
             android.hardware.radio.V1_5.CellIdentity cellIdentity,
             ArrayList<android.hardware.radio.V1_5.BarringInfo> barringInfos) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (cellIdentity == null || barringInfos == null) {
-            reportAnomaly(
+            AnomalyReporter.reportAnomaly(
                     UUID.fromString("645b16bb-c930-4c1c-9c5d-568696542e05"),
                             "Invalid barringInfoChanged indication");
 
@@ -1150,14 +1176,38 @@
             return;
         }
 
-        BarringInfo cbi = new BarringInfo(RILUtils.convertHalCellIdentity(cellIdentity),
-                RILUtils.convertHalBarringInfoList(barringInfos));
+        CellIdentity ci = CellIdentity.create(cellIdentity);
+        BarringInfo cbi = BarringInfo.create(cellIdentity, barringInfos);
 
         mRil.mBarringInfoChangedRegistrants.notifyRegistrants(
                 new AsyncResult(null, cbi, null));
     }
 
     /**
+     * @param stateInt
+     * @return {@link RadioPowerState RadioPowerState}
+     */
+    private @RadioPowerState int getRadioStateFromInt(int stateInt) {
+        int state;
+
+        switch(stateInt) {
+            case android.hardware.radio.V1_0.RadioState.OFF:
+                state = TelephonyManager.RADIO_POWER_OFF;
+                break;
+            case android.hardware.radio.V1_0.RadioState.UNAVAILABLE:
+                state = TelephonyManager.RADIO_POWER_UNAVAILABLE;
+                break;
+            case android.hardware.radio.V1_0.RadioState.ON:
+                state = TelephonyManager.RADIO_POWER_ON;
+                break;
+            default:
+                throw new RuntimeException("Unrecognized RadioState: " + stateInt);
+        }
+        return state;
+    }
+
+
+    /**
      * Set the frequency range or channel number from the physical channel config. Only one of them
      * is valid, we should set the other to the unknown value.
      * @param builder the builder of {@link PhysicalChannelConfig}.
@@ -1178,6 +1228,49 @@
         }
     }
 
+    private int convertConnectionStatusFromCellConnectionStatus(int status) {
+        switch (status) {
+            case CellConnectionStatus.PRIMARY_SERVING:
+                return PhysicalChannelConfig.CONNECTION_PRIMARY_SERVING;
+            case CellConnectionStatus.SECONDARY_SERVING:
+                return PhysicalChannelConfig.CONNECTION_SECONDARY_SERVING;
+            default:
+                // only PRIMARY_SERVING and SECONDARY_SERVING are supported.
+                mRil.riljLoge("Unsupported CellConnectionStatus in PhysicalChannelConfig: "
+                        + status);
+                return PhysicalChannelConfig.CONNECTION_UNKNOWN;
+        }
+    }
+
+    /**
+     * Set the band from the physical channel config.
+     *
+     * @param builder the builder of {@link PhysicalChannelConfig}.
+     * @param config physical channel config from ril.
+     */
+    public void setBandToBuilder(PhysicalChannelConfig.Builder builder,
+            android.hardware.radio.V1_6.PhysicalChannelConfig config) {
+
+        android.hardware.radio.V1_6.PhysicalChannelConfig.Band band = config.band;
+
+        switch (band.getDiscriminator()) {
+            case Band.hidl_discriminator.geranBand:
+                builder.setBand(band.geranBand());
+                break;
+            case Band.hidl_discriminator.utranBand:
+                builder.setBand(band.utranBand());
+                break;
+            case Band.hidl_discriminator.eutranBand:
+                builder.setBand(band.eutranBand());
+                break;
+            case Band.hidl_discriminator.ngranBand:
+                builder.setBand(band.ngranBand());
+                break;
+            default:
+                mRil.riljLoge("Unsupported band type " + band.getDiscriminator());
+        }
+    }
+
     private void physicalChannelConfigsIndication(List<? extends Object> configs) {
         List<PhysicalChannelConfig> response = new ArrayList<>(configs.size());
         try {
@@ -1187,8 +1280,8 @@
                             (android.hardware.radio.V1_2.PhysicalChannelConfig) obj;
 
                     response.add(new PhysicalChannelConfig.Builder()
-                            .setCellConnectionStatus(RILUtils.convertHalCellConnectionStatus(
-                                    config.status))
+                            .setCellConnectionStatus(
+                                    convertConnectionStatusFromCellConnectionStatus(config.status))
                             .setCellBandwidthDownlinkKhz(config.cellBandwidthDownlink)
                             .build());
                 } else if (obj instanceof android.hardware.radio.V1_4.PhysicalChannelConfig) {
@@ -1197,7 +1290,7 @@
                     PhysicalChannelConfig.Builder builder = new PhysicalChannelConfig.Builder();
                     setFrequencyRangeOrChannelNumber(builder, config);
                     response.add(builder.setCellConnectionStatus(
-                            RILUtils.convertHalCellConnectionStatus(config.base.status))
+                            convertConnectionStatusFromCellConnectionStatus(config.base.status))
                             .setCellBandwidthDownlinkKhz(config.base.cellBandwidthDownlink)
                             .setNetworkType(
                                     ServiceState.rilRadioTechnologyToNetworkType(config.rat))
@@ -1208,24 +1301,9 @@
                     android.hardware.radio.V1_6.PhysicalChannelConfig config =
                             (android.hardware.radio.V1_6.PhysicalChannelConfig) obj;
                     PhysicalChannelConfig.Builder builder = new PhysicalChannelConfig.Builder();
-                    switch (config.band.getDiscriminator()) {
-                        case Band.hidl_discriminator.geranBand:
-                            builder.setBand(config.band.geranBand());
-                            break;
-                        case Band.hidl_discriminator.utranBand:
-                            builder.setBand(config.band.utranBand());
-                            break;
-                        case Band.hidl_discriminator.eutranBand:
-                            builder.setBand(config.band.eutranBand());
-                            break;
-                        case Band.hidl_discriminator.ngranBand:
-                            builder.setBand(config.band.ngranBand());
-                            break;
-                        default:
-                            mRil.riljLoge("Unsupported band " + config.band.getDiscriminator());
-                    }
+                    setBandToBuilder(builder, config);
                     response.add(builder.setCellConnectionStatus(
-                            RILUtils.convertHalCellConnectionStatus(config.status))
+                            convertConnectionStatusFromCellConnectionStatus(config.status))
                             .setDownlinkChannelNumber(config.downlinkChannelNumber)
                             .setUplinkChannelNumber(config.uplinkChannelNumber)
                             .setCellBandwidthDownlinkKhz(config.cellBandwidthDownlinkKhz)
@@ -1240,8 +1318,9 @@
                 }
             }
         } catch (IllegalArgumentException iae) {
-            reportAnomaly(UUID.fromString("918f0970-9aa9-4bcd-a28e-e49a83fe77d5"),
-                    "RIL reported invalid PCC (HIDL)");
+            AnomalyReporter.reportAnomaly(
+                    UUID.fromString("918f0970-9aa9-4bcd-a28e-e49a83fe77d5"),
+                    "Invalid PhysicalChannelConfig reported by HAL");
             mRil.riljLoge("Invalid PhysicalChannelConfig " + iae);
             return;
         }
@@ -1253,33 +1332,32 @@
     }
 
     private void responseNetworkScan(int indicationType,
-            android.hardware.radio.V1_1.NetworkScanResult result) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+                                     android.hardware.radio.V1_1.NetworkScanResult result) {
+        mRil.processIndication(indicationType);
 
-        ArrayList<CellInfo> cellInfos =
-                RILUtils.convertHalCellInfoList(new ArrayList<>(result.networkInfos));
-        NetworkScanResult nsr = new NetworkScanResult(result.status, result.error, cellInfos);
+        NetworkScanResult nsr = null;
+        ArrayList<CellInfo> infos = RIL.convertHalCellInfoList(result.networkInfos);
+        nsr = new NetworkScanResult(result.status, result.error, infos);
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_NETWORK_SCAN_RESULT, nsr);
         mRil.mRilNetworkScanResultRegistrants.notifyRegistrants(new AsyncResult(null, nsr, null));
     }
 
     private void responseNetworkScan_1_2(int indicationType,
-            android.hardware.radio.V1_2.NetworkScanResult result) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+                                         android.hardware.radio.V1_2.NetworkScanResult result) {
+        mRil.processIndication(indicationType);
 
-        ArrayList<CellInfo> cellInfos =
-                RILUtils.convertHalCellInfoList(new ArrayList<>(result.networkInfos));
-        NetworkScanResult nsr = new NetworkScanResult(result.status, result.error, cellInfos);
+        NetworkScanResult nsr = null;
+        ArrayList<CellInfo> infos = RIL.convertHalCellInfoList_1_2(result.networkInfos);
+        nsr = new NetworkScanResult(result.status, result.error, infos);
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_NETWORK_SCAN_RESULT, nsr);
         mRil.mRilNetworkScanResultRegistrants.notifyRegistrants(new AsyncResult(null, nsr, null));
     }
 
     private void responseNetworkScan_1_4(int indicationType,
-            android.hardware.radio.V1_4.NetworkScanResult result) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+                                         android.hardware.radio.V1_4.NetworkScanResult result) {
+        mRil.processIndication(indicationType);
 
-        ArrayList<CellInfo> cellInfos =
-                RILUtils.convertHalCellInfoList(new ArrayList<>(result.networkInfos));
+        ArrayList<CellInfo> cellInfos = RIL.convertHalCellInfoList_1_4(result.networkInfos);
         NetworkScanResult nsr = new NetworkScanResult(result.status, result.error, cellInfos);
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_NETWORK_SCAN_RESULT, nsr);
         mRil.mRilNetworkScanResultRegistrants.notifyRegistrants(new AsyncResult(null, nsr, null));
@@ -1287,10 +1365,9 @@
 
     private void responseNetworkScan_1_5(int indicationType,
             android.hardware.radio.V1_5.NetworkScanResult result) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        ArrayList<CellInfo> cellInfos =
-                RILUtils.convertHalCellInfoList(new ArrayList<>(result.networkInfos));
+        ArrayList<CellInfo> cellInfos = RIL.convertHalCellInfoList_1_5(result.networkInfos);
         NetworkScanResult nsr = new NetworkScanResult(result.status, result.error, cellInfos);
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_NETWORK_SCAN_RESULT, nsr);
         mRil.mRilNetworkScanResultRegistrants.notifyRegistrants(new AsyncResult(null, nsr, null));
@@ -1298,37 +1375,30 @@
 
     private void responseNetworkScan_1_6(int indicationType,
             android.hardware.radio.V1_6.NetworkScanResult result) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
-        ArrayList<CellInfo> cellInfos =
-                RILUtils.convertHalCellInfoList(new ArrayList<>(result.networkInfos));
+        ArrayList<CellInfo> cellInfos = RIL.convertHalCellInfoList_1_6(result.networkInfos);
         NetworkScanResult nsr = new NetworkScanResult(result.status, result.error, cellInfos);
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_NETWORK_SCAN_RESULT, nsr);
         mRil.mRilNetworkScanResultRegistrants.notifyRegistrants(new AsyncResult(null, nsr, null));
     }
 
     private void responseDataCallListChanged(int indicationType, List<?> dcList) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_DATA_CALL_LIST_CHANGED, dcList);
 
-        ArrayList<DataCallResponse> response = RILUtils.convertHalDataCallResultList(dcList);
+        ArrayList<DataCallResponse> response = RIL.convertDataCallResultList(dcList);
         mRil.mDataCallListChangedRegistrants.notifyRegistrants(
                 new AsyncResult(null, response, null));
     }
 
     private void responseApnUnthrottled(int indicationType, String apn) {
-        mRil.processIndication(RIL.RADIO_SERVICE, indicationType);
+        mRil.processIndication(indicationType);
 
         if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_UNTHROTTLE_APN, apn);
 
         mRil.mApnUnthrottledRegistrants.notifyRegistrants(
                 new AsyncResult(null, apn, null));
     }
-
-    private void reportAnomaly(UUID uuid, String msg) {
-        Phone phone = mRil.mPhoneId == null ? null : PhoneFactory.getPhone(mRil.mPhoneId);
-        int carrierId = phone == null ? UNKNOWN_CARRIER_ID : phone.getCarrierId();
-        AnomalyReporter.reportAnomaly(uuid, msg, carrierId);
-    }
 }
diff --git a/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java b/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java
index 04c6b54..de62c70 100644
--- a/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java
+++ b/src/java/com/android/internal/telephony/RadioInterfaceCapabilityController.java
@@ -22,6 +22,7 @@
 import android.os.HandlerThread;
 import android.os.Looper;
 import android.os.Message;
+import android.os.storage.StorageManager;
 import android.util.ArraySet;
 import android.util.Log;
 
@@ -41,6 +42,7 @@
     private static RadioInterfaceCapabilityController sInstance;
     private final RadioConfig mRadioConfig;
     private final CommandsInterface mCommandsInterface;
+    private final boolean mRegisterForOn;
     private Set<String> mRadioInterfaceCapabilities;
     private final Object mLockRadioInterfaceCapabilities = new Object();
     private static final int EVENT_GET_HAL_DEVICE_CAPABILITIES_DONE = 100;
@@ -81,6 +83,7 @@
         super(looper);
         mRadioConfig = radioConfig;
         mCommandsInterface = commandsInterface;
+        mRegisterForOn = StorageManager.inCryptKeeperBounce();
         register();
     }
 
@@ -144,11 +147,19 @@
             return;
         }
 
-        mCommandsInterface.registerForAvailable(this, Phone.EVENT_RADIO_AVAILABLE, null);
+        if (mRegisterForOn) {
+            mCommandsInterface.registerForOn(this, Phone.EVENT_RADIO_ON, null);
+        } else {
+            mCommandsInterface.registerForAvailable(this, Phone.EVENT_RADIO_AVAILABLE, null);
+        }
     }
 
     private void unregister() {
-        mCommandsInterface.unregisterForAvailable(this);
+        if (mRegisterForOn) {
+            mCommandsInterface.unregisterForOn(this);
+        } else {
+            mCommandsInterface.unregisterForAvailable(this);
+        }
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/RadioMessagingProxy.java b/src/java/com/android/internal/telephony/RadioMessagingProxy.java
deleted file mode 100644
index e68e957..0000000
--- a/src/java/com/android/internal/telephony/RadioMessagingProxy.java
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.os.RemoteException;
-import android.telephony.Rlog;
-
-import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
-import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
-
-import java.util.ArrayList;
-
-/**
- * A holder for IRadioMessaging. Use getHidl to get IRadio 1.0 and call the HIDL implementations or
- * getAidl to get IRadioMessaging and call the AIDL implementations of the HAL APIs.
- */
-public class RadioMessagingProxy extends RadioServiceProxy {
-    private static final String TAG = "RadioMessagingProxy";
-    private volatile android.hardware.radio.messaging.IRadioMessaging mMessagingProxy = null;
-
-    /**
-     * Set IRadioMessaging as the AIDL implementation for RadioServiceProxy
-     * @param halVersion Radio HAL version
-     * @param messaging IRadioMessaging implementation
-     */
-    public void setAidl(HalVersion halVersion,
-            android.hardware.radio.messaging.IRadioMessaging messaging) {
-        mHalVersion = halVersion;
-        mMessagingProxy = messaging;
-        mIsAidl = true;
-        Rlog.d(TAG, "AIDL initialized");
-    }
-
-    /**
-     * Get the AIDL implementation of RadioMessagingProxy
-     * @return IRadioMessaging implementation
-     */
-    public android.hardware.radio.messaging.IRadioMessaging getAidl() {
-        return mMessagingProxy;
-    }
-
-    /**
-     * Reset RadioMessagingProxy
-     */
-    @Override
-    public void clear() {
-        super.clear();
-        mMessagingProxy = null;
-    }
-
-    /**
-     * Check whether a RadioMessaging implementation exists
-     * @return true if there is neither a HIDL nor AIDL implementation
-     */
-    @Override
-    public boolean isEmpty() {
-        return mRadioProxy == null && mMessagingProxy == null;
-    }
-
-    /**
-     * Call IRadioMessaging#acknowledgeIncomingGsmSmsWithPdu
-     * @param serial Serial number of request
-     * @param success True on successful receipt (RP-ACK) and false on failed receipt (RP-ERROR)
-     * @param ackPdu Acknowledgement TPDU in hexadecimal format
-     * @throws RemoteException
-     */
-    public void acknowledgeIncomingGsmSmsWithPdu(int serial, boolean success, String ackPdu)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.acknowledgeIncomingGsmSmsWithPdu(serial, success, ackPdu);
-        } else {
-            mRadioProxy.acknowledgeIncomingGsmSmsWithPdu(serial, success, ackPdu);
-        }
-    }
-
-    /**
-     * Calls IRadioMessaging#acknowledgeLastIncomingCdmaSms
-     * @param serial Serial number of request
-     * @param success True on successful receipt
-     * @param cause Failure cause if success is false
-     * @throws RemoteException
-     */
-    public void acknowledgeLastIncomingCdmaSms(int serial, boolean success, int cause)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            android.hardware.radio.messaging.CdmaSmsAck msg =
-                    new android.hardware.radio.messaging.CdmaSmsAck();
-            msg.errorClass = success;
-            msg.smsCauseCode = cause;
-            mMessagingProxy.acknowledgeLastIncomingCdmaSms(serial, msg);
-        } else {
-            android.hardware.radio.V1_0.CdmaSmsAck msg =
-                    new android.hardware.radio.V1_0.CdmaSmsAck();
-            msg.errorClass = success ? 0 : 1;
-            msg.smsCauseCode = cause;
-            mRadioProxy.acknowledgeLastIncomingCdmaSms(serial, msg);
-        }
-    }
-
-    /**
-     * Calls IRadioMessaging#acknowledgeLastIncomingGsmSms
-     * @param serial Serial number of request
-     * @param success True on successful receipt
-     * @param cause Failure cause if success is false
-     * @throws RemoteException
-     */
-    public void acknowledgeLastIncomingGsmSms(int serial, boolean success, int cause)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.acknowledgeLastIncomingGsmSms(serial, success, cause);
-        } else {
-            mRadioProxy.acknowledgeLastIncomingGsmSms(serial, success, cause);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#deleteSmsOnRuim
-     * @param serial Serial number of request
-     * @param index Record index of the message to delete
-     * @throws RemoteException
-     */
-    public void deleteSmsOnRuim(int serial, int index) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.deleteSmsOnRuim(serial, index);
-        } else {
-            mRadioProxy.deleteSmsOnRuim(serial, index);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#deleteSmsOnSim
-     * @param serial Serial number of request
-     * @param index Record index of the message to delete
-     * @throws RemoteException
-     */
-    public void deleteSmsOnSim(int serial, int index) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.deleteSmsOnSim(serial, index);
-        } else {
-            mRadioProxy.deleteSmsOnSim(serial, index);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#getCdmaBroadcastConfig
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getCdmaBroadcastConfig(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.getCdmaBroadcastConfig(serial);
-        } else {
-            mRadioProxy.getCdmaBroadcastConfig(serial);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#getGsmBroadcastConfig
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getGsmBroadcastConfig(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.getGsmBroadcastConfig(serial);
-        } else {
-            mRadioProxy.getGsmBroadcastConfig(serial);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#getSmscAddress
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getSmscAddress(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.getSmscAddress(serial);
-        } else {
-            mRadioProxy.getSmscAddress(serial);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#reportSmsMemoryStatus
-     * @param serial Serial number of request
-     * @param available Whether or not storage is available
-     * @throws RemoteException
-     */
-    public void reportSmsMemoryStatus(int serial, boolean available) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.reportSmsMemoryStatus(serial, available);
-        } else {
-            mRadioProxy.reportSmsMemoryStatus(serial, available);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#responseAcknowledgement
-     * @throws RemoteException
-     */
-    @Override
-    public void responseAcknowledgement() throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.responseAcknowledgement();
-        } else {
-            mRadioProxy.responseAcknowledgement();
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#sendCdmaSms
-     * @param serial Serial number of request
-     * @param pdu CDMA-SMS in internal pseudo-PDU format
-     * @throws RemoteException
-     */
-    public void sendCdmaSms(int serial, byte[] pdu) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.sendCdmaSms(serial, RILUtils.convertToHalCdmaSmsMessageAidl(pdu));
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).sendCdmaSms_1_6(
-                    serial, RILUtils.convertToHalCdmaSmsMessage(pdu));
-        } else {
-            mRadioProxy.sendCdmaSms(serial, RILUtils.convertToHalCdmaSmsMessage(pdu));
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#sendCdmaSmsExpectMore
-     * @param serial Serial number of request
-     * @param pdu CDMA-SMS in internal pseudo-PDU format
-     * @throws RemoteException
-     */
-    public void sendCdmaSmsExpectMore(int serial, byte[] pdu) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.sendCdmaSmsExpectMore(
-                    serial, RILUtils.convertToHalCdmaSmsMessageAidl(pdu));
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).sendCdmaSmsExpectMore_1_6(
-                    serial, RILUtils.convertToHalCdmaSmsMessage(pdu));
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).sendCdmaSmsExpectMore(
-                    serial, RILUtils.convertToHalCdmaSmsMessage(pdu));
-        } else {
-            mRadioProxy.sendCdmaSms(serial, RILUtils.convertToHalCdmaSmsMessage(pdu));
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#sendImsSms
-     * @param serial Serial number of request
-     * @param smscPdu SMSC address in PDU form GSM BCD format prefixed by a length byte
-     *                or NULL for default SMSC
-     * @param gsmPdu SMS in PDU format as an ASCII hex string less the SMSC address
-     * @param cdmaPdu CDMA-SMS in internal pseudo-PDU format
-     * @param retry Whether this is a retry; 0 == not retry, nonzero = retry
-     * @param messageRef MessageRef from RIL_SMS_RESPONSE corresponding to failed MO SMS
-     *                   if retry is nonzero
-     * @throws RemoteException
-     */
-    public void sendImsSms(int serial, String smscPdu, String gsmPdu, byte[] cdmaPdu, int retry,
-            int messageRef) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            android.hardware.radio.messaging.ImsSmsMessage msg =
-                    new android.hardware.radio.messaging.ImsSmsMessage();
-            msg.tech = android.hardware.radio.RadioTechnologyFamily.THREE_GPP;
-            msg.retry = (byte) retry >= 1;
-            msg.messageRef = messageRef;
-            if (gsmPdu != null) {
-                msg.gsmMessage = new android.hardware.radio.messaging.GsmSmsMessage[]{
-                        RILUtils.convertToHalGsmSmsMessageAidl(smscPdu, gsmPdu)};
-                msg.cdmaMessage = new android.hardware.radio.messaging.CdmaSmsMessage[0];
-            }
-            if (cdmaPdu != null) {
-                msg.gsmMessage = new android.hardware.radio.messaging.GsmSmsMessage[0];
-                msg.cdmaMessage = new android.hardware.radio.messaging.CdmaSmsMessage[]{
-                        RILUtils.convertToHalCdmaSmsMessageAidl(cdmaPdu)};
-            }
-            mMessagingProxy.sendImsSms(serial, msg);
-        } else {
-            android.hardware.radio.V1_0.ImsSmsMessage msg =
-                    new android.hardware.radio.V1_0.ImsSmsMessage();
-            msg.tech = android.hardware.radio.V1_0.RadioTechnologyFamily.THREE_GPP;
-            msg.retry = (byte) retry >= 1;
-            msg.messageRef = messageRef;
-            if (gsmPdu != null) {
-                msg.gsmMessage.add(RILUtils.convertToHalGsmSmsMessage(smscPdu, gsmPdu));
-            }
-            if (cdmaPdu != null) {
-                msg.cdmaMessage.add(RILUtils.convertToHalCdmaSmsMessage(cdmaPdu));
-            }
-            mRadioProxy.sendImsSms(serial, msg);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#sendSms
-     * @param serial Serial number of request
-     * @param smscPdu SMSC address in PDU form GSM BCD format prefixed by a length byte
-     *                or NULL for default SMSC
-     * @param pdu SMS in PDU format as an ASCII hex string less the SMSC address
-     * @throws RemoteException
-     */
-    public void sendSms(int serial, String smscPdu, String pdu) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.sendSms(serial, RILUtils.convertToHalGsmSmsMessageAidl(smscPdu, pdu));
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).sendSms_1_6(
-                    serial, RILUtils.convertToHalGsmSmsMessage(smscPdu, pdu));
-        } else {
-            mRadioProxy.sendSms(serial, RILUtils.convertToHalGsmSmsMessage(smscPdu, pdu));
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#sendSmsExpectMore
-     * @param serial Serial number of request
-     * @param smscPdu SMSC address in PDU form GSM BCD format prefixed by a length byte
-     *                or NULL for default SMSC
-     * @param pdu SMS in PDU format as an ASCII hex string less the SMSC address
-     * @throws RemoteException
-     */
-    public void sendSmsExpectMore(int serial, String smscPdu, String pdu) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.sendSmsExpectMore(serial,
-                    RILUtils.convertToHalGsmSmsMessageAidl(smscPdu, pdu));
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).sendSmsExpectMore_1_6(serial,
-                    RILUtils.convertToHalGsmSmsMessage(smscPdu, pdu));
-        } else {
-            mRadioProxy.sendSMSExpectMore(serial, RILUtils.convertToHalGsmSmsMessage(smscPdu, pdu));
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#setCdmaBroadcastActivation
-     * @param serial Serial number of request
-     * @param activate Whether to activate or turn off the reception of CDMA Cell Broadcast SMS;
-     *                 true = activate, false = turn off
-     * @throws RemoteException
-     */
-    public void setCdmaBroadcastActivation(int serial, boolean activate) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.setCdmaBroadcastActivation(serial, activate);
-        } else {
-            mRadioProxy.setCdmaBroadcastActivation(serial, activate);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#setCdmaBroadcastConfig
-     * @param serial Serial number of request
-     * @param configs Setting of CDMA cell broadcast config
-     * @throws RemoteException
-     */
-    public void setCdmaBroadcastConfig(int serial, CdmaSmsBroadcastConfigInfo[] configs)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            ArrayList<android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo> halConfigs =
-                    new ArrayList<>();
-            for (CdmaSmsBroadcastConfigInfo config: configs) {
-                for (int i = config.getFromServiceCategory(); i <= config.getToServiceCategory();
-                        i++) {
-                    android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo info =
-                            new android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo();
-                    info.serviceCategory = i;
-                    info.language = config.getLanguage();
-                    info.selected = config.isSelected();
-                    halConfigs.add(info);
-                }
-            }
-            mMessagingProxy.setCdmaBroadcastConfig(serial, halConfigs.stream().toArray(
-                    android.hardware.radio.messaging.CdmaBroadcastSmsConfigInfo[]::new));
-        } else {
-            ArrayList<android.hardware.radio.V1_0.CdmaBroadcastSmsConfigInfo> halConfigs =
-                    new ArrayList<>();
-            for (CdmaSmsBroadcastConfigInfo config: configs) {
-                for (int i = config.getFromServiceCategory(); i <= config.getToServiceCategory();
-                        i++) {
-                    android.hardware.radio.V1_0.CdmaBroadcastSmsConfigInfo info =
-                            new android.hardware.radio.V1_0.CdmaBroadcastSmsConfigInfo();
-                    info.serviceCategory = i;
-                    info.language = config.getLanguage();
-                    info.selected = config.isSelected();
-                    halConfigs.add(info);
-                }
-            }
-            mRadioProxy.setCdmaBroadcastConfig(serial, halConfigs);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#setGsmBroadcastActivation
-     * @param serial Serial number of request
-     * @param activate Whether to activate or turn off the reception of GSM/WCDMA Cell Broadcast
-     *                 SMS; true = activate, false = turn off
-     * @throws RemoteException
-     */
-    public void setGsmBroadcastActivation(int serial, boolean activate) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.setGsmBroadcastActivation(serial, activate);
-        } else {
-            mRadioProxy.setGsmBroadcastActivation(serial, activate);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#setGsmBroadcastConfig
-     * @param serial Serial number of request
-     * @param configInfo Setting of GSM/WCDMA cell broadcast config
-     * @throws RemoteException
-     */
-    public void setGsmBroadcastConfig(int serial, SmsBroadcastConfigInfo[] configInfo)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[] configs =
-                    new android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo[
-                            configInfo.length];
-            android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo info;
-            for (int i = 0; i < configInfo.length; i++) {
-                info = new android.hardware.radio.messaging.GsmBroadcastSmsConfigInfo();
-                info.fromServiceId = configInfo[i].getFromServiceId();
-                info.toServiceId = configInfo[i].getToServiceId();
-                info.fromCodeScheme = configInfo[i].getFromCodeScheme();
-                info.toCodeScheme = configInfo[i].getToCodeScheme();
-                info.selected = configInfo[i].isSelected();
-                configs[i] = info;
-            }
-            mMessagingProxy.setGsmBroadcastConfig(serial, configs);
-        } else {
-            ArrayList<android.hardware.radio.V1_0.GsmBroadcastSmsConfigInfo> configs =
-                    new ArrayList<>();
-            android.hardware.radio.V1_0.GsmBroadcastSmsConfigInfo info;
-            for (int i = 0; i < configInfo.length; i++) {
-                info = new android.hardware.radio.V1_0.GsmBroadcastSmsConfigInfo();
-                info.fromServiceId = configInfo[i].getFromServiceId();
-                info.toServiceId = configInfo[i].getToServiceId();
-                info.fromCodeScheme = configInfo[i].getFromCodeScheme();
-                info.toCodeScheme = configInfo[i].getToCodeScheme();
-                info.selected = configInfo[i].isSelected();
-                configs.add(info);
-            }
-            mRadioProxy.setGsmBroadcastConfig(serial, configs);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#setSmscAddress
-     * @param serial Serial number of request
-     * @param smsc Short Message Service Center address to set
-     * @throws RemoteException
-     */
-    public void setSmscAddress(int serial, String smsc) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mMessagingProxy.setSmscAddress(serial, smsc);
-        } else {
-            mRadioProxy.setSmscAddress(serial, smsc);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#writeSmsToRuim
-     * @param serial Serial number of request
-     * @param status Status of message on SIM. One of:
-     *               SmsManager.STATUS_ON_ICC_READ
-     *               SmsManager.STATUS_ON_ICC_UNREAD
-     *               SmsManager.STATUS_ON_ICC_SENT
-     *               SmsManager.STATUS_ON_ICC_UNSENT
-     * @param pdu SMS in PDU format as a byte array
-     * @throws RemoteException
-     */
-    public void writeSmsToRuim(int serial, int status, byte[] pdu) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            android.hardware.radio.messaging.CdmaSmsWriteArgs args =
-                    new android.hardware.radio.messaging.CdmaSmsWriteArgs();
-            args.status = RILUtils.convertToHalSmsWriteArgsStatusAidl(status);
-            args.message = RILUtils.convertToHalCdmaSmsMessageAidl(pdu);
-            mMessagingProxy.writeSmsToRuim(serial, args);
-        } else {
-            android.hardware.radio.V1_0.CdmaSmsWriteArgs args =
-                    new android.hardware.radio.V1_0.CdmaSmsWriteArgs();
-            args.status = RILUtils.convertToHalSmsWriteArgsStatus(status);
-            args.message = RILUtils.convertToHalCdmaSmsMessage(pdu);
-            mRadioProxy.writeSmsToRuim(serial, args);
-        }
-    }
-
-    /**
-     * Call IRadioMessaging#writeSmsToSim
-     * @param serial Serial number of request
-     * @param status Status of message on SIM. One of:
-     *               SmsManager.STATUS_ON_ICC_READ
-     *               SmsManager.STATUS_ON_ICC_UNREAD
-     *               SmsManager.STATUS_ON_ICC_SENT
-     *               SmsManager.STATUS_ON_ICC_UNSENT
-     * @param smsc SMSC address
-     * @param pdu SMS in PDU format as an ASCII hex string less the SMSC address
-     * @throws RemoteException
-     */
-    public void writeSmsToSim(int serial, int status, String smsc, String pdu)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            android.hardware.radio.messaging.SmsWriteArgs args =
-                    new android.hardware.radio.messaging.SmsWriteArgs();
-            args.status = RILUtils.convertToHalSmsWriteArgsStatusAidl(status);
-            args.smsc = smsc;
-            args.pdu = pdu;
-            mMessagingProxy.writeSmsToSim(serial, args);
-        } else {
-            android.hardware.radio.V1_0.SmsWriteArgs args =
-                    new android.hardware.radio.V1_0.SmsWriteArgs();
-            args.status = RILUtils.convertToHalSmsWriteArgsStatus(status);
-            args.smsc = smsc;
-            args.pdu = pdu;
-            mRadioProxy.writeSmsToSim(serial, args);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/telephony/RadioModemProxy.java b/src/java/com/android/internal/telephony/RadioModemProxy.java
deleted file mode 100644
index 7aaf727..0000000
--- a/src/java/com/android/internal/telephony/RadioModemProxy.java
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.os.RemoteException;
-import android.telephony.Rlog;
-
-/**
- * A holder for IRadioModem. Use getHidl to get IRadio 1.0 and call the HIDL implementations or
- * getAidl to get IRadioModem and call the AIDL implementations of the HAL APIs.
- */
-public class RadioModemProxy extends RadioServiceProxy {
-    private static final String TAG = "RadioModemProxy";
-    private volatile android.hardware.radio.modem.IRadioModem mModemProxy = null;
-
-    /**
-     * Set IRadioModem as the AIDL implementation for RadioServiceProxy
-     * @param halVersion Radio HAL version
-     * @param modem IRadioModem implementation
-     */
-    public void setAidl(HalVersion halVersion,
-            android.hardware.radio.modem.IRadioModem modem) {
-        mHalVersion = halVersion;
-        mModemProxy = modem;
-        mIsAidl = true;
-        Rlog.d(TAG, "AIDL initialized");
-    }
-
-    /**
-     * Get the AIDL implementation of RadioModemProxy
-     * @return IRadioModem implementation
-     */
-    public android.hardware.radio.modem.IRadioModem getAidl() {
-        return mModemProxy;
-    }
-
-    /**
-     * Reset RadioModemProxy
-     */
-    @Override
-    public void clear() {
-        super.clear();
-        mModemProxy = null;
-    }
-
-    /**
-     * Check whether a RadioModem implementation exists
-     * @return true if there is neither a HIDL nor AIDL implementation
-     */
-    @Override
-    public boolean isEmpty() {
-        return mRadioProxy == null && mModemProxy == null;
-    }
-
-    /**
-     * Call IRadioModem#enableModem
-     * @param serial Serial number of request
-     * @param on Whether to enable or disable the modem
-     * @throws RemoteException
-     */
-    public void enableModem(int serial, boolean on) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_3)) return;
-        if (isAidl()) {
-            mModemProxy.enableModem(serial, on);
-        } else {
-            ((android.hardware.radio.V1_3.IRadio) mRadioProxy).enableModem(serial, on);
-        }
-    }
-
-    /**
-     * Call IRadioModem#getBasebandVersion
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getBasebandVersion(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mModemProxy.getBasebandVersion(serial);
-        } else {
-            mRadioProxy.getBasebandVersion(serial);
-        }
-    }
-
-    /**
-     * Call IRadioModem#getDeviceIdentity
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getDeviceIdentity(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mModemProxy.getDeviceIdentity(serial);
-        } else {
-            mRadioProxy.getDeviceIdentity(serial);
-        }
-    }
-
-    /**
-     * Call IRadioModem#getHardwareConfig
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getHardwareConfig(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mModemProxy.getHardwareConfig(serial);
-        } else {
-            mRadioProxy.getHardwareConfig(serial);
-        }
-    }
-
-    /**
-     * Call IRadioModem#getModemActivityInfo
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getModemActivityInfo(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mModemProxy.getModemActivityInfo(serial);
-        } else {
-            mRadioProxy.getModemActivityInfo(serial);
-        }
-    }
-
-    /**
-     * Call IRadioModem#getModemStackStatus
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getModemStackStatus(int serial) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_3)) return;
-        if (isAidl()) {
-            mModemProxy.getModemStackStatus(serial);
-        } else {
-            ((android.hardware.radio.V1_3.IRadio) mRadioProxy).getModemStackStatus(serial);
-        }
-    }
-
-    /**
-     * Call IRadioModem#getRadioCapability
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getRadioCapability(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mModemProxy.getRadioCapability(serial);
-        } else {
-            mRadioProxy.getRadioCapability(serial);
-        }
-    }
-
-    /**
-     * Call IRadioModem#nvReadItem
-     * @param serial Serial number of request
-     * @param itemId ID of the item to read
-     * @throws RemoteException
-     */
-    public void nvReadItem(int serial, int itemId) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mModemProxy.nvReadItem(serial, itemId);
-        } else {
-            mRadioProxy.nvReadItem(serial, itemId);
-        }
-    }
-
-    /**
-     * Call IRadioModem#nvResetConfig
-     * @param serial Serial number of request
-     * @param resetType Reset type; 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
-     * @throws RemoteException
-     */
-    public void nvResetConfig(int serial, int resetType) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mModemProxy.nvResetConfig(serial, RILUtils.convertToHalResetNvTypeAidl(resetType));
-        } else {
-            mRadioProxy.nvResetConfig(serial, RILUtils.convertToHalResetNvType(resetType));
-        }
-    }
-
-    /**
-     * Call IRadioModem#nvWriteCdmaPrl
-     * @param serial Serial number of request
-     * @param prl Preferred roaming list as a byte array
-     * @throws RemoteException
-     */
-    public void nvWriteCdmaPrl(int serial, byte[] prl) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mModemProxy.nvWriteCdmaPrl(serial, prl);
-        } else {
-            mRadioProxy.nvWriteCdmaPrl(serial, RILUtils.primitiveArrayToArrayList(prl));
-        }
-    }
-
-    /**
-     * Call IRadioModem#nvWriteItem
-     * @param serial Serial number of request
-     * @param itemId ID of the item to write
-     * @param itemValue Value to write as a String
-     * @throws RemoteException
-     */
-    public void nvWriteItem(int serial, int itemId, String itemValue) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            android.hardware.radio.modem.NvWriteItem item =
-                    new android.hardware.radio.modem.NvWriteItem();
-            item.itemId = itemId;
-            item.value = itemValue;
-            mModemProxy.nvWriteItem(serial, item);
-        } else {
-            android.hardware.radio.V1_0.NvWriteItem item =
-                    new android.hardware.radio.V1_0.NvWriteItem();
-            item.itemId = itemId;
-            item.value = itemValue;
-            mRadioProxy.nvWriteItem(serial, item);
-        }
-    }
-
-    /**
-     * Call IRadioModem#requestShutdown
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void requestShutdown(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mModemProxy.requestShutdown(serial);
-        } else {
-            mRadioProxy.requestShutdown(serial);
-        }
-    }
-
-    /**
-     * Call IRadioModem#responseAcknowledgement
-     * @throws RemoteException
-     */
-    @Override
-    public void responseAcknowledgement() throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mModemProxy.responseAcknowledgement();
-        } else {
-            mRadioProxy.responseAcknowledgement();
-        }
-    }
-
-    /**
-     * Call IRadioModem#sendDeviceState
-     * @param serial Serial number of request
-     * @param deviceStateType Device state type
-     * @param state True if enabled and false if disabled
-     * @throws RemoteException
-     */
-    public void sendDeviceState(int serial, int deviceStateType, boolean state)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mModemProxy.sendDeviceState(serial, deviceStateType, state);
-        } else {
-            mRadioProxy.sendDeviceState(serial, deviceStateType, state);
-        }
-    }
-
-    /**
-     * Call IRadioModem#setRadioCapability
-     * @param serial Serial number of request
-     * @param rc The phone radio capability defined in RadioCapability
-     *           It's a input object used to transfer parameter to logic modem
-     * @throws RemoteException
-     */
-    public void setRadioCapability(int serial, RadioCapability rc) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            android.hardware.radio.modem.RadioCapability halRc =
-                    new android.hardware.radio.modem.RadioCapability();
-            halRc.session = rc.getSession();
-            halRc.phase = rc.getPhase();
-            halRc.raf = rc.getRadioAccessFamily();
-            halRc.logicalModemUuid = RILUtils.convertNullToEmptyString(rc.getLogicalModemUuid());
-            halRc.status = rc.getStatus();
-            mModemProxy.setRadioCapability(serial, halRc);
-        } else {
-            android.hardware.radio.V1_0.RadioCapability halRc =
-                    new android.hardware.radio.V1_0.RadioCapability();
-            halRc.session = rc.getSession();
-            halRc.phase = rc.getPhase();
-            halRc.raf = rc.getRadioAccessFamily();
-            halRc.logicalModemUuid = RILUtils.convertNullToEmptyString(rc.getLogicalModemUuid());
-            halRc.status = rc.getStatus();
-            mRadioProxy.setRadioCapability(serial, halRc);
-        }
-    }
-
-    /**
-     * Call IRadioModem#setRadioPower
-     * @param serial Serial number of request
-     * @param powerOn True to turn on radio and false to turn off
-     * @param forEmergencyCall Indicates that this request is due to emergency call
-     *                         No effect if powerOn is false
-     * @param preferredForEmergencyCall Whether or not the following emergency call will be sent
-     *                                  on this modem
-     *                                  No effect if powerOn or forEmergencyCall is false
-     * @throws RemoteException
-     */
-    public void setRadioPower(int serial, boolean powerOn, boolean forEmergencyCall,
-            boolean preferredForEmergencyCall) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mModemProxy.setRadioPower(serial, powerOn, forEmergencyCall, preferredForEmergencyCall);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).setRadioPower_1_6(serial, powerOn,
-                    forEmergencyCall, preferredForEmergencyCall);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).setRadioPower_1_5(serial, powerOn,
-                    forEmergencyCall, preferredForEmergencyCall);
-        } else {
-            mRadioProxy.setRadioPower(serial, powerOn);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/telephony/RadioNetworkProxy.java b/src/java/com/android/internal/telephony/RadioNetworkProxy.java
deleted file mode 100644
index b881035..0000000
--- a/src/java/com/android/internal/telephony/RadioNetworkProxy.java
+++ /dev/null
@@ -1,831 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static com.android.internal.telephony.RILConstants.REQUEST_NOT_SUPPORTED;
-
-import android.annotation.NonNull;
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.RemoteException;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.NetworkScanRequest;
-import android.telephony.RadioAccessSpecifier;
-import android.telephony.Rlog;
-import android.telephony.SignalThresholdInfo;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * A holder for IRadioNetwork. Use getHidl to get IRadio 1.0 and call the HIDL implementations or
- * getAidl to get IRadioNetwork and call the AIDL implementations of the HAL APIs.
- */
-public class RadioNetworkProxy extends RadioServiceProxy {
-    private static final String TAG = "RadioNetworkProxy";
-    private volatile android.hardware.radio.network.IRadioNetwork mNetworkProxy = null;
-
-    private static final int INDICATION_FILTERS_ALL_V1_0 =
-            android.hardware.radio.V1_5.IndicationFilter.SIGNAL_STRENGTH
-                    | android.hardware.radio.V1_5.IndicationFilter.FULL_NETWORK_STATE
-                    | android.hardware.radio.V1_5.IndicationFilter.DATA_CALL_DORMANCY_CHANGED;
-    private static final int INDICATION_FILTERS_ALL_V1_2 =
-            INDICATION_FILTERS_ALL_V1_0
-                    | android.hardware.radio.V1_5.IndicationFilter.LINK_CAPACITY_ESTIMATE
-                    | android.hardware.radio.V1_5.IndicationFilter.PHYSICAL_CHANNEL_CONFIG;
-    private static final int INDICATION_FILTERS_ALL_V1_5 =
-            INDICATION_FILTERS_ALL_V1_2
-                    | android.hardware.radio.V1_5.IndicationFilter.REGISTRATION_FAILURE
-                    | android.hardware.radio.V1_5.IndicationFilter.BARRING_INFO;
-    private static final int INDICATION_FILTERS_ALL_AIDL =
-            android.hardware.radio.network.IndicationFilter.SIGNAL_STRENGTH
-                    | android.hardware.radio.network.IndicationFilter.FULL_NETWORK_STATE
-                    | android.hardware.radio.network.IndicationFilter.DATA_CALL_DORMANCY_CHANGED
-                    | android.hardware.radio.network.IndicationFilter.LINK_CAPACITY_ESTIMATE
-                    | android.hardware.radio.network.IndicationFilter.PHYSICAL_CHANNEL_CONFIG
-                    | android.hardware.radio.network.IndicationFilter.REGISTRATION_FAILURE
-                    | android.hardware.radio.network.IndicationFilter.BARRING_INFO;
-
-    /**
-     * Set IRadioNetwork as the AIDL implementation for RadioServiceProxy
-     * @param halVersion Radio HAL version
-     * @param network IRadioNetwork implementation
-     */
-    public void setAidl(HalVersion halVersion,
-            android.hardware.radio.network.IRadioNetwork network) {
-        mHalVersion = halVersion;
-        mNetworkProxy = network;
-        mIsAidl = true;
-        Rlog.d(TAG, "AIDL initialized");
-    }
-
-    /**
-     * Get the AIDL implementation of RadioNetworkProxy
-     * @return IRadioNetwork implementation
-     */
-    public android.hardware.radio.network.IRadioNetwork getAidl() {
-        return mNetworkProxy;
-    }
-
-    /**
-     * Reset RadioNetworkProxy
-     */
-    @Override
-    public void clear() {
-        super.clear();
-        mNetworkProxy = null;
-    }
-
-    /**
-     * Check whether a RadioNetwork implementation exists
-     * @return true if there is neither a HIDL nor AIDL implementation
-     */
-    @Override
-    public boolean isEmpty() {
-        return mRadioProxy == null && mNetworkProxy == null;
-    }
-
-    /**
-     * Call IRadioNetwork#getAllowedNetworkTypesBitmap
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getAllowedNetworkTypesBitmap(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.getAllowedNetworkTypesBitmap(serial);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getAllowedNetworkTypesBitmap(serial);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_4)) {
-            ((android.hardware.radio.V1_4.IRadio) mRadioProxy)
-                    .getPreferredNetworkTypeBitmap(serial);
-        } else {
-            mRadioProxy.getPreferredNetworkType(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getAvailableBandModes
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getAvailableBandModes(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.getAvailableBandModes(serial);
-        } else {
-            mRadioProxy.getAvailableBandModes(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getAvailableNetworks
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getAvailableNetworks(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.getAvailableNetworks(serial);
-        } else {
-            mRadioProxy.getAvailableNetworks(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getBarringInfo
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getBarringInfo(int serial) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_5)) return;
-        if (isAidl()) {
-            mNetworkProxy.getBarringInfo(serial);
-        } else {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).getBarringInfo(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getCdmaRoamingPreference
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getCdmaRoamingPreference(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.getCdmaRoamingPreference(serial);
-        } else {
-            mRadioProxy.getCdmaRoamingPreference(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getCellInfoList
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getCellInfoList(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.getCellInfoList(serial);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getCellInfoList_1_6(serial);
-        } else {
-            mRadioProxy.getCellInfoList(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getDataRegistrationState
-     * @param serial Serial number of request
-     * @param overrideHalVersion Radio HAL fallback compatibility override
-     * @throws RemoteException
-     */
-    public void getDataRegistrationState(int serial, HalVersion overrideHalVersion)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.getDataRegistrationState(serial);
-        } else if ((overrideHalVersion == null
-                || overrideHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6))
-                && mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getDataRegistrationState_1_6(serial);
-        } else if ((overrideHalVersion == null
-                || overrideHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5))
-                && mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).getDataRegistrationState_1_5(serial);
-        } else {
-            mRadioProxy.getDataRegistrationState(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getImsRegistrationState
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getImsRegistrationState(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.getImsRegistrationState(serial);
-        } else {
-            mRadioProxy.getImsRegistrationState(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getNetworkSelectionMode
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getNetworkSelectionMode(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.getNetworkSelectionMode(serial);
-        } else {
-            mRadioProxy.getNetworkSelectionMode(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getOperator
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getOperator(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.getOperator(serial);
-        } else {
-            mRadioProxy.getOperator(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getSignalStrength
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getSignalStrength(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.getSignalStrength(serial);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getSignalStrength_1_6(serial);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_4)) {
-            ((android.hardware.radio.V1_4.IRadio) mRadioProxy).getSignalStrength_1_4(serial);
-        } else {
-            mRadioProxy.getSignalStrength(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getSystemSelectionChannels
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getSystemSelectionChannels(int serial) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (isAidl()) {
-            mNetworkProxy.getSystemSelectionChannels(serial);
-        } else {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getSystemSelectionChannels(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getVoiceRadioTechnology
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getVoiceRadioTechnology(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.getVoiceRadioTechnology(serial);
-        } else {
-            mRadioProxy.getVoiceRadioTechnology(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getVoiceRegistrationState
-     * @param serial Serial number of request
-     * @param overrideHalVersion Radio HAL fallback compatibility override
-     * @throws RemoteException
-     */
-    public void getVoiceRegistrationState(int serial, HalVersion overrideHalVersion)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.getVoiceRegistrationState(serial);
-        } else if ((overrideHalVersion == null
-                || overrideHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6))
-                && mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy)
-                    .getVoiceRegistrationState_1_6(serial);
-        } else if ((overrideHalVersion == null
-                || overrideHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5))
-                && mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy)
-                    .getVoiceRegistrationState_1_5(serial);
-        } else {
-            mRadioProxy.getVoiceRegistrationState(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#isNrDualConnectivityEnabled
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void isNrDualConnectivityEnabled(int serial) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (isAidl()) {
-            mNetworkProxy.isNrDualConnectivityEnabled(serial);
-        } else {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).isNrDualConnectivityEnabled(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#responseAcknowledgement
-     * @throws RemoteException
-     */
-    @Override
-    public void responseAcknowledgement() throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.responseAcknowledgement();
-        } else {
-            mRadioProxy.responseAcknowledgement();
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setAllowedNetworkTypesBitmap
-     * @param serial Serial number of request
-     * @param networkTypeBitmask Network type bitmask to set
-     * @throws RemoteException
-     */
-    public void setAllowedNetworkTypesBitmap(int serial, int networkTypeBitmask)
-            throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (isAidl()) {
-            mNetworkProxy.setAllowedNetworkTypesBitmap(serial,
-                    RILUtils.convertToHalRadioAccessFamilyAidl(networkTypeBitmask));
-        } else {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).setAllowedNetworkTypesBitmap(
-                    serial, RILUtils.convertToHalRadioAccessFamily(networkTypeBitmask));
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setPreferredNetworkTypeBitmap
-     * @param serial Serial number of request
-     * @param networkTypesBitmask Preferred network types bitmask to set
-     * @throws RemoteException
-     */
-    public void setPreferredNetworkTypeBitmap(int serial, int networkTypesBitmask)
-            throws RemoteException {
-        if (isEmpty() || mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_4)) {
-            ((android.hardware.radio.V1_4.IRadio) mRadioProxy).setPreferredNetworkTypeBitmap(serial,
-                    RILUtils.convertToHalRadioAccessFamily(networkTypesBitmask));
-        } else {
-            mRadioProxy.setPreferredNetworkType(serial, networkTypesBitmask);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setBandMode
-     * @param serial Serial number of request
-     * @param bandMode One of BM_*_BAND
-     * @throws RemoteException
-     */
-    public void setBandMode(int serial, int bandMode) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.setBandMode(serial, bandMode);
-        } else {
-            mRadioProxy.setBandMode(serial, bandMode);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setBarringPassword
-     * @param serial Serial number of request
-     * @param facility Facility string code
-     * @param oldPassword Old password
-     * @param newPassword New password
-     * @throws RemoteException
-     */
-    public void setBarringPassword(int serial, String facility, String oldPassword,
-            String newPassword) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.setBarringPassword(serial, facility, oldPassword, newPassword);
-        } else {
-            mRadioProxy.setBarringPassword(serial, facility, oldPassword, newPassword);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setCdmaRoamingPreference
-     * @param serial Serial number of request
-     * @param cdmaRoamingType One of CDMA_RM_*
-     * @throws RemoteException
-     */
-    public void setCdmaRoamingPreference(int serial, int cdmaRoamingType) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.setCdmaRoamingPreference(serial, cdmaRoamingType);
-        } else {
-            mRadioProxy.setCdmaRoamingPreference(serial, cdmaRoamingType);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setCellInfoListRate
-     * @param serial Serial number of request
-     * @param rate Minimum time in milliseconds to indicate time between unsolicited cellInfoList()
-     * @throws RemoteException
-     */
-    public void setCellInfoListRate(int serial, int rate) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.setCellInfoListRate(serial, rate);
-        } else {
-            mRadioProxy.setCellInfoListRate(serial, rate);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setIndicationFilter
-     * @param serial Serial number of request
-     * @param filter Unsolicited response filter
-     * @throws RemoteException
-     */
-    public void setIndicationFilter(int serial, int filter) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.setIndicationFilter(serial, filter & INDICATION_FILTERS_ALL_AIDL);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).setIndicationFilter_1_5(serial,
-                    filter & INDICATION_FILTERS_ALL_V1_5);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_2)) {
-            ((android.hardware.radio.V1_2.IRadio) mRadioProxy).setIndicationFilter_1_2(serial,
-                    filter & INDICATION_FILTERS_ALL_V1_2);
-        } else {
-            mRadioProxy.setIndicationFilter(serial, filter & INDICATION_FILTERS_ALL_V1_0);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setLinkCapacityReportingCriteria
-     * @param serial Serial number of request
-     * @param hysteresisMs A hysteresis time in milliseconds. A value of 0 disables hysteresis.
-     * @param hysteresisDlKbps An interval in kbps defining the required magnitude change between DL
-     *                         reports. A value of 0 disables hysteresis
-     * @param hysteresisUlKbps An interval in kbps defining the required magnitude change between UL
-     *                         reports. A value of 0 disables hysteresis
-     * @param thresholdsDlKbps An array of trigger thresholds in kbps for DL reports. A size of 0
-     *                         disables thresholds
-     * @param thresholdsUlKbps An array of trigger thresholds in kbps for UL reports. A size of 0
-     *                         disables thresholds
-     * @param ran RadioAccessNetwork for which to apply criteria
-     * @throws RemoteException
-     */
-    public void setLinkCapacityReportingCriteria(int serial, int hysteresisMs, int hysteresisDlKbps,
-            int hysteresisUlKbps, int[] thresholdsDlKbps, int[] thresholdsUlKbps, int ran)
-            throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_2)) return;
-        if (isAidl()) {
-            mNetworkProxy.setLinkCapacityReportingCriteria(serial, hysteresisMs, hysteresisDlKbps,
-                    hysteresisUlKbps, thresholdsDlKbps, thresholdsUlKbps,
-                    RILUtils.convertToHalAccessNetworkAidl(ran));
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).setLinkCapacityReportingCriteria_1_5(
-                    serial, hysteresisMs, hysteresisDlKbps, hysteresisUlKbps,
-                    RILUtils.primitiveArrayToArrayList(thresholdsDlKbps),
-                    RILUtils.primitiveArrayToArrayList(thresholdsUlKbps),
-                    RILUtils.convertToHalAccessNetwork(ran));
-        } else {
-            if (ran == AccessNetworkConstants.AccessNetworkType.NGRAN) {
-                throw new RuntimeException("NGRAN unsupported on IRadio version: " + mHalVersion);
-            }
-            ((android.hardware.radio.V1_2.IRadio) mRadioProxy).setLinkCapacityReportingCriteria(
-                    serial, hysteresisMs, hysteresisDlKbps, hysteresisUlKbps,
-                    RILUtils.primitiveArrayToArrayList(thresholdsDlKbps),
-                    RILUtils.primitiveArrayToArrayList(thresholdsUlKbps),
-                    RILUtils.convertToHalAccessNetwork(ran));
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setLocationUpdates
-     * @param serial Serial number of request
-     * @param enable Whether to enable or disable network state change notifications when location
-     *               information (lac and/or cid) has changed
-     * @throws RemoteException
-     */
-    public void setLocationUpdates(int serial, boolean enable) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.setLocationUpdates(serial, enable);
-        } else {
-            mRadioProxy.setLocationUpdates(serial, enable);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setNetworkSelectionModeAutomatic
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void setNetworkSelectionModeAutomatic(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.setNetworkSelectionModeAutomatic(serial);
-        } else {
-            mRadioProxy.setNetworkSelectionModeAutomatic(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setNetworkSelectionModeManual
-     * @param serial Serial number of request
-     * @param operatorNumeric PLMN ID of the network to select
-     * @param ran Radio access network type
-     * @throws RemoteException
-     */
-    public void setNetworkSelectionModeManual(int serial, String operatorNumeric, int ran)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.setNetworkSelectionModeManual(serial, operatorNumeric,
-                    RILUtils.convertToHalAccessNetworkAidl(ran));
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).setNetworkSelectionModeManual_1_5(
-                    serial, operatorNumeric, RILUtils.convertToHalRadioAccessNetworks(ran));
-        } else {
-            mRadioProxy.setNetworkSelectionModeManual(serial, operatorNumeric);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setNrDualConnectivityState
-     * @param serial Serial number of request
-     * @param nrDualConnectivityState Expected NR dual connectivity state
-     * @throws RemoteException
-     */
-    public void setNrDualConnectivityState(int serial, byte nrDualConnectivityState)
-            throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (isAidl()) {
-            mNetworkProxy.setNrDualConnectivityState(serial, nrDualConnectivityState);
-        } else {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).setNrDualConnectivityState(
-                    serial, nrDualConnectivityState);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setSignalStrengthReportingCriteria
-     * @param serial Serial number of request
-     * @param signalThresholdInfos a list of {@link SignalThresholdInfo} to set with.
-     * @throws RemoteException
-     */
-    public void setSignalStrengthReportingCriteria(int serial,
-            @NonNull List<SignalThresholdInfo> signalThresholdInfos) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_2)) return;
-        if (isAidl()) {
-            android.hardware.radio.network.SignalThresholdInfo[] halSignalThresholdsInfos =
-            new android.hardware.radio.network.SignalThresholdInfo[signalThresholdInfos.size()];
-            for (int i = 0; i < signalThresholdInfos.size(); i++) {
-                halSignalThresholdsInfos[i] = RILUtils.convertToHalSignalThresholdInfoAidl(
-                        signalThresholdInfos.get(i));
-            }
-            mNetworkProxy.setSignalStrengthReportingCriteria(serial, halSignalThresholdsInfos);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            for (SignalThresholdInfo signalThresholdInfo : signalThresholdInfos) {
-                ((android.hardware.radio.V1_5.IRadio) mRadioProxy)
-                        .setSignalStrengthReportingCriteria_1_5(serial,
-                                RILUtils.convertToHalSignalThresholdInfo(signalThresholdInfo),
-                                RILUtils.convertToHalAccessNetwork(
-                                        signalThresholdInfo.getRadioAccessNetworkType()));
-            }
-        } else {
-            for (SignalThresholdInfo signalThresholdInfo : signalThresholdInfos) {
-                ((android.hardware.radio.V1_2.IRadio) mRadioProxy)
-                        .setSignalStrengthReportingCriteria(serial,
-                                signalThresholdInfo.getHysteresisMs(),
-                                signalThresholdInfo.getHysteresisDb(),
-                                RILUtils.primitiveArrayToArrayList(
-                                        signalThresholdInfo.getThresholds()),
-                                RILUtils.convertToHalAccessNetwork(
-                                        signalThresholdInfo.getRadioAccessNetworkType()));
-            }
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setSuppServiceNotifications
-     * @param serial Serial number of request
-     * @param enable True to enable notifications, false to disable
-     * @throws RemoteException
-     */
-    public void setSuppServiceNotifications(int serial, boolean enable) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.setSuppServiceNotifications(serial, enable);
-        } else {
-            mRadioProxy.setSuppServiceNotifications(serial, enable);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#setSystemSelectionChannels
-     * @param serial Serial number of request
-     * @param specifiers Which bands to scan
-     * @throws RemoteException
-     */
-    public void setSystemSelectionChannels(int serial, List<RadioAccessSpecifier> specifiers)
-            throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_3)) return;
-        if (isAidl()) {
-            mNetworkProxy.setSystemSelectionChannels(serial, !specifiers.isEmpty(),
-                    specifiers.stream().map(RILUtils::convertToHalRadioAccessSpecifierAidl)
-                            .toArray(android.hardware.radio.network.RadioAccessSpecifier[]::new));
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).setSystemSelectionChannels_1_5(
-                    serial, !specifiers.isEmpty(), specifiers.stream()
-                            .map(RILUtils::convertToHalRadioAccessSpecifier15)
-                            .collect(Collectors.toCollection(ArrayList::new)));
-        } else {
-            ((android.hardware.radio.V1_3.IRadio) mRadioProxy).setSystemSelectionChannels(
-                    serial, !specifiers.isEmpty(), specifiers.stream()
-                            .map(RILUtils::convertToHalRadioAccessSpecifier11)
-                            .collect(Collectors.toCollection(ArrayList::new)));
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#startNetworkScan
-     * @param serial Serial number of request
-     * @param request Defines the radio networks/bands/channels which need to be scanned
-     * @param overrideHalVersion Radio HAL fallback compatibility override
-     * @throws RemoteException
-     */
-    public void startNetworkScan(int serial, NetworkScanRequest request,
-            HalVersion overrideHalVersion, Message result) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_1)) return;
-        if (isAidl()) {
-            android.hardware.radio.network.NetworkScanRequest halRequest =
-                    new android.hardware.radio.network.NetworkScanRequest();
-            halRequest.type = request.getScanType();
-            halRequest.interval = request.getSearchPeriodicity();
-            halRequest.maxSearchTime = request.getMaxSearchTime();
-            halRequest.incrementalResultsPeriodicity = request.getIncrementalResultsPeriodicity();
-            halRequest.incrementalResults = request.getIncrementalResults();
-            halRequest.mccMncs = request.getPlmns().stream().toArray(String[]::new);
-            ArrayList<android.hardware.radio.network.RadioAccessSpecifier> specifiers =
-                    new ArrayList<>();
-            for (RadioAccessSpecifier ras : request.getSpecifiers()) {
-                android.hardware.radio.network.RadioAccessSpecifier rasInHalFormat =
-                        RILUtils.convertToHalRadioAccessSpecifierAidl(ras);
-                if (rasInHalFormat == null) {
-                    AsyncResult.forMessage(result, null,
-                            CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                    result.sendToTarget();
-                    return;
-                }
-                specifiers.add(rasInHalFormat);
-            }
-            halRequest.specifiers = specifiers.stream().toArray(
-                    android.hardware.radio.network.RadioAccessSpecifier[]::new);
-            mNetworkProxy.startNetworkScan(serial, halRequest);
-        } else if ((overrideHalVersion == null
-                || overrideHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5))
-                && mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            android.hardware.radio.V1_5.NetworkScanRequest halRequest =
-                    new android.hardware.radio.V1_5.NetworkScanRequest();
-            halRequest.type = request.getScanType();
-            halRequest.interval = request.getSearchPeriodicity();
-            halRequest.maxSearchTime = request.getMaxSearchTime();
-            halRequest.incrementalResultsPeriodicity = request.getIncrementalResultsPeriodicity();
-            halRequest.incrementalResults = request.getIncrementalResults();
-            halRequest.mccMncs.addAll(request.getPlmns());
-            for (RadioAccessSpecifier ras : request.getSpecifiers()) {
-                android.hardware.radio.V1_5.RadioAccessSpecifier rasInHalFormat =
-                        RILUtils.convertToHalRadioAccessSpecifier15(ras);
-                if (rasInHalFormat == null) {
-                    AsyncResult.forMessage(result, null,
-                            CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                    result.sendToTarget();
-                    return;
-                }
-                halRequest.specifiers.add(rasInHalFormat);
-            }
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).startNetworkScan_1_5(
-                    serial, halRequest);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_2)) {
-            android.hardware.radio.V1_2.NetworkScanRequest halRequest =
-                    new android.hardware.radio.V1_2.NetworkScanRequest();
-            halRequest.type = request.getScanType();
-            halRequest.interval = request.getSearchPeriodicity();
-            halRequest.maxSearchTime = request.getMaxSearchTime();
-            halRequest.incrementalResultsPeriodicity = request.getIncrementalResultsPeriodicity();
-            halRequest.incrementalResults = request.getIncrementalResults();
-            halRequest.mccMncs.addAll(request.getPlmns());
-
-            for (RadioAccessSpecifier ras : request.getSpecifiers()) {
-                android.hardware.radio.V1_1.RadioAccessSpecifier rasInHalFormat =
-                        RILUtils.convertToHalRadioAccessSpecifier11(ras);
-                if (rasInHalFormat == null) {
-                    AsyncResult.forMessage(result, null,
-                            CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                    result.sendToTarget();
-                    return;
-                }
-                halRequest.specifiers.add(rasInHalFormat);
-            }
-
-            if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_4)) {
-                ((android.hardware.radio.V1_4.IRadio) mRadioProxy).startNetworkScan_1_4(
-                        serial, halRequest);
-            } else {
-                ((android.hardware.radio.V1_2.IRadio) mRadioProxy).startNetworkScan_1_2(
-                        serial, halRequest);
-            }
-        } else {
-            android.hardware.radio.V1_1.NetworkScanRequest halRequest =
-                    new android.hardware.radio.V1_1.NetworkScanRequest();
-            halRequest.type = request.getScanType();
-            halRequest.interval = request.getSearchPeriodicity();
-            for (RadioAccessSpecifier ras : request.getSpecifiers()) {
-                android.hardware.radio.V1_1.RadioAccessSpecifier rasInHalFormat =
-                        RILUtils.convertToHalRadioAccessSpecifier11(ras);
-                if (rasInHalFormat == null) {
-                    AsyncResult.forMessage(result, null,
-                            CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                    result.sendToTarget();
-                    return;
-                }
-                halRequest.specifiers.add(rasInHalFormat);
-            }
-            ((android.hardware.radio.V1_1.IRadio) mRadioProxy).startNetworkScan(serial, halRequest);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#stopNetworkScan
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void stopNetworkScan(int serial) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_1)) return;
-        if (isAidl()) {
-            mNetworkProxy.stopNetworkScan(serial);
-        } else {
-            ((android.hardware.radio.V1_1.IRadio) mRadioProxy).stopNetworkScan(serial);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#supplyNetworkDepersonalization
-     * @param serial Serial number of request
-     * @param netPin Network depersonalization code
-     * @throws RemoteException
-     */
-    public void supplyNetworkDepersonalization(int serial, String netPin) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.supplyNetworkDepersonalization(serial, netPin);
-        } else {
-            mRadioProxy.supplyNetworkDepersonalization(serial, netPin);
-        }
-    }
-
-    /**
-     * Call IRadioNetwork#getUsageSetting()
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getUsageSetting(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.getUsageSetting(serial);
-        }
-        // Only supported on AIDL.
-    }
-
-    /**
-     * Call IRadioNetwork#setUsageSetting()
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void setUsageSetting(int serial,
-            /* TelephonyManager.UsageSetting */ int usageSetting) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mNetworkProxy.setUsageSetting(serial, usageSetting);
-        }
-        // Only supported on AIDL.
-    }
-}
diff --git a/src/java/com/android/internal/telephony/RadioResponse.java b/src/java/com/android/internal/telephony/RadioResponse.java
index 5265be5..9e08b9c 100644
--- a/src/java/com/android/internal/telephony/RadioResponse.java
+++ b/src/java/com/android/internal/telephony/RadioResponse.java
@@ -18,7 +18,9 @@
 
 import android.content.Context;
 import android.hardware.radio.V1_0.ActivityStatsInfo;
+import android.hardware.radio.V1_0.AppStatus;
 import android.hardware.radio.V1_0.CardStatus;
+import android.hardware.radio.V1_0.Carrier;
 import android.hardware.radio.V1_0.CarrierRestrictions;
 import android.hardware.radio.V1_0.CdmaBroadcastSmsConfigInfo;
 import android.hardware.radio.V1_0.DataRegStateResult;
@@ -39,6 +41,8 @@
 import android.os.AsyncResult;
 import android.os.Message;
 import android.os.SystemClock;
+import android.service.carrier.CarrierIdentifier;
+import android.telephony.AccessNetworkConstants;
 import android.telephony.AnomalyReporter;
 import android.telephony.BarringInfo;
 import android.telephony.CarrierRestrictionRules;
@@ -47,6 +51,7 @@
 import android.telephony.ModemActivityInfo;
 import android.telephony.NeighboringCellInfo;
 import android.telephony.NetworkScanRequest;
+import android.telephony.PhoneNumberUtils;
 import android.telephony.RadioAccessFamily;
 import android.telephony.RadioAccessSpecifier;
 import android.telephony.SignalStrength;
@@ -56,12 +61,13 @@
 import android.telephony.data.NetworkSlicingConfig;
 import android.text.TextUtils;
 
-import com.android.internal.telephony.data.KeepaliveStatus;
+import com.android.internal.telephony.dataconnection.KeepaliveStatus;
 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
 import com.android.internal.telephony.uicc.AdnCapacity;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus;
 import com.android.internal.telephony.uicc.IccCardStatus;
 import com.android.internal.telephony.uicc.IccIoResult;
-import com.android.internal.telephony.uicc.IccSlotPortMapping;
+import com.android.internal.telephony.uicc.IccUtils;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -69,6 +75,19 @@
 import java.util.UUID;
 
 public class RadioResponse extends IRadioResponse.Stub {
+    // The number of the required config values for broadcast SMS stored in the C struct
+    // RIL_CDMA_BroadcastServiceInfo
+    private static final int CDMA_BSI_NO_OF_INTS_STRUCT = 3;
+
+    private static final int CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES = 31;
+
+    private static final String RADIO_POWER_FAILURE_BUGREPORT_UUID =
+            "316f3801-fa21-4954-a42f-0041eada3b31";
+    private static final String RADIO_POWER_FAILURE_RF_HARDWARE_ISSUE_UUID =
+            "316f3801-fa21-4954-a42f-0041eada3b32";
+    private static final String RADIO_POWER_FAILURE_NO_RF_CALIBRATION_UUID =
+            "316f3801-fa21-4954-a42f-0041eada3b33";
+
     RIL mRil;
 
     public RadioResponse(RIL ril) {
@@ -521,7 +540,9 @@
      * @param numeric is 5 or 6 digit numeric code (MCC + MNC) or empty string if unregistered
      */
     public void getOperatorResponse(RadioResponseInfo responseInfo,
-            String longName, String shortName, String numeric) {
+            String longName,
+            String shortName,
+            String numeric) {
         responseStrings(responseInfo, longName, shortName, numeric);
     }
 
@@ -544,7 +565,8 @@
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param sms Response to sms sent as defined by SendSmsResult in types.hal
      */
-    public void sendSmsResponse(RadioResponseInfo responseInfo, SendSmsResult sms) {
+    public void sendSmsResponse(RadioResponseInfo responseInfo,
+            SendSmsResult sms) {
         responseSms(responseInfo, sms);
     }
 
@@ -573,7 +595,8 @@
      * @param sms Response to sms sent as defined by SendSmsResult in 1.6/types.hal
      */
     public void sendSmsExpectMoreResponse_1_6(
-            android.hardware.radio.V1_6.RadioResponseInfo responseInfo, SendSmsResult sms) {
+            android.hardware.radio.V1_6.RadioResponseInfo responseInfo,
+            SendSmsResult sms) {
         responseSms_1_6(responseInfo, sms);
     }
 
@@ -638,8 +661,9 @@
 
     @Override
     public void getAllowedNetworkTypesBitmapResponse(
-            android.hardware.radio.V1_6.RadioResponseInfo info, int halRadioAccessFamilyBitmap) {
-        int networkTypeBitmask = RILUtils.convertHalNetworkTypeBitMask(halRadioAccessFamilyBitmap);
+            android.hardware.radio.V1_6.RadioResponseInfo info,
+            int halRadioAccessFamilyBitmap) {
+        int networkTypeBitmask = RIL.convertToNetworkTypeBitMask(halRadioAccessFamilyBitmap);
         mRil.mAllowedNetworkTypesBitmask = networkTypeBitmask;
         responseInts_1_6(info, networkTypeBitmask);
     }
@@ -689,7 +713,8 @@
      *        each distinct registered phone number.
      */
     public void getCallForwardStatusResponse(RadioResponseInfo responseInfo,
-            ArrayList<android.hardware.radio.V1_0.CallForwardInfo> callForwardInfos) {
+            ArrayList<android.hardware.radio.V1_0.CallForwardInfo>
+                    callForwardInfos) {
         responseCallForwardInfo(responseInfo, callForwardInfos);
     }
 
@@ -711,7 +736,8 @@
      *        and voice and disabled for everything else.
      */
     public void getCallWaitingResponse(RadioResponseInfo responseInfo,
-            boolean enable, int serviceClass) {
+            boolean enable,
+            int serviceClass) {
         responseInts(responseInfo, enable ? 1 : 0, serviceClass);
     }
 
@@ -744,6 +770,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param response 0 is the TS 27.007 service class bit vector of
      *        services for which the specified barring facility
@@ -754,6 +781,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param retry 0 is the number of retries remaining, or -1 if unknown
      */
@@ -769,6 +797,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param selection false for automatic selection, true for manual selection
      */
@@ -798,12 +827,14 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param networkInfos List of network operator information as OperatorInfos defined in
      *                     types.hal
      */
     public void getAvailableNetworksResponse(RadioResponseInfo responseInfo,
-            ArrayList<android.hardware.radio.V1_0.OperatorInfo> networkInfos) {
+            ArrayList<android.hardware.radio.V1_0.OperatorInfo>
+                    networkInfos) {
         responseOperatorInfos(responseInfo, networkInfos);
     }
 
@@ -835,6 +866,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      */
     public void stopNetworkScanResponse(RadioResponseInfo responseInfo) {
@@ -856,6 +888,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param version string containing version string for log reporting
      */
@@ -878,6 +911,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param enable true for "mute enabled" and false for "mute disabled"
      */
@@ -886,6 +920,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param status indicates CLIP status
      */
@@ -956,6 +991,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param bandModes List of RadioBandMode listing supported modes
      */
@@ -965,6 +1001,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param commandResponse SAT/USAT response in hexadecimal format
      *        string starting with first byte of response
@@ -1010,6 +1047,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param nwType RadioPreferredNetworkType defined in types.hal
      */
@@ -1027,12 +1065,13 @@
     public void getPreferredNetworkTypeBitmapResponse(
             RadioResponseInfo responseInfo, int halRadioAccessFamilyBitmap) {
 
-        int networkTypeBitmask = RILUtils.convertHalNetworkTypeBitMask(halRadioAccessFamilyBitmap);
+        int networkTypeBitmask = RIL.convertToNetworkTypeBitMask(halRadioAccessFamilyBitmap);
         mRil.mAllowedNetworkTypesBitmask = networkTypeBitmask;
         responseInts(responseInfo, networkTypeBitmask);
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param cells Vector of neighboring radio cell information
      */
@@ -1063,6 +1102,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param type CdmaRoamingType defined in types.hal
      */
@@ -1078,6 +1118,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param mode TTY mode
      */
@@ -1093,11 +1134,13 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param enable false for Standard Privacy Mode (Public Long Code Mask)
      *        true for Enhanced Privacy Mode (Private Long Code Mask)
      */
-    public void getPreferredVoicePrivacyResponse(RadioResponseInfo responseInfo, boolean enable) {
+    public void getPreferredVoicePrivacyResponse(RadioResponseInfo responseInfo,
+            boolean enable) {
         responseInts(responseInfo, enable ? 1 : 0);
     }
 
@@ -1116,6 +1159,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param sms Sms result struct as defined by SendSmsResult in types.hal
      */
@@ -1124,6 +1168,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error which
      *                     is defined in 1.6/types.hal
      * @param sms Sms result struct as defined by SendSmsResult in types.hal
@@ -1143,6 +1188,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error which
      *                     is defined in 1.6/types.hal
      * @param sms Sms result struct as defined by SendSmsResult in types.hal
@@ -1168,6 +1214,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param configs Vector of GSM/WCDMA Cell broadcast configs
      */
@@ -1191,6 +1238,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param configs Vector of CDMA Broadcast SMS configs.
      */
@@ -1214,6 +1262,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param mdn MDN if CDMA subscription is available
      * @param hSid is a comma separated list of H_SID (Home SID) if
@@ -1229,6 +1278,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param index record index where the cmda sms message is stored
      */
@@ -1292,6 +1342,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param source CDMA subscription source
      */
@@ -1317,6 +1368,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param iccIo IccIoResult as defined in types.hal corresponding to ICC IO response
      */
@@ -1326,6 +1378,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param rat Current voice RAT
      */
@@ -1342,27 +1395,30 @@
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param cellInfo List of current cell information known to radio
      */
-    public void getCellInfoListResponse_1_2(RadioResponseInfo responseInfo,
+    public void getCellInfoListResponse_1_2(
+            RadioResponseInfo responseInfo,
             ArrayList<android.hardware.radio.V1_2.CellInfo> cellInfo) {
-        responseCellInfoList(responseInfo, cellInfo);
+        responseCellInfoList_1_2(responseInfo, cellInfo);
     }
 
     /**
      * @param responseInfo Response info struct containing response type, serial no. and error.
      * @param cellInfo List of current cell information known to radio.
      */
-    public void getCellInfoListResponse_1_4(RadioResponseInfo responseInfo,
+    public void getCellInfoListResponse_1_4(
+            RadioResponseInfo responseInfo,
             ArrayList<android.hardware.radio.V1_4.CellInfo> cellInfo) {
-        responseCellInfoList(responseInfo, cellInfo);
+        responseCellInfoList_1_4(responseInfo, cellInfo);
     }
 
     /**
      * @param responseInfo Response info struct containing response type, serial no. and error.
      * @param cellInfo List of current cell information known to radio.
      */
-    public void getCellInfoListResponse_1_5(RadioResponseInfo responseInfo,
+    public void getCellInfoListResponse_1_5(
+            RadioResponseInfo responseInfo,
             ArrayList<android.hardware.radio.V1_5.CellInfo> cellInfo) {
-        responseCellInfoList(responseInfo, cellInfo);
+        responseCellInfoList_1_5(responseInfo, cellInfo);
     }
 
     /**
@@ -1397,6 +1453,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param isRegistered false = not registered, true = registered
      * @param ratFamily RadioTechnologyFamily as defined in types.hal. This value is valid only if
@@ -1404,12 +1461,16 @@
      */
     public void getImsRegistrationStateResponse(RadioResponseInfo responseInfo,
             boolean isRegistered, int ratFamily) {
-        responseInts(responseInfo, isRegistered ? 1 : 0,
-                ratFamily == RadioTechnologyFamily.THREE_GPP ? PhoneConstants.PHONE_TYPE_GSM
+        responseInts(
+                responseInfo,
+                isRegistered ? 1 : 0,
+                ratFamily == RadioTechnologyFamily.THREE_GPP
+                        ? PhoneConstants.PHONE_TYPE_GSM
                         : PhoneConstants.PHONE_TYPE_CDMA);
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param sms Response to sms sent as defined by SendSmsResult in types.hal
      */
@@ -1418,15 +1479,18 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param result IccIoResult as defined in types.hal
      */
     public void iccTransmitApduBasicChannelResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.V1_0.IccIoResult result) {
+            android.hardware.radio.V1_0.IccIoResult
+                    result) {
         responseIccIo(responseInfo, result);
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param channelId session id of the logical channel.
      * @param selectResponse Contains the select response for the open channel command with one
@@ -1450,6 +1514,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param result IccIoResult as defined in types.hal
      */
@@ -1460,6 +1525,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param result string containing the contents of the NV item
      */
@@ -1509,16 +1575,21 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param result IccIoResult as defined in types.hal
      */
     public void requestIccSimAuthenticationResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.V1_0.IccIoResult result) {
+            android.hardware.radio.V1_0.IccIoResult
+                    result) {
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            IccIoResult ret = new IccIoResult(result.sw1, result.sw2,
-                    TextUtils.isEmpty(result.simResponse) ? null : result.simResponse.getBytes());
+            IccIoResult ret = new IccIoResult(
+                    result.sw1,
+                    result.sw2,
+                    TextUtils.isEmpty(result.simResponse)
+                            ? null : result.simResponse.getBytes());
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
             }
@@ -1552,7 +1623,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            RadioCapability ret = RILUtils.convertHalRadioCapability(rc, mRil);
+            RadioCapability ret = RIL.convertHalRadioCapability(rc, mRil);
             if (responseInfo.error == RadioError.REQUEST_NOT_SUPPORTED
                     || responseInfo.error == RadioError.GENERIC_FAILURE) {
                 // we should construct the RAF bitmask the radio
@@ -1573,6 +1644,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param statusInfo LceStatusInfo indicating LCE status
      */
@@ -1581,6 +1653,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param statusInfo LceStatusInfo indicating LCE status
      */
@@ -1593,6 +1666,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param activityInfo modem activity information
      */
@@ -1602,6 +1676,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param isEnabled Indicates whether NR dual connectivity is enabled or not, True if enabled
      *               else false.
@@ -1620,6 +1695,7 @@
     }
 
     /**
+     *
      * @param info Response info struct containing response type, serial no. and error
      */
     public void setNrDualConnectivityStateResponse(
@@ -1628,6 +1704,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param numAllowed number of allowed carriers which have been set correctly.
      *        On success, it must match the length of list Carriers->allowedCarriers.
@@ -1657,6 +1734,7 @@
     }
 
     /**
+     *
      * @param responseInfo Response info struct containing response type, serial no. and error
      */
     public void setAllowedCarriersResponse_1_4(RadioResponseInfo responseInfo) {
@@ -1773,6 +1851,7 @@
         responseVoid(responseInfo);
     }
 
+
     /**
      * @param responseInfo Response info struct containing response type, serial no. and error
      * @param keepaliveStatus status of the keepalive with a handle for the session
@@ -1787,13 +1866,11 @@
         try {
             switch(responseInfo.error) {
                 case RadioError.NONE:
-                    int convertedStatus = RILUtils.convertHalKeepaliveStatusCode(
-                            keepaliveStatus.code);
+                    int convertedStatus = convertHalKeepaliveStatusCode(keepaliveStatus.code);
                     if (convertedStatus < 0) {
                         ret = new KeepaliveStatus(KeepaliveStatus.ERROR_UNSUPPORTED);
                     } else {
-                        ret = new KeepaliveStatus(
-                                keepaliveStatus.sessionHandle, convertedStatus);
+                        ret = new KeepaliveStatus(keepaliveStatus.sessionHandle, convertedStatus);
                     }
                     // If responseInfo.error is NONE, response function sends the response message
                     // even if result is actually an error.
@@ -1833,6 +1910,96 @@
         }
     }
 
+    private int convertHalKeepaliveStatusCode(int halCode) {
+        switch (halCode) {
+            case android.hardware.radio.V1_1.KeepaliveStatusCode.ACTIVE:
+                return KeepaliveStatus.STATUS_ACTIVE;
+            case android.hardware.radio.V1_1.KeepaliveStatusCode.INACTIVE:
+                return KeepaliveStatus.STATUS_INACTIVE;
+            case android.hardware.radio.V1_1.KeepaliveStatusCode.PENDING:
+                return KeepaliveStatus.STATUS_PENDING;
+            default:
+                mRil.riljLog("Invalid Keepalive Status" + halCode);
+                return -1;
+        }
+    }
+
+    private IccCardStatus convertHalCardStatus(CardStatus cardStatus) {
+        IccCardStatus iccCardStatus = new IccCardStatus();
+        iccCardStatus.setCardState(cardStatus.cardState);
+        iccCardStatus.setUniversalPinState(cardStatus.universalPinState);
+        iccCardStatus.mGsmUmtsSubscriptionAppIndex = cardStatus.gsmUmtsSubscriptionAppIndex;
+        iccCardStatus.mCdmaSubscriptionAppIndex = cardStatus.cdmaSubscriptionAppIndex;
+        iccCardStatus.mImsSubscriptionAppIndex = cardStatus.imsSubscriptionAppIndex;
+        int numApplications = cardStatus.applications.size();
+
+        // limit to maximum allowed applications
+        if (numApplications
+                > com.android.internal.telephony.uicc.IccCardStatus.CARD_MAX_APPS) {
+            numApplications =
+                    com.android.internal.telephony.uicc.IccCardStatus.CARD_MAX_APPS;
+        }
+        iccCardStatus.mApplications = new IccCardApplicationStatus[numApplications];
+        for (int i = 0; i < numApplications; i++) {
+            AppStatus rilAppStatus = cardStatus.applications.get(i);
+            IccCardApplicationStatus appStatus = new IccCardApplicationStatus();
+            appStatus.app_type       = appStatus.AppTypeFromRILInt(rilAppStatus.appType);
+            appStatus.app_state      = appStatus.AppStateFromRILInt(rilAppStatus.appState);
+            appStatus.perso_substate = appStatus.PersoSubstateFromRILInt(
+                    rilAppStatus.persoSubstate);
+            appStatus.aid            = rilAppStatus.aidPtr;
+            appStatus.app_label      = rilAppStatus.appLabelPtr;
+            appStatus.pin1_replaced  = rilAppStatus.pin1Replaced;
+            appStatus.pin1           = appStatus.PinStateFromRILInt(rilAppStatus.pin1);
+            appStatus.pin2           = appStatus.PinStateFromRILInt(rilAppStatus.pin2);
+            iccCardStatus.mApplications[i] = appStatus;
+            mRil.riljLog("IccCardApplicationStatus " + i + ":" + appStatus.toString());
+        }
+        return iccCardStatus;
+    }
+
+    private IccCardStatus convertHalCardStatus_1_5(
+            android.hardware.radio.V1_5.CardStatus cardStatus) {
+        IccCardStatus iccCardStatus = new IccCardStatus();
+        iccCardStatus.setCardState(cardStatus.base.base.base.cardState);
+        iccCardStatus.setUniversalPinState(cardStatus.base.base.base.universalPinState);
+        iccCardStatus.mGsmUmtsSubscriptionAppIndex =
+                cardStatus.base.base.base.gsmUmtsSubscriptionAppIndex;
+        iccCardStatus.mCdmaSubscriptionAppIndex =
+                cardStatus.base.base.base.cdmaSubscriptionAppIndex;
+        iccCardStatus.mImsSubscriptionAppIndex =
+                cardStatus.base.base.base.imsSubscriptionAppIndex;
+        iccCardStatus.physicalSlotIndex = cardStatus.base.base.physicalSlotId;
+        iccCardStatus.atr = cardStatus.base.base.atr;
+        iccCardStatus.iccid = cardStatus.base.base.iccid;
+        iccCardStatus.eid = cardStatus.base.eid;
+        int numApplications = cardStatus.applications.size();
+
+        // limit to maximum allowed applications
+        if (numApplications
+                > com.android.internal.telephony.uicc.IccCardStatus.CARD_MAX_APPS) {
+            numApplications =
+                    com.android.internal.telephony.uicc.IccCardStatus.CARD_MAX_APPS;
+        }
+        iccCardStatus.mApplications = new IccCardApplicationStatus[numApplications];
+        for (int i = 0; i < numApplications; i++) {
+            android.hardware.radio.V1_5.AppStatus rilAppStatus = cardStatus.applications.get(i);
+            IccCardApplicationStatus appStatus = new IccCardApplicationStatus();
+            appStatus.app_type       = appStatus.AppTypeFromRILInt(rilAppStatus.base.appType);
+            appStatus.app_state      = appStatus.AppStateFromRILInt(rilAppStatus.base.appState);
+            appStatus.perso_substate = appStatus.PersoSubstateFromRILInt(
+                    rilAppStatus.persoSubstate);
+            appStatus.aid            = rilAppStatus.base.aidPtr;
+            appStatus.app_label      = rilAppStatus.base.appLabelPtr;
+            appStatus.pin1_replaced  = rilAppStatus.base.pin1Replaced;
+            appStatus.pin1           = appStatus.PinStateFromRILInt(rilAppStatus.base.pin1);
+            appStatus.pin2           = appStatus.PinStateFromRILInt(rilAppStatus.base.pin2);
+            iccCardStatus.mApplications[i] = appStatus;
+            mRil.riljLog("IccCardApplicationStatus " + i + ":" + appStatus.toString());
+        }
+        return iccCardStatus;
+    }
+
     /**
      * @param responseInfo Response info struct containing response type, serial no. and error.
      */
@@ -1848,7 +2015,7 @@
     public void getSimPhonebookCapacityResponse(
             android.hardware.radio.V1_6.RadioResponseInfo responseInfo,
             android.hardware.radio.V1_6.PhonebookCapacity pbCapacity) {
-        AdnCapacity capacity = RILUtils.convertHalPhonebookCapacity(pbCapacity);
+        AdnCapacity capacity = new AdnCapacity(pbCapacity);
         responseAdnCapacity(responseInfo, capacity);
     }
 
@@ -1878,7 +2045,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            IccCardStatus iccCardStatus = RILUtils.convertHalCardStatus(cardStatus);
+            IccCardStatus iccCardStatus = convertHalCardStatus(cardStatus);
             mRil.riljLog("responseIccCardStatus: from HIDL: " + iccCardStatus);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, iccCardStatus);
@@ -1892,10 +2059,8 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            IccCardStatus iccCardStatus = RILUtils.convertHalCardStatus(cardStatus.base);
-            IccSlotPortMapping slotPortMapping = new IccSlotPortMapping();
-            slotPortMapping.mPhysicalSlotIndex = cardStatus.physicalSlotId;
-            iccCardStatus.mSlotPortMapping = slotPortMapping;
+            IccCardStatus iccCardStatus = convertHalCardStatus(cardStatus.base);
+            iccCardStatus.physicalSlotIndex = cardStatus.physicalSlotId;
             iccCardStatus.atr = cardStatus.atr;
             iccCardStatus.iccid = cardStatus.iccid;
             mRil.riljLog("responseIccCardStatus: from HIDL: " + iccCardStatus);
@@ -1911,10 +2076,8 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            IccCardStatus iccCardStatus = RILUtils.convertHalCardStatus(cardStatus.base.base);
-            IccSlotPortMapping slotPortMapping = new IccSlotPortMapping();
-            slotPortMapping.mPhysicalSlotIndex = cardStatus.base.physicalSlotId;
-            iccCardStatus.mSlotPortMapping = slotPortMapping;
+            IccCardStatus iccCardStatus = convertHalCardStatus(cardStatus.base.base);
+            iccCardStatus.physicalSlotIndex = cardStatus.base.physicalSlotId;
             iccCardStatus.atr = cardStatus.base.atr;
             iccCardStatus.iccid = cardStatus.base.iccid;
             iccCardStatus.eid = cardStatus.eid;
@@ -1931,7 +2094,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            IccCardStatus iccCardStatus = RILUtils.convertHalCardStatus(cardStatus);
+            IccCardStatus iccCardStatus = convertHalCardStatus_1_5(cardStatus);
             mRil.riljLog("responseIccCardStatus: from HIDL: " + iccCardStatus);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, iccCardStatus);
@@ -1964,22 +2127,6 @@
         responseIntArrayList_1_6(responseInfo, ints);
     }
 
-    /**
-     * Send int array response
-     * @param service radio service that received the response
-     * @param ril RIL to send response
-     * @param responseInfo responseInfo
-     * @param var response int array
-     */
-    public static void responseInts(int service, RIL ril,
-            android.hardware.radio.RadioResponseInfo responseInfo, int ...var) {
-        final ArrayList<Integer> ints = new ArrayList<>();
-        for (int i = 0; i < var.length; i++) {
-            ints.add(var[i]);
-        }
-        responseIntArrayList(service, ril, responseInfo, ints);
-    }
-
     private void responseIntArrayList(RadioResponseInfo responseInfo, ArrayList<Integer> var) {
         RILRequest rr = mRil.processResponse(responseInfo);
 
@@ -2011,29 +2158,6 @@
         }
     }
 
-    /**
-     * Send int array list response
-     * @param service radio service that received the response
-     * @param ril RIL to send response
-     * @param responseInfo responseInfo
-     * @param var response int array list
-     */
-    public static void responseIntArrayList(int service, RIL ril,
-            android.hardware.radio.RadioResponseInfo responseInfo, ArrayList<Integer> var) {
-        RILRequest rr = ril.processResponse(service, responseInfo);
-
-        if (rr != null) {
-            int[] ret = new int[var.size()];
-            for (int i = 0; i < var.size(); i++) {
-                ret[i] = var.get(i);
-            }
-            if (responseInfo.error == RadioError.NONE) {
-                sendMessageResponse(rr.mResult, ret);
-            }
-            ril.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
     private void responseCurrentCalls(RadioResponseInfo responseInfo,
             ArrayList<android.hardware.radio.V1_0.Call> calls) {
         RILRequest rr = mRil.processResponse(responseInfo);
@@ -2044,7 +2168,7 @@
             DriverCall dc;
 
             for (int i = 0; i < num; i++) {
-                dc = RILUtils.convertToDriverCall(calls.get(i));
+                dc = convertToDriverCall(calls.get(i));
 
                 dcCalls.add(dc);
 
@@ -2084,7 +2208,7 @@
             DriverCall dc;
 
             for (int i = 0; i < num; i++) {
-                dc = RILUtils.convertToDriverCall(calls.get(i));
+                dc = convertToDriverCall_1_2(calls.get(i));
 
                 dcCalls.add(dc);
 
@@ -2125,7 +2249,7 @@
             DriverCall dc;
 
             for (int i = 0; i < num; i++) {
-                dc = RILUtils.convertToDriverCall(calls.get(i));
+                dc = convertToDriverCall_1_6(calls.get(i));
 
                 dcCalls.add(dc);
 
@@ -2155,6 +2279,62 @@
         }
     }
 
+    private DriverCall convertToDriverCall(android.hardware.radio.V1_0.Call call) {
+        DriverCall dc = new DriverCall();
+        // TODO: change name of function stateFromCLCC() in DriverCall.java to name
+        // clarifying what is CLCC
+        dc.state = DriverCall.stateFromCLCC((int) (call.state));
+        dc.index = call.index;
+        dc.TOA = call.toa;
+        dc.isMpty = call.isMpty;
+        dc.isMT = call.isMT;
+        dc.als = call.als;
+        dc.isVoice = call.isVoice;
+        dc.isVoicePrivacy = call.isVoicePrivacy;
+        dc.number = call.number;
+        dc.numberPresentation = DriverCall.presentationFromCLIP((int) (call.numberPresentation));
+        dc.name = call.name;
+        dc.namePresentation = DriverCall.presentationFromCLIP((int) (call.namePresentation));
+        if (call.uusInfo.size() == 1) {
+            dc.uusInfo = new UUSInfo();
+            dc.uusInfo.setType(call.uusInfo.get(0).uusType);
+            dc.uusInfo.setDcs(call.uusInfo.get(0).uusDcs);
+            if (!TextUtils.isEmpty(call.uusInfo.get(0).uusData)) {
+                byte[] userData = call.uusInfo.get(0).uusData.getBytes();
+                dc.uusInfo.setUserData(userData);
+            } else {
+                mRil.riljLog("convertToDriverCall: uusInfo data is null or empty");
+            }
+
+            mRil.riljLogv(String.format("Incoming UUS : type=%d, dcs=%d, length=%d",
+                    dc.uusInfo.getType(), dc.uusInfo.getDcs(),
+                    dc.uusInfo.getUserData().length));
+            mRil.riljLogv("Incoming UUS : data (hex): "
+                    + IccUtils.bytesToHexString(dc.uusInfo.getUserData()));
+        } else {
+            mRil.riljLogv("Incoming UUS : NOT present!");
+        }
+
+        // Make sure there's a leading + on addresses with a TOA of 145
+        dc.number = PhoneNumberUtils.stringFromStringAndTOA(dc.number, dc.TOA);
+
+        return dc;
+    }
+
+    private DriverCall convertToDriverCall_1_2(android.hardware.radio.V1_2.Call call) {
+        android.hardware.radio.V1_0.Call earlierVersionCall = call.base;
+        DriverCall dc = convertToDriverCall(earlierVersionCall);
+        dc.audioQuality = (int) (call.audioQuality);
+        return dc;
+    }
+
+    private DriverCall convertToDriverCall_1_6(android.hardware.radio.V1_6.Call call) {
+        android.hardware.radio.V1_2.Call earlierVersionCall = call.base;
+        DriverCall dc = convertToDriverCall_1_2(earlierVersionCall);
+        dc.forwardedNumber = call.forwardedNumber;
+        return dc;
+    }
+
     private void responseVoid(RadioResponseInfo responseInfo) {
         RILRequest rr = mRil.processResponse(responseInfo);
 
@@ -2179,25 +2359,6 @@
         }
     }
 
-    /**
-     * Send void response
-     * @param service radio service that received the response
-     * @param ril RIL to send response
-     * @param responseInfo response void
-     */
-    public static void responseVoid(int service, RIL ril,
-            android.hardware.radio.RadioResponseInfo responseInfo) {
-        RILRequest rr = ril.processResponse(service, responseInfo);
-
-        if (rr != null) {
-            Object ret = null;
-            if (responseInfo.error == RadioError.NONE) {
-                sendMessageResponse(rr.mResult, ret);
-            }
-            ril.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
     private void responseString(RadioResponseInfo responseInfo, String str) {
         RILRequest rr = mRil.processResponse(responseInfo);
 
@@ -2209,25 +2370,6 @@
         }
     }
 
-    /**
-     * Send string response
-     * @param service radio service that received the response
-     * @param ril RIL to send response
-     * @param responseInfo responseInfo
-     * @param str response string
-     */
-    public static void responseString(int service, RIL ril,
-            android.hardware.radio.RadioResponseInfo responseInfo, String str) {
-        RILRequest rr = ril.processResponse(service, responseInfo);
-
-        if (rr != null) {
-            if (responseInfo.error == RadioError.NONE) {
-                sendMessageResponse(rr.mResult, str);
-            }
-            ril.processResponseDone(rr, responseInfo, str);
-        }
-    }
-
     private void responseStrings(RadioResponseInfo responseInfo, String ...str) {
         ArrayList<String> strings = new ArrayList<>();
         for (int i = 0; i < str.length; i++) {
@@ -2236,22 +2378,6 @@
         responseStringArrayList(mRil, responseInfo, strings);
     }
 
-    /**
-     * Send String array response
-     * @param service radio service that received the response
-     * @param ril RIL to send response
-     * @param responseInfo responseInfo
-     * @param str String array
-     */
-    public static void responseStrings(int service, RIL ril,
-            android.hardware.radio.RadioResponseInfo responseInfo, String ...str) {
-        ArrayList<String> strings = new ArrayList<>();
-        for (int i = 0; i < str.length; i++) {
-            strings.add(str[i]);
-        }
-        responseStringArrayList(service, ril, responseInfo, strings);
-    }
-
     static void responseStringArrayList(RIL ril, RadioResponseInfo responseInfo,
             ArrayList<String> strings) {
         RILRequest rr = ril.processResponse(responseInfo);
@@ -2268,22 +2394,6 @@
         }
     }
 
-    private static void responseStringArrayList(int service, RIL ril,
-            android.hardware.radio.RadioResponseInfo responseInfo, ArrayList<String> strings) {
-        RILRequest rr = ril.processResponse(service, responseInfo);
-
-        if (rr != null) {
-            String[] ret = new String[strings.size()];
-            for (int i = 0; i < strings.size(); i++) {
-                ret[i] = strings.get(i);
-            }
-            if (responseInfo.error == RadioError.NONE) {
-                sendMessageResponse(rr.mResult, ret);
-            }
-            ril.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
     private void responseLastCallFailCauseInfo(RadioResponseInfo responseInfo,
             LastCallFailCauseInfo fcInfo) {
         RILRequest rr = mRil.processResponse(responseInfo);
@@ -2305,7 +2415,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            SignalStrength ret = RILUtils.convertHalSignalStrength(signalStrength);
+            SignalStrength ret = new SignalStrength(signalStrength);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
             }
@@ -2319,7 +2429,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            SignalStrength ret = RILUtils.convertHalSignalStrength(signalStrength);
+            SignalStrength ret = new SignalStrength(signalStrength);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
             }
@@ -2333,7 +2443,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            SignalStrength ret = RILUtils.convertHalSignalStrength(signalStrength);
+            SignalStrength ret = new SignalStrength(signalStrength);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
             }
@@ -2347,7 +2457,7 @@
         RILRequest rr = mRil.processResponse_1_6(responseInfo);
 
         if (rr != null) {
-            SignalStrength ret = RILUtils.convertHalSignalStrength(signalStrength);
+            SignalStrength ret = new SignalStrength(signalStrength);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
             }
@@ -2387,7 +2497,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            DataCallResponse response = RILUtils.convertHalDataCallResult(setupDataCallResult);
+            DataCallResponse response = RIL.convertDataCallResult(setupDataCallResult);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, response);
             }
@@ -2401,7 +2511,7 @@
         RILRequest rr = mRil.processResponse_1_6(responseInfo);
 
         if (rr != null) {
-            DataCallResponse response = RILUtils.convertHalDataCallResult(setupDataCallResult);
+            DataCallResponse response = RIL.convertDataCallResult(setupDataCallResult);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, response);
             }
@@ -2423,7 +2533,8 @@
     }
 
     private void responseCallForwardInfo(RadioResponseInfo responseInfo,
-            ArrayList<android.hardware.radio.V1_0.CallForwardInfo> callForwardInfos) {
+            ArrayList<android.hardware.radio.V1_0.CallForwardInfo>
+                    callForwardInfos) {
         RILRequest rr = mRil.processResponse(responseInfo);
         if (rr != null) {
             CallForwardInfo[] ret = new CallForwardInfo[callForwardInfos.size()];
@@ -2443,8 +2554,23 @@
         }
     }
 
+    private static String convertOpertatorInfoToString(int status) {
+        if (status == android.hardware.radio.V1_0.OperatorStatus.UNKNOWN) {
+            return "unknown";
+        } else if (status == android.hardware.radio.V1_0.OperatorStatus.AVAILABLE) {
+            return "available";
+        } else if (status == android.hardware.radio.V1_0.OperatorStatus.CURRENT) {
+            return "current";
+        } else if (status == android.hardware.radio.V1_0.OperatorStatus.FORBIDDEN) {
+            return "forbidden";
+        } else {
+            return "";
+        }
+    }
+
     private void responseOperatorInfos(RadioResponseInfo responseInfo,
-            ArrayList<android.hardware.radio.V1_0.OperatorInfo> networkInfos) {
+            ArrayList<android.hardware.radio.V1_0.OperatorInfo>
+                    networkInfos) {
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
@@ -2452,7 +2578,7 @@
             for (int i = 0; i < networkInfos.size(); i++) {
                 ret.add(new OperatorInfo(networkInfos.get(i).alphaLong,
                         networkInfos.get(i).alphaShort, networkInfos.get(i).operatorNumeric,
-                        RILUtils.convertHalOperatorStatus(networkInfos.get(i).status)));
+                        convertOpertatorInfoToString(networkInfos.get(i).status)));
             }
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
@@ -2500,7 +2626,7 @@
 
         if (rr != null) {
             ArrayList<DataCallResponse> response =
-                    RILUtils.convertHalDataCallResultList(dataCallResultList);
+                    RIL.convertDataCallResultList(dataCallResultList);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, response);
             }
@@ -2514,7 +2640,7 @@
 
         if (rr != null) {
             ArrayList<DataCallResponse> response =
-                    RILUtils.convertHalDataCallResultList(dataCallResultList);
+                    RIL.convertDataCallResultList(dataCallResultList);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, response);
             }
@@ -2557,7 +2683,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            ArrayList<SmsBroadcastConfigInfo> ret = new ArrayList<>();
+            ArrayList<SmsBroadcastConfigInfo> ret = new ArrayList<SmsBroadcastConfigInfo>();
             for (int i = 0; i < configs.size(); i++) {
                 ret.add(new SmsBroadcastConfigInfo(configs.get(i).fromServiceId,
                         configs.get(i).toServiceId, configs.get(i).fromCodeScheme,
@@ -2584,28 +2710,28 @@
                 // not be done by this transport layer. And needs to
                 // be done by the vendor ril or application logic.
                 int numInts;
-                numInts = RILUtils.CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES
-                        * RILUtils.CDMA_BSI_NO_OF_INTS_STRUCT + 1;
+                numInts = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES
+                        * CDMA_BSI_NO_OF_INTS_STRUCT + 1;
                 ret = new int[numInts];
 
                 // Faking a default record for all possible records.
-                ret[0] = RILUtils.CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES;
+                ret[0] = CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES;
 
                 // Loop over CDMA_BROADCAST_SMS_NO_OF_SERVICE_CATEGORIES set 'english' as
                 // default language and selection status to false for all.
-                for (int i = 1; i < numInts; i += RILUtils.CDMA_BSI_NO_OF_INTS_STRUCT) {
-                    ret[i + 0] = i / RILUtils.CDMA_BSI_NO_OF_INTS_STRUCT;
+                for (int i = 1; i < numInts; i += CDMA_BSI_NO_OF_INTS_STRUCT) {
+                    ret[i + 0] = i / CDMA_BSI_NO_OF_INTS_STRUCT;
                     ret[i + 1] = 1;
                     ret[i + 2] = 0;
                 }
             } else {
                 int numInts;
-                numInts = (numServiceCategories * RILUtils.CDMA_BSI_NO_OF_INTS_STRUCT) + 1;
+                numInts = (numServiceCategories * CDMA_BSI_NO_OF_INTS_STRUCT) + 1;
                 ret = new int[numInts];
 
                 ret[0] = numServiceCategories;
                 for (int i = 1, j = 0; j < configs.size();
-                        j++, i = i + RILUtils.CDMA_BSI_NO_OF_INTS_STRUCT) {
+                        j++, i = i + CDMA_BSI_NO_OF_INTS_STRUCT) {
                     ret[i] = configs.get(j).serviceCategory;
                     ret[i + 1] = configs.get(j).language;
                     ret[i + 2] = configs.get(j).selected ? 1 : 0;
@@ -2619,11 +2745,52 @@
     }
 
     private void responseCellInfoList(RadioResponseInfo responseInfo,
-            ArrayList<? extends Object> cellInfo) {
+            ArrayList<android.hardware.radio.V1_0.CellInfo> cellInfo) {
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            ArrayList<CellInfo> ret = RILUtils.convertHalCellInfoList((ArrayList<Object>) cellInfo);
+            ArrayList<CellInfo> ret = RIL.convertHalCellInfoList(cellInfo);
+            if (responseInfo.error == RadioError.NONE) {
+                sendMessageResponse(rr.mResult, ret);
+            }
+            mRil.processResponseDone(rr, responseInfo, ret);
+        }
+    }
+
+    private void responseCellInfoList_1_2(
+            RadioResponseInfo responseInfo,
+            ArrayList<android.hardware.radio.V1_2.CellInfo> cellInfo) {
+        RILRequest rr = mRil.processResponse(responseInfo);
+
+        if (rr != null) {
+            ArrayList<CellInfo> ret = RIL.convertHalCellInfoList_1_2(cellInfo);
+            if (responseInfo.error == RadioError.NONE) {
+                sendMessageResponse(rr.mResult, ret);
+            }
+            mRil.processResponseDone(rr, responseInfo, ret);
+        }
+    }
+
+    private void responseCellInfoList_1_4(
+            RadioResponseInfo responseInfo,
+            ArrayList<android.hardware.radio.V1_4.CellInfo> cellInfo) {
+        RILRequest rr = mRil.processResponse(responseInfo);
+
+        if (rr != null) {
+            ArrayList<CellInfo> ret = RIL.convertHalCellInfoList_1_4(cellInfo);
+            if (responseInfo.error == RadioError.NONE) {
+                sendMessageResponse(rr.mResult, ret);
+            }
+            mRil.processResponseDone(rr, responseInfo, ret);
+        }
+    }
+
+    private void responseCellInfoList_1_5(RadioResponseInfo responseInfo,
+            ArrayList<android.hardware.radio.V1_5.CellInfo> cellInfo) {
+        RILRequest rr = mRil.processResponse(responseInfo);
+
+        if (rr != null) {
+            ArrayList<CellInfo> ret = RIL.convertHalCellInfoList_1_5(cellInfo);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
             }
@@ -2633,11 +2800,11 @@
 
     private void responseCellInfoList_1_6(
             android.hardware.radio.V1_6.RadioResponseInfo responseInfo,
-            ArrayList<? extends Object> cellInfo) {
+            ArrayList<android.hardware.radio.V1_6.CellInfo> cellInfo) {
         RILRequest rr = mRil.processResponse_1_6(responseInfo);
 
         if (rr != null) {
-            ArrayList<CellInfo> ret = RILUtils.convertHalCellInfoList((ArrayList<Object>) cellInfo);
+            ArrayList<CellInfo> ret = RIL.convertHalCellInfoList_1_6(cellInfo);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
             }
@@ -2671,12 +2838,13 @@
         }
     }
 
-    private void responseHardwareConfig(RadioResponseInfo responseInfo,
+    private void responseHardwareConfig(
+            RadioResponseInfo responseInfo,
             ArrayList<android.hardware.radio.V1_0.HardwareConfig> config) {
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            ArrayList<HardwareConfig> ret = RILUtils.convertHalHardwareConfigList(config);
+            ArrayList<HardwareConfig> ret = RIL.convertHalHwConfigList(config, mRil);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
             }
@@ -2689,7 +2857,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            RadioCapability ret = RILUtils.convertHalRadioCapability(rc, mRil);
+            RadioCapability ret = RIL.convertHalRadioCapability(rc, mRil);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
             }
@@ -2701,7 +2869,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            ArrayList<Integer> ret = new ArrayList<>();
+            ArrayList<Integer> ret = new ArrayList<Integer>();
             ret.add(statusInfo.lceStatus);
             ret.add(Byte.toUnsignedInt(statusInfo.actualIntervalMs));
             if (responseInfo.error == RadioError.NONE) {
@@ -2715,7 +2883,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            List<LinkCapacityEstimate> ret = RILUtils.convertHalLceData(lceInfo);
+            List<LinkCapacityEstimate> ret = RIL.convertHalLceData(lceInfo, mRil);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
             }
@@ -2723,8 +2891,31 @@
         }
     }
 
+    private static List<CarrierIdentifier> convertCarrierList(List<Carrier> carrierList) {
+        List<CarrierIdentifier> ret = new ArrayList<>();
+        for (int i = 0; i < carrierList.size(); i++) {
+            String mcc = carrierList.get(i).mcc;
+            String mnc = carrierList.get(i).mnc;
+            String spn = null, imsi = null, gid1 = null, gid2 = null;
+            int matchType = carrierList.get(i).matchType;
+            String matchData = carrierList.get(i).matchData;
+            if (matchType == CarrierIdentifier.MatchType.SPN) {
+                spn = matchData;
+            } else if (matchType == CarrierIdentifier.MatchType.IMSI_PREFIX) {
+                imsi = matchData;
+            } else if (matchType == CarrierIdentifier.MatchType.GID1) {
+                gid1 = matchData;
+            } else if (matchType == CarrierIdentifier.MatchType.GID2) {
+                gid2 = matchData;
+            }
+            ret.add(new CarrierIdentifier(mcc, mnc, spn, imsi, gid1, gid2));
+        }
+        return ret;
+    }
+
     private void responseCarrierRestrictions(RadioResponseInfo responseInfo, boolean allAllowed,
-            CarrierRestrictionsWithPriority carriers, int multiSimPolicy) {
+            CarrierRestrictionsWithPriority carriers,
+            int multiSimPolicy) {
         RILRequest rr = mRil.processResponse(responseInfo);
         if (rr == null) {
             return;
@@ -2747,8 +2938,8 @@
             }
 
             ret = CarrierRestrictionRules.newBuilder()
-                    .setAllowedCarriers(RILUtils.convertHalCarrierList(carriers.allowedCarriers))
-                    .setExcludedCarriers(RILUtils.convertHalCarrierList(carriers.excludedCarriers))
+                    .setAllowedCarriers(convertCarrierList(carriers.allowedCarriers))
+                    .setExcludedCarriers(convertCarrierList(carriers.excludedCarriers))
                     .setDefaultCarrierRestriction(carrierRestrictionDefault)
                     .setMultiSimPolicy(policy)
                     .build();
@@ -2820,8 +3011,7 @@
         mRil.mLastRadioPowerResult = info.error;
         if (info.error != RadioError.RADIO_NOT_AVAILABLE && info.error != RadioError.NONE) {
             AnomalyReporter.reportAnomaly(
-                    UUID.fromString(RILUtils.RADIO_POWER_FAILURE_BUGREPORT_UUID),
-                    "Radio power failure");
+                    UUID.fromString(RADIO_POWER_FAILURE_BUGREPORT_UUID), "Radio power failure");
         }
     }
 
@@ -2833,17 +3023,15 @@
         mRil.mLastRadioPowerResult = info.error;
         if (info.error == android.hardware.radio.V1_6.RadioError.RF_HARDWARE_ISSUE) {
             AnomalyReporter.reportAnomaly(
-                    UUID.fromString(RILUtils.RADIO_POWER_FAILURE_RF_HARDWARE_ISSUE_UUID),
-                    "RF HW damaged");
+                    UUID.fromString(RADIO_POWER_FAILURE_RF_HARDWARE_ISSUE_UUID), "RF HW damaged");
         } else if (info.error == android.hardware.radio.V1_6.RadioError.NO_RF_CALIBRATION_INFO) {
             AnomalyReporter.reportAnomaly(
-                    UUID.fromString(RILUtils.RADIO_POWER_FAILURE_NO_RF_CALIBRATION_UUID),
+                    UUID.fromString(RADIO_POWER_FAILURE_NO_RF_CALIBRATION_UUID),
                     "No RF calibration data");
         } else if (info.error != android.hardware.radio.V1_6.RadioError.RADIO_NOT_AVAILABLE
                 && info.error != android.hardware.radio.V1_6.RadioError.NONE) {
             AnomalyReporter.reportAnomaly(
-                    UUID.fromString(RILUtils.RADIO_POWER_FAILURE_BUGREPORT_UUID),
-                    "Radio power failure");
+                    UUID.fromString(RADIO_POWER_FAILURE_BUGREPORT_UUID), "Radio power failure");
         }
     }
 
@@ -2867,7 +3055,7 @@
         if (rr != null) {
             ArrayList<RadioAccessSpecifier> specifiers = new ArrayList<>();
             for (android.hardware.radio.V1_5.RadioAccessSpecifier specifier : halSpecifiers) {
-                specifiers.add(RILUtils.convertHalRadioAccessSpecifier(specifier));
+                specifiers.add(convertRadioAccessSpecifier(specifier));
             }
             mRil.riljLog("getSystemSelectionChannelsResponse: from HIDL: " + specifiers);
             if (info.error == RadioError.NONE) {
@@ -2877,6 +3065,51 @@
         }
     }
 
+    private static RadioAccessSpecifier convertRadioAccessSpecifier(
+            android.hardware.radio.V1_5.RadioAccessSpecifier specifier) {
+        if (specifier == null) return null;
+        ArrayList<Integer> halBands = new ArrayList<>();
+        switch (specifier.bands.getDiscriminator()) {
+            case android.hardware.radio.V1_5.RadioAccessSpecifier.Bands.hidl_discriminator
+                    .geranBands:
+                halBands = specifier.bands.geranBands();
+                break;
+            case android.hardware.radio.V1_5.RadioAccessSpecifier.Bands.hidl_discriminator
+                    .utranBands:
+                halBands = specifier.bands.utranBands();
+                break;
+            case android.hardware.radio.V1_5.RadioAccessSpecifier.Bands.hidl_discriminator
+                    .eutranBands:
+                halBands = specifier.bands.eutranBands();
+                break;
+            case android.hardware.radio.V1_5.RadioAccessSpecifier.Bands.hidl_discriminator
+                    .ngranBands:
+                halBands = specifier.bands.ngranBands();
+                break;
+        }
+        return new RadioAccessSpecifier(convertRanToAnt(specifier.radioAccessNetwork),
+                halBands.stream().mapToInt(Integer::intValue).toArray(),
+                specifier.channels.stream().mapToInt(Integer::intValue).toArray());
+    }
+
+    private static int convertRanToAnt(int ran) {
+        switch (ran) {
+            case android.hardware.radio.V1_5.RadioAccessNetworks.GERAN:
+                return AccessNetworkConstants.AccessNetworkType.GERAN;
+            case android.hardware.radio.V1_5.RadioAccessNetworks.UTRAN:
+                return AccessNetworkConstants.AccessNetworkType.UTRAN;
+            case android.hardware.radio.V1_5.RadioAccessNetworks.EUTRAN:
+                return AccessNetworkConstants.AccessNetworkType.EUTRAN;
+            case android.hardware.radio.V1_5.RadioAccessNetworks.NGRAN:
+                return AccessNetworkConstants.AccessNetworkType.NGRAN;
+            case android.hardware.radio.V1_5.RadioAccessNetworks.CDMA2000:
+                return AccessNetworkConstants.AccessNetworkType.CDMA2000;
+            case android.hardware.radio.V1_5.RadioAccessNetworks.UNKNOWN:
+            default:
+                return AccessNetworkConstants.AccessNetworkType.UNKNOWN;
+        }
+    }
+
     /**
      * @param responseInfo Response info struct containing response type, serial no. and error.
      * @param cellIdentity CellIdentity for the barringInfos.
@@ -2888,8 +3121,7 @@
         RILRequest rr = mRil.processResponse(responseInfo);
 
         if (rr != null) {
-            BarringInfo bi = new BarringInfo(RILUtils.convertHalCellIdentity(cellIdentity),
-                    RILUtils.convertHalBarringInfoList(barringInfos));
+            BarringInfo bi = BarringInfo.create(cellIdentity, barringInfos);
             if (responseInfo.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, bi);
                 // notify all registrants for the possible barring info change
@@ -2945,7 +3177,7 @@
         RILRequest rr = mRil.processResponse_1_6(info);
 
         if (rr != null) {
-            NetworkSlicingConfig ret = RILUtils.convertHalSlicingConfig(slicingConfig);
+            NetworkSlicingConfig ret = new NetworkSlicingConfig(slicingConfig);
             if (info.error == RadioError.NONE) {
                 sendMessageResponse(rr.mResult, ret);
             }
diff --git a/src/java/com/android/internal/telephony/RadioServiceProxy.java b/src/java/com/android/internal/telephony/RadioServiceProxy.java
deleted file mode 100644
index 8650dd0..0000000
--- a/src/java/com/android/internal/telephony/RadioServiceProxy.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.os.RemoteException;
-
-/**
- * A holder for IRadio services. Use getHidl to get IRadio 1.0 and call the HIDL implementations or
- * getAidl to get the AIDL service and call the AIDL implementations of the HAL APIs.
- */
-public abstract class RadioServiceProxy {
-    boolean mIsAidl;
-    HalVersion mHalVersion = RIL.RADIO_HAL_VERSION_UNKNOWN;
-    volatile android.hardware.radio.V1_0.IRadio mRadioProxy = null;
-
-    /**
-     * Whether RadioServiceProxy is an AIDL or HIDL implementation
-     * @return true if AIDL, false if HIDL
-     */
-    public boolean isAidl() {
-        return mIsAidl;
-    }
-
-    /**
-     * Set IRadio as the HIDL implementation for RadioServiceProxy
-     * @param halVersion Radio HAL version
-     * @param radio      IRadio implementation
-     */
-    public void setHidl(HalVersion halVersion, android.hardware.radio.V1_0.IRadio radio) {
-        mHalVersion = halVersion;
-        mRadioProxy = radio;
-        mIsAidl = false;
-    }
-
-    /**
-     * Get the HIDL implementation of RadioServiceProxy
-     * @return IRadio implementation
-     */
-    public android.hardware.radio.V1_0.IRadio getHidl() {
-        return mRadioProxy;
-    }
-
-    /**
-     * Reset RadioServiceProxy
-     */
-    public void clear() {
-        mHalVersion = RIL.RADIO_HAL_VERSION_UNKNOWN;
-        mRadioProxy = null;
-    }
-
-    /**
-     * Check whether an implementation exists for this service
-     * @return false if there is neither a HIDL nor AIDL implementation
-     */
-    public boolean isEmpty() {
-        return mRadioProxy == null;
-    }
-
-    /**
-     * Call responseAcknowledgement for the service
-     * @throws RemoteException
-     */
-    public void responseAcknowledgement() throws RemoteException {
-        if (isEmpty()) return;
-        if (!isAidl()) mRadioProxy.responseAcknowledgement();
-    }
-}
diff --git a/src/java/com/android/internal/telephony/RadioSimProxy.java b/src/java/com/android/internal/telephony/RadioSimProxy.java
deleted file mode 100644
index c7e19c4..0000000
--- a/src/java/com/android/internal/telephony/RadioSimProxy.java
+++ /dev/null
@@ -1,811 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static com.android.internal.telephony.RILConstants.REQUEST_NOT_SUPPORTED;
-
-import android.os.AsyncResult;
-import android.os.Message;
-import android.os.RemoteException;
-import android.telephony.CarrierRestrictionRules;
-import android.telephony.ImsiEncryptionInfo;
-import android.telephony.Rlog;
-import android.telephony.TelephonyManager;
-
-import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
-import com.android.internal.telephony.uicc.SimPhonebookRecord;
-
-/**
- * A holder for IRadioSim. Use getHidl to get IRadio 1.0 and call the HIDL implementations or
- * getAidl to get IRadioSim and call the AIDL implementations of the HAL APIs.
- */
-public class RadioSimProxy extends RadioServiceProxy {
-    private static final String TAG = "RadioSimProxy";
-    private volatile android.hardware.radio.sim.IRadioSim mSimProxy = null;
-
-    /**
-     * Set IRadioSim as the AIDL implementation for RadioServiceProxy
-     * @param halVersion Radio HAL version
-     * @param sim IRadioSim implementation
-     */
-    public void setAidl(HalVersion halVersion, android.hardware.radio.sim.IRadioSim sim) {
-        mHalVersion = halVersion;
-        mSimProxy = sim;
-        mIsAidl = true;
-        Rlog.d(TAG, "AIDL initialized");
-    }
-
-    /**
-     * Get the AIDL implementation of RadioSimProxy
-     * @return IRadioSim implementation
-     */
-    public android.hardware.radio.sim.IRadioSim getAidl() {
-        return mSimProxy;
-    }
-
-    /**
-     * Reset RadioSimProxy
-     */
-    @Override
-    public void clear() {
-        super.clear();
-        mSimProxy = null;
-    }
-
-    /**
-     * Check whether a RadioSim implementation exists
-     * @return true if there is neither a HIDL nor AIDL implementation
-     */
-    @Override
-    public boolean isEmpty() {
-        return mRadioProxy == null && mSimProxy == null;
-    }
-
-    /**
-     * Call IRadioSim#areUiccApplicationsEnabled
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void areUiccApplicationsEnabled(int serial) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_5)) return;
-        if (isAidl()) {
-            mSimProxy.areUiccApplicationsEnabled(serial);
-        } else {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).areUiccApplicationsEnabled(serial);
-        }
-    }
-
-    /**
-     * Call IRadioSim#changeIccPin2ForApp
-     * @param serial Serial number of request
-     * @param oldPin2 Old PIN value
-     * @param newPin2 New PIN value
-     * @param aid Application ID
-     * @throws RemoteException
-     */
-    public void changeIccPin2ForApp(int serial, String oldPin2, String newPin2, String aid)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.changeIccPin2ForApp(serial, oldPin2, newPin2, aid);
-        } else {
-            mRadioProxy.changeIccPin2ForApp(serial, oldPin2, newPin2, aid);
-        }
-    }
-
-    /**
-     * Call IRadioSim#changeIccPinForApp
-     * @param serial Serial number of request
-     * @param oldPin Old PIN value
-     * @param newPin New PIN value
-     * @param aid Application ID
-     * @throws RemoteException
-     */
-    public void changeIccPinForApp(int serial, String oldPin, String newPin, String aid)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.changeIccPinForApp(serial, oldPin, newPin, aid);
-        } else {
-            mRadioProxy.changeIccPinForApp(serial, oldPin, newPin, aid);
-        }
-    }
-
-    /**
-     * Call IRadioSim#enableUiccApplications
-     * @param serial Serial number of request
-     * @param enable Whether or not to enable UiccApplications on the SIM
-     * @throws RemoteException
-     */
-    public void enableUiccApplications(int serial, boolean enable) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_5)) return;
-        if (isAidl()) {
-            mSimProxy.enableUiccApplications(serial, enable);
-        } else {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).enableUiccApplications(
-                    serial, enable);
-        }
-    }
-
-    /**
-     * Call IRadioSim#getAllowedCarriers
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getAllowedCarriers(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.getAllowedCarriers(serial);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_4)) {
-            ((android.hardware.radio.V1_4.IRadio) mRadioProxy).getAllowedCarriers_1_4(serial);
-        } else {
-            mRadioProxy.getAllowedCarriers(serial);
-        }
-    }
-
-    /**
-     * Call IRadioSim#getCdmaSubscription
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getCdmaSubscription(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.getCdmaSubscription(serial);
-        } else {
-            mRadioProxy.getCDMASubscription(serial);
-        }
-    }
-
-    /**
-     * Call IRadioSim#getCdmaSubscriptionSource
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getCdmaSubscriptionSource(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.getCdmaSubscriptionSource(serial);
-        } else {
-            mRadioProxy.getCdmaSubscriptionSource(serial);
-        }
-    }
-
-    /**
-     * Call IRadioSim#getFacilityLockForApp
-     * @param serial Serial number of request
-     * @param facility One of CB_FACILTY_*
-     * @param password Password or "" if not required
-     * @param serviceClass Sum of SERVICE_CLASS_*
-     * @param appId Application ID or null if none
-     * @throws RemoteException
-     */
-    public void getFacilityLockForApp(int serial, String facility, String password,
-            int serviceClass, String appId) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.getFacilityLockForApp(serial, facility, password, serviceClass, appId);
-        } else {
-            mRadioProxy.getFacilityLockForApp(serial, facility, password, serviceClass, appId);
-        }
-    }
-
-    /**
-     * Call IRadioSim#getIccCardStatus
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getIccCardStatus(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.getIccCardStatus(serial);
-        } else {
-            mRadioProxy.getIccCardStatus(serial);
-        }
-    }
-
-    /**
-     * Call IRadioSim#getImsiForApp
-     * @param serial Serial number of request
-     * @param aid Application ID
-     * @throws RemoteException
-     */
-    public void getImsiForApp(int serial, String aid) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.getImsiForApp(serial, aid);
-        } else {
-            mRadioProxy.getImsiForApp(serial, aid);
-        }
-    }
-
-    /**
-     * Call IRadioSim#getSimPhonebookCapacity
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getSimPhonebookCapacity(int serial) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (isAidl()) {
-            mSimProxy.getSimPhonebookCapacity(serial);
-        } else {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getSimPhonebookCapacity(serial);
-        }
-    }
-
-    /**
-     * Call IRadioSim#getSimPhonebookRecords
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getSimPhonebookRecords(int serial) throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (isAidl()) {
-            mSimProxy.getSimPhonebookRecords(serial);
-        } else {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getSimPhonebookRecords(serial);
-        }
-    }
-
-    /**
-     * Call IRadioSim#iccCloseLogicalChannel
-     * @param serial Serial number of request
-     * @param channelId Channel ID of the channel to be closed
-     * @throws RemoteException
-     */
-    public void iccCloseLogicalChannel(int serial, int channelId) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.iccCloseLogicalChannel(serial, channelId);
-        } else {
-            mRadioProxy.iccCloseLogicalChannel(serial, channelId);
-        }
-    }
-
-    /**
-     * Call IRadioSim#iccIoForApp
-     * @param serial Serial number of request
-     * @param command Command
-     * @param fileId File ID
-     * @param path Path
-     * @param p1 P1 value of the command
-     * @param p2 P2 value of the command
-     * @param p3 P3 value of the command
-     * @param data Data to be sent
-     * @param pin2 PIN 2 value
-     * @param aid Application ID
-     * @throws RemoteException
-     */
-    public void iccIoForApp(int serial, int command, int fileId, String path, int p1, int p2,
-            int p3, String data, String pin2, String aid) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            android.hardware.radio.sim.IccIo iccIo = new android.hardware.radio.sim.IccIo();
-            iccIo.command = command;
-            iccIo.fileId = fileId;
-            iccIo.path = path;
-            iccIo.p1 = p1;
-            iccIo.p2 = p2;
-            iccIo.p3 = p3;
-            iccIo.data = data;
-            iccIo.pin2 = pin2;
-            iccIo.aid = aid;
-            mSimProxy.iccIoForApp(serial, iccIo);
-        } else {
-            android.hardware.radio.V1_0.IccIo iccIo = new android.hardware.radio.V1_0.IccIo();
-            iccIo.command = command;
-            iccIo.fileId = fileId;
-            iccIo.path = path;
-            iccIo.p1 = p1;
-            iccIo.p2 = p2;
-            iccIo.p3 = p3;
-            iccIo.data = data;
-            iccIo.pin2 = pin2;
-            iccIo.aid = aid;
-            mRadioProxy.iccIOForApp(serial, iccIo);
-        }
-    }
-
-    /**
-     * Call IRadioSim#iccOpenLogicalChannel
-     * @param serial Serial number of request
-     * @param aid Application ID
-     * @param p2 P2 value of the command
-     * @throws RemoteException
-     */
-    public void iccOpenLogicalChannel(int serial, String aid, int p2) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.iccOpenLogicalChannel(serial, aid, p2);
-        } else {
-            mRadioProxy.iccOpenLogicalChannel(serial, aid, p2);
-        }
-    }
-
-    /**
-     * Call IRadioSim#iccTransmitApduBasicChannel
-     * @param serial Serial number of request
-     * @param cla Class of the command
-     * @param instruction Instruction of the command
-     * @param p1 P1 value of the command
-     * @param p2 P2 value of the command
-     * @param p3 P3 value of the command
-     * @param data Data to be sent
-     * @throws RemoteException
-     */
-    public void iccTransmitApduBasicChannel(int serial, int cla, int instruction, int p1, int p2,
-            int p3, String data) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.iccTransmitApduBasicChannel(serial,
-                    RILUtils.convertToHalSimApduAidl(0, cla, instruction, p1, p2, p3, data));
-        } else {
-            mRadioProxy.iccTransmitApduBasicChannel(serial,
-                    RILUtils.convertToHalSimApdu(0, cla, instruction, p1, p2, p3, data));
-        }
-    }
-
-    /**
-     * Call IRadioSim#iccTransmitApduLogicalChannel
-     * @param serial Serial number of request
-     * @param channel Channel ID of the channel to use for communication
-     * @param cla Class of the command
-     * @param instruction Instruction of the command
-     * @param p1 P1 value of the command
-     * @param p2 P2 value of the command
-     * @param p3 P3 value of the command
-     * @param data Data to be sent
-     * @throws RemoteException
-     */
-    public void iccTransmitApduLogicalChannel(int serial, int channel, int cla, int instruction,
-            int p1, int p2, int p3, String data) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.iccTransmitApduLogicalChannel(serial,
-                    RILUtils.convertToHalSimApduAidl(channel, cla, instruction, p1, p2, p3, data));
-        } else {
-            mRadioProxy.iccTransmitApduLogicalChannel(serial,
-                    RILUtils.convertToHalSimApdu(channel, cla, instruction, p1, p2, p3, data));
-        }
-    }
-
-    /**
-     * Call IRadioSim#reportStkServiceIsRunning
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void reportStkServiceIsRunning(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.reportStkServiceIsRunning(serial);
-        } else {
-            mRadioProxy.reportStkServiceIsRunning(serial);
-        }
-    }
-
-    /**
-     * Call IRadioSim#requestIccSimAuthentication
-     * @param serial Serial number of request
-     * @param authContext P2 parameter that specifies the authentication context
-     * @param authData Authentication challenge data
-     * @param aid Application ID of the application/slot to send the auth command to
-     * @throws RemoteException
-     */
-    public void requestIccSimAuthentication(int serial, int authContext, String authData,
-            String aid) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.requestIccSimAuthentication(serial, authContext, authData, aid);
-        } else {
-            mRadioProxy.requestIccSimAuthentication(serial, authContext, authData, aid);
-        }
-    }
-
-    /**
-     * Call IRadioSim#responseAcknowledgement
-     * @throws RemoteException
-     */
-    @Override
-    public void responseAcknowledgement() throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.responseAcknowledgement();
-        } else {
-            mRadioProxy.responseAcknowledgement();
-        }
-    }
-
-    /**
-     * Call IRadioSim#sendEnvelope
-     * @param serial Serial number of request
-     * @param contents String containing SAT/USAT response in hexadecimal format starting with
-     *                 command tag
-     * @throws RemoteException
-     */
-    public void sendEnvelope(int serial, String contents) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.sendEnvelope(serial, contents);
-        } else {
-            mRadioProxy.sendEnvelope(serial, contents);
-        }
-    }
-
-    /**
-     * Call IRadioSim#sendEnvelopeWithStatus
-     * @param serial Serial number of request
-     * @param contents String containing SAT/USAT response in hexadecimal format starting with
-     *                 command tag
-     * @throws RemoteException
-     */
-    public void sendEnvelopeWithStatus(int serial, String contents) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.sendEnvelopeWithStatus(serial, contents);
-        } else {
-            mRadioProxy.sendEnvelopeWithStatus(serial, contents);
-        }
-    }
-
-    /**
-     * Call IRadioSim#sendTerminalResponseToSim
-     * @param serial Serial number of request
-     * @param contents String containing SAT/USAT response in hexadecimal format starting with
-     *                 first byte of response data
-     * @throws RemoteException
-     */
-    public void sendTerminalResponseToSim(int serial, String contents) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.sendTerminalResponseToSim(serial, contents);
-        } else {
-            mRadioProxy.sendTerminalResponseToSim(serial, contents);
-        }
-    }
-
-    /**
-     * Call IRadioSim#setAllowedCarriers
-     * @param serial Serial number of request
-     * @param carrierRestrictionRules Allowed carriers
-     * @param result Result to return in case of error
-     * @throws RemoteException
-     */
-    public void setAllowedCarriers(int serial, CarrierRestrictionRules carrierRestrictionRules,
-            Message result) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            // Prepare structure with allowed list, excluded list and priority
-            android.hardware.radio.sim.CarrierRestrictions carrierRestrictions =
-                    new android.hardware.radio.sim.CarrierRestrictions();
-            carrierRestrictions.allowedCarriers = RILUtils.convertToHalCarrierRestrictionListAidl(
-                    carrierRestrictionRules.getAllowedCarriers());
-            carrierRestrictions.excludedCarriers = RILUtils.convertToHalCarrierRestrictionListAidl(
-                    carrierRestrictionRules.getExcludedCarriers());
-            carrierRestrictions.allowedCarriersPrioritized =
-                    (carrierRestrictionRules.getDefaultCarrierRestriction()
-                            == CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED);
-            mSimProxy.setAllowedCarriers(serial, carrierRestrictions,
-                    RILUtils.convertToHalSimLockMultiSimPolicyAidl(
-                            carrierRestrictionRules.getMultiSimPolicy()));
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_4)) {
-            // Prepare structure with allowed list, excluded list and priority
-            android.hardware.radio.V1_4.CarrierRestrictionsWithPriority carrierRestrictions =
-                    new android.hardware.radio.V1_4.CarrierRestrictionsWithPriority();
-            carrierRestrictions.allowedCarriers = RILUtils.convertToHalCarrierRestrictionList(
-                    carrierRestrictionRules.getAllowedCarriers());
-            carrierRestrictions.excludedCarriers = RILUtils.convertToHalCarrierRestrictionList(
-                    carrierRestrictionRules.getExcludedCarriers());
-            carrierRestrictions.allowedCarriersPrioritized =
-                    (carrierRestrictionRules.getDefaultCarrierRestriction()
-                            == CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED);
-            ((android.hardware.radio.V1_4.IRadio) mRadioProxy).setAllowedCarriers_1_4(
-                    serial, carrierRestrictions, RILUtils.convertToHalSimLockMultiSimPolicy(
-                            carrierRestrictionRules.getMultiSimPolicy()));
-        } else {
-            boolean isAllCarriersAllowed = carrierRestrictionRules.isAllCarriersAllowed();
-            boolean supported = (isAllCarriersAllowed
-                    || (carrierRestrictionRules.getExcludedCarriers().isEmpty()
-                    && (carrierRestrictionRules.getDefaultCarrierRestriction()
-                    == CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED)))
-                    && (RILUtils.convertToHalSimLockMultiSimPolicy(
-                    carrierRestrictionRules.getMultiSimPolicy())
-                    == android.hardware.radio.V1_4.SimLockMultiSimPolicy.NO_MULTISIM_POLICY);
-
-            if (!supported) {
-                // Feature is not supported by IRadio interface
-                if (result != null) {
-                    AsyncResult.forMessage(result, null,
-                            CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                    result.sendToTarget();
-                }
-                return;
-            }
-
-            // Prepare structure with allowed list
-            android.hardware.radio.V1_0.CarrierRestrictions carrierRestrictions =
-                    new android.hardware.radio.V1_0.CarrierRestrictions();
-            carrierRestrictions.allowedCarriers = RILUtils.convertToHalCarrierRestrictionList(
-                    carrierRestrictionRules.getAllowedCarriers());
-            mRadioProxy.setAllowedCarriers(serial, isAllCarriersAllowed, carrierRestrictions);
-        }
-    }
-
-    /**
-     * Call IRadioSim#setCarrierInfoForImsiEncryption
-     * @param serial Serial number of request
-     * @param imsiEncryptionInfo ImsiEncryptionInfo
-     * @throws RemoteException
-     */
-    public void setCarrierInfoForImsiEncryption(int serial, ImsiEncryptionInfo imsiEncryptionInfo)
-            throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_1)) return;
-        if (isAidl()) {
-            android.hardware.radio.sim.ImsiEncryptionInfo halImsiInfo =
-                    new android.hardware.radio.sim.ImsiEncryptionInfo();
-            halImsiInfo.mnc = imsiEncryptionInfo.getMnc();
-            halImsiInfo.mcc = imsiEncryptionInfo.getMcc();
-            halImsiInfo.keyIdentifier = imsiEncryptionInfo.getKeyIdentifier();
-            if (imsiEncryptionInfo.getExpirationTime() != null) {
-                halImsiInfo.expirationTime = imsiEncryptionInfo.getExpirationTime().getTime();
-            }
-            halImsiInfo.carrierKey = imsiEncryptionInfo.getPublicKey().getEncoded();
-            halImsiInfo.keyType = (byte) imsiEncryptionInfo.getKeyType();
-
-            mSimProxy.setCarrierInfoForImsiEncryption(serial, halImsiInfo);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            android.hardware.radio.V1_6.ImsiEncryptionInfo halImsiInfo =
-                    new android.hardware.radio.V1_6.ImsiEncryptionInfo();
-            halImsiInfo.base.mnc = imsiEncryptionInfo.getMnc();
-            halImsiInfo.base.mcc = imsiEncryptionInfo.getMcc();
-            halImsiInfo.base.keyIdentifier = imsiEncryptionInfo.getKeyIdentifier();
-            if (imsiEncryptionInfo.getExpirationTime() != null) {
-                halImsiInfo.base.expirationTime = imsiEncryptionInfo.getExpirationTime().getTime();
-            }
-            for (byte b : imsiEncryptionInfo.getPublicKey().getEncoded()) {
-                halImsiInfo.base.carrierKey.add(new Byte(b));
-            }
-            halImsiInfo.keyType = (byte) imsiEncryptionInfo.getKeyType();
-
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).setCarrierInfoForImsiEncryption_1_6(
-                    serial, halImsiInfo);
-        } else {
-            android.hardware.radio.V1_1.ImsiEncryptionInfo halImsiInfo =
-                    new android.hardware.radio.V1_1.ImsiEncryptionInfo();
-            halImsiInfo.mnc = imsiEncryptionInfo.getMnc();
-            halImsiInfo.mcc = imsiEncryptionInfo.getMcc();
-            halImsiInfo.keyIdentifier = imsiEncryptionInfo.getKeyIdentifier();
-            if (imsiEncryptionInfo.getExpirationTime() != null) {
-                halImsiInfo.expirationTime = imsiEncryptionInfo.getExpirationTime().getTime();
-            }
-            for (byte b : imsiEncryptionInfo.getPublicKey().getEncoded()) {
-                halImsiInfo.carrierKey.add(new Byte(b));
-            }
-
-            ((android.hardware.radio.V1_1.IRadio) mRadioProxy).setCarrierInfoForImsiEncryption(
-                    serial, halImsiInfo);
-        }
-    }
-
-    /**
-     * Call IRadioSim#setCdmaSubscriptionSource
-     * @param serial Serial number of request
-     * @param cdmaSub One of  CDMA_SUBSCRIPTION_*
-     * @throws RemoteException
-     */
-    public void setCdmaSubscriptionSource(int serial, int cdmaSub) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.setCdmaSubscriptionSource(serial, cdmaSub);
-        } else {
-            mRadioProxy.setCdmaSubscriptionSource(serial, cdmaSub);
-        }
-    }
-
-    /**
-     * Call IRadioSim#setFacilityLockForApp
-     * @param serial Serial number of request
-     * @param facility One of CB_FACILTY_*
-     * @param lockState True means lock, false means unlock
-     * @param password Password or "" if not required
-     * @param serviceClass Sum of SERVICE_CLASS_*
-     * @param appId Application ID or null if none
-     * @throws RemoteException
-     */
-    public void setFacilityLockForApp(int serial, String facility, boolean lockState,
-            String password, int serviceClass, String appId) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.setFacilityLockForApp(
-                    serial, facility, lockState, password, serviceClass, appId);
-        } else {
-            mRadioProxy.setFacilityLockForApp(
-                    serial, facility, lockState, password, serviceClass, appId);
-        }
-    }
-
-    /**
-     * Call IRadioSim#setSimCardPower
-     * @param serial Serial number of request
-     * @param state SIM state (power down, power up, pass through)
-     * @param result Result to return in case of error
-     * @throws RemoteException
-     */
-    public void setSimCardPower(int serial, int state, Message result) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.setSimCardPower(serial, state);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).setSimCardPower_1_6(serial, state);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_1)) {
-            ((android.hardware.radio.V1_1.IRadio) mRadioProxy).setSimCardPower_1_1(serial, state);
-        } else {
-            switch (state) {
-                case TelephonyManager.CARD_POWER_DOWN: {
-                    mRadioProxy.setSimCardPower(serial, false);
-                    break;
-                }
-                case TelephonyManager.CARD_POWER_UP: {
-                    mRadioProxy.setSimCardPower(serial, true);
-                    break;
-                }
-                default: {
-                    if (result != null) {
-                        AsyncResult.forMessage(result, null,
-                                CommandException.fromRilErrno(REQUEST_NOT_SUPPORTED));
-                        result.sendToTarget();
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Call IRadioSim#setUiccSubscription
-     * @param serial Serial number of request
-     * @param slotId Slot ID
-     * @param appIndex Application index in the card
-     * @param subId Subscription ID
-     * @param subStatus Activation status; 1 = activate and 0 = deactivate
-     * @throws RemoteException
-     */
-    public void setUiccSubscription(int serial, int slotId, int appIndex, int subId, int subStatus)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            android.hardware.radio.sim.SelectUiccSub info =
-                    new android.hardware.radio.sim.SelectUiccSub();
-            info.slot = slotId;
-            info.appIndex = appIndex;
-            info.subType = subId;
-            info.actStatus = subStatus;
-            mSimProxy.setUiccSubscription(serial, info);
-        } else {
-            android.hardware.radio.V1_0.SelectUiccSub info =
-                    new android.hardware.radio.V1_0.SelectUiccSub();
-            info.slot = slotId;
-            info.appIndex = appIndex;
-            info.subType = subId;
-            info.actStatus = subStatus;
-            mRadioProxy.setUiccSubscription(serial, info);
-        }
-    }
-
-    /**
-     * Call IRadioSim#supplyIccPin2ForApp
-     * @param serial Serial number of request
-     * @param pin2 PIN 2 value
-     * @param aid Application ID
-     * @throws RemoteException
-     */
-    public void supplyIccPin2ForApp(int serial, String pin2, String aid) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.supplyIccPin2ForApp(serial, pin2, aid);
-        } else {
-            mRadioProxy.supplyIccPin2ForApp(serial, pin2, aid);
-        }
-    }
-
-    /**
-     * Call IRadioSim#supplyIccPinForApp
-     * @param serial Serial number of request
-     * @param pin PIN value
-     * @param aid Application ID
-     * @throws RemoteException
-     */
-    public void supplyIccPinForApp(int serial, String pin, String aid) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.supplyIccPinForApp(serial, pin, aid);
-        } else {
-            mRadioProxy.supplyIccPinForApp(serial, pin, aid);
-        }
-    }
-
-    /**
-     * Call IRadioSim#supplyIccPuk2ForApp
-     * @param serial Serial number of request
-     * @param puk2 PUK 2 value
-     * @param pin2 PIN 2 value
-     * @param aid Application ID
-     * @throws RemoteException
-     */
-    public void supplyIccPuk2ForApp(int serial, String puk2, String pin2, String aid)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.supplyIccPuk2ForApp(serial, puk2, pin2, aid);
-        } else {
-            mRadioProxy.supplyIccPuk2ForApp(serial, puk2, pin2, aid);
-        }
-    }
-
-    /**
-     * Call IRadioSim#supplyIccPukForApp
-     * @param serial Serial number of request
-     * @param puk PUK value
-     * @param pin PIN value
-     * @param aid Application ID
-     * @throws RemoteException
-     */
-    public void supplyIccPukForApp(int serial, String puk, String pin, String aid)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mSimProxy.supplyIccPukForApp(serial, puk, pin, aid);
-        } else {
-            mRadioProxy.supplyIccPukForApp(serial, puk, pin, aid);
-        }
-    }
-
-    /**
-     * Call IRadioSim#supplySimDepersonalization
-     * @param serial Serial number of request
-     * @param persoType SIM personalization type
-     * @param controlKey Unlock code for removing SIM personalization from this device
-     * @throws RemoteException
-     */
-    public void supplySimDepersonalization(int serial, PersoSubState persoType, String controlKey)
-            throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_5)) return;
-        if (isAidl()) {
-            mSimProxy.supplySimDepersonalization(serial,
-                    RILUtils.convertToHalPersoTypeAidl(persoType), controlKey);
-        } else {
-            ((android.hardware.radio.V1_5.IRadio) mRadioProxy).supplySimDepersonalization(serial,
-                    RILUtils.convertToHalPersoType(persoType), controlKey);
-        }
-    }
-
-    /**
-     * Call IRadioSim#updateSimPhonebookRecords
-     * @param serial Serial number of request
-     * @param recordInfo ADN record information to be updated
-     * @throws RemoteException
-     */
-    public void updateSimPhonebookRecords(int serial, SimPhonebookRecord recordInfo)
-            throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_6)) return;
-        if (isAidl()) {
-            mSimProxy.updateSimPhonebookRecords(serial,
-                    RILUtils.convertToHalPhonebookRecordInfoAidl(recordInfo));
-        } else {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).updateSimPhonebookRecords(serial,
-                    RILUtils.convertToHalPhonebookRecordInfo(recordInfo));
-        }
-    }
-}
diff --git a/src/java/com/android/internal/telephony/RadioVoiceProxy.java b/src/java/com/android/internal/telephony/RadioVoiceProxy.java
deleted file mode 100644
index 6ac603b..0000000
--- a/src/java/com/android/internal/telephony/RadioVoiceProxy.java
+++ /dev/null
@@ -1,701 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.os.RemoteException;
-import android.telephony.PhoneNumberUtils;
-import android.telephony.Rlog;
-import android.telephony.emergency.EmergencyNumber;
-
-import java.util.ArrayList;
-
-/**
- * A holder for IRadioVoice. Use getHidl to get IRadio 1.0 and call the HIDL implementations or
- * getAidl to get IRadioVoice and call the AIDL implementations of the HAL APIs.
- */
-public class RadioVoiceProxy extends RadioServiceProxy {
-    private static final String TAG = "RadioVoiceProxy";
-    private volatile android.hardware.radio.voice.IRadioVoice mVoiceProxy = null;
-
-    /**
-     * Set IRadioVoice as the AIDL implementation for RadioServiceProxy
-     * @param halVersion Radio HAL version
-     * @param voice IRadioVoice implementation
-     */
-    public void setAidl(HalVersion halVersion, android.hardware.radio.voice.IRadioVoice voice) {
-        mHalVersion = halVersion;
-        mVoiceProxy = voice;
-        mIsAidl = true;
-        Rlog.d(TAG, "AIDL initialized");
-    }
-
-    /**
-     * Get the AIDL implementation of RadioVoiceProxy
-     * @return IRadioVoice implementation
-     */
-    public android.hardware.radio.voice.IRadioVoice getAidl() {
-        return mVoiceProxy;
-    }
-
-    /**
-     * Reset RadioVoiceProxy
-     */
-    @Override
-    public void clear() {
-        super.clear();
-        mVoiceProxy = null;
-    }
-
-    /**
-     * Check whether a RadioVoice implementation exists
-     * @return true if there is neither a HIDL nor AIDL implementation
-     */
-    @Override
-    public boolean isEmpty() {
-        return mRadioProxy == null && mVoiceProxy == null;
-    }
-
-    /**
-     * Call IRadioVoice#acceptCall
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void acceptCall(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.acceptCall(serial);
-        } else {
-            mRadioProxy.acceptCall(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#cancelPendingUssd
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void cancelPendingUssd(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.cancelPendingUssd(serial);
-        } else {
-            mRadioProxy.cancelPendingUssd(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#conference
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void conference(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.conference(serial);
-        } else {
-            mRadioProxy.conference(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#dial
-     * @param serial Serial number of request
-     * @param address Address
-     * @param clirMode CLIR mode
-     * @param uusInfo UUS info
-     * @throws RemoteException
-     */
-    public void dial(int serial, String address, int clirMode, UUSInfo uusInfo)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.dial(serial, RILUtils.convertToHalDialAidl(address, clirMode, uusInfo));
-        } else {
-            mRadioProxy.dial(serial, RILUtils.convertToHalDial(address, clirMode, uusInfo));
-        }
-    }
-
-    /**
-     * Call IRadioVoice#emergencyDial
-     * @param serial Serial number of request
-     * @param address Address
-     * @param emergencyNumberInfo Emergency number information
-     * @param hasKnownUserIntentEmergency Whether or not the request has known user intent emergency
-     * @param clirMode CLIR mode
-     * @param uusInfo UUS info
-     * @throws RemoteException
-     */
-    public void emergencyDial(int serial, String address, EmergencyNumber emergencyNumberInfo,
-            boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo)
-            throws RemoteException {
-        if (isEmpty() || mHalVersion.less(RIL.RADIO_HAL_VERSION_1_4)) return;
-        if (isAidl()) {
-            mVoiceProxy.emergencyDial(serial,
-                    RILUtils.convertToHalDialAidl(address, clirMode, uusInfo),
-                    emergencyNumberInfo.getEmergencyServiceCategoryBitmaskInternalDial(),
-                    emergencyNumberInfo.getEmergencyUrns() != null
-                            ? emergencyNumberInfo.getEmergencyUrns().stream().toArray(String[]::new)
-                            : new String[0],
-                    emergencyNumberInfo.getEmergencyCallRouting(),
-                    hasKnownUserIntentEmergency,
-                    emergencyNumberInfo.getEmergencyNumberSourceBitmask()
-                            == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).emergencyDial_1_6(serial,
-                    RILUtils.convertToHalDial(address, clirMode, uusInfo),
-                    emergencyNumberInfo.getEmergencyServiceCategoryBitmaskInternalDial(),
-                    emergencyNumberInfo.getEmergencyUrns() != null
-                            ? new ArrayList(emergencyNumberInfo.getEmergencyUrns())
-                            : new ArrayList<>(),
-                    emergencyNumberInfo.getEmergencyCallRouting(),
-                    hasKnownUserIntentEmergency,
-                    emergencyNumberInfo.getEmergencyNumberSourceBitmask()
-                            == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST);
-        } else {
-            ((android.hardware.radio.V1_4.IRadio) mRadioProxy).emergencyDial(serial,
-                    RILUtils.convertToHalDial(address, clirMode, uusInfo),
-                    emergencyNumberInfo.getEmergencyServiceCategoryBitmaskInternalDial(),
-                    emergencyNumberInfo.getEmergencyUrns() != null
-                            ? new ArrayList(emergencyNumberInfo.getEmergencyUrns())
-                            : new ArrayList<>(),
-                    emergencyNumberInfo.getEmergencyCallRouting(),
-                    hasKnownUserIntentEmergency,
-                    emergencyNumberInfo.getEmergencyNumberSourceBitmask()
-                            == EmergencyNumber.EMERGENCY_NUMBER_SOURCE_TEST);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#exitEmergencyCallbackMode
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void exitEmergencyCallbackMode(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.exitEmergencyCallbackMode(serial);
-        } else {
-            mRadioProxy.exitEmergencyCallbackMode(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#explicitCallTransfer
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void explicitCallTransfer(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.explicitCallTransfer(serial);
-        } else {
-            mRadioProxy.explicitCallTransfer(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#getCallForwardStatus
-     * @param serial Serial number of request
-     * @param cfReason One of CF_REASON_*
-     * @param serviceClass Sum of SERVICE_CLASS_*
-     * @param number Number
-     * @throws RemoteException
-     */
-    public void getCallForwardStatus(int serial, int cfReason, int serviceClass, String number)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            android.hardware.radio.voice.CallForwardInfo cfInfo =
-                    new android.hardware.radio.voice.CallForwardInfo();
-            cfInfo.reason = cfReason;
-            cfInfo.serviceClass = serviceClass;
-            cfInfo.toa = PhoneNumberUtils.toaFromString(number);
-            cfInfo.number = RILUtils.convertNullToEmptyString(number);
-            cfInfo.timeSeconds = 0;
-            mVoiceProxy.getCallForwardStatus(serial, cfInfo);
-        } else {
-            android.hardware.radio.V1_0.CallForwardInfo cfInfo =
-                    new android.hardware.radio.V1_0.CallForwardInfo();
-            cfInfo.reason = cfReason;
-            cfInfo.serviceClass = serviceClass;
-            cfInfo.toa = PhoneNumberUtils.toaFromString(number);
-            cfInfo.number = RILUtils.convertNullToEmptyString(number);
-            cfInfo.timeSeconds = 0;
-            mRadioProxy.getCallForwardStatus(serial, cfInfo);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#getCallWaiting
-     * @param serial Serial number of request
-     * @param serviceClass Sum of SERVICE_CLASS_*
-     * @throws RemoteException
-     */
-    public void getCallWaiting(int serial, int serviceClass) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.getCallWaiting(serial, serviceClass);
-        } else {
-            mRadioProxy.getCallWaiting(serial, serviceClass);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#getClip
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getClip(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.getClip(serial);
-        } else {
-            mRadioProxy.getClip(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#getClir
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getClir(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.getClir(serial);
-        } else {
-            mRadioProxy.getClir(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#getCurrentCalls
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getCurrentCalls(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.getCurrentCalls(serial);
-        } else if (mHalVersion.greaterOrEqual(RIL.RADIO_HAL_VERSION_1_6)) {
-            ((android.hardware.radio.V1_6.IRadio) mRadioProxy).getCurrentCalls_1_6(serial);
-        } else {
-            mRadioProxy.getCurrentCalls(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#getLastCallFailCause
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getLastCallFailCause(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.getLastCallFailCause(serial);
-        } else {
-            mRadioProxy.getLastCallFailCause(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#getMute
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getMute(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.getMute(serial);
-        } else {
-            mRadioProxy.getMute(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#getPreferredVoicePrivacy
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getPreferredVoicePrivacy(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.getPreferredVoicePrivacy(serial);
-        } else {
-            mRadioProxy.getPreferredVoicePrivacy(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#getTtyMode
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void getTtyMode(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.getTtyMode(serial);
-        } else {
-            mRadioProxy.getTTYMode(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#handleStkCallSetupRequestFromSim
-     * @param serial Serial number of request
-     * @param accept Whether or not the call is to be accepted
-     * @throws RemoteException
-     */
-    public void handleStkCallSetupRequestFromSim(int serial, boolean accept)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.handleStkCallSetupRequestFromSim(serial, accept);
-        } else {
-            mRadioProxy.handleStkCallSetupRequestFromSim(serial, accept);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#hangup
-     * @param serial Serial number of request
-     * @param gsmIndex Connection index
-     * @throws RemoteException
-     */
-    public void hangup(int serial, int gsmIndex) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.hangup(serial, gsmIndex);
-        } else {
-            mRadioProxy.hangup(serial, gsmIndex);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#hangupForegroundResumeBackground
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void hangupForegroundResumeBackground(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.hangupForegroundResumeBackground(serial);
-        } else {
-            mRadioProxy.hangupForegroundResumeBackground(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#hangupWaitingOrBackground
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void hangupWaitingOrBackground(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.hangupWaitingOrBackground(serial);
-        } else {
-            mRadioProxy.hangupWaitingOrBackground(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#isVoNrEnabled
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void isVoNrEnabled(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.isVoNrEnabled(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#rejectCall
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void rejectCall(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.rejectCall(serial);
-        } else {
-            mRadioProxy.rejectCall(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#responseAcknowledgement
-     * @throws RemoteException
-     */
-    @Override
-    public void responseAcknowledgement() throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.responseAcknowledgement();
-        } else {
-            mRadioProxy.responseAcknowledgement();
-        }
-    }
-
-    /**
-     * Call IRadioVoice#sendBurstDtmf
-     * @param serial Serial number of request
-     * @param dtmf DTMF string
-     * @param on DTMF ON length in milliseconds, or 0 to use default
-     * @param off DTMF OFF length in milliseconds, or 0 to use default
-     * @throws RemoteException
-     */
-    public void sendBurstDtmf(int serial, String dtmf, int on, int off) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.sendBurstDtmf(serial, dtmf, on, off);
-        } else {
-            mRadioProxy.sendBurstDtmf(serial, dtmf, on, off);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#sendCdmaFeatureCode
-     * @param serial Serial number of request
-     * @param featureCode String associated with FLASH command
-     * @throws RemoteException
-     */
-    public void sendCdmaFeatureCode(int serial, String featureCode) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.sendCdmaFeatureCode(serial, featureCode);
-        } else {
-            mRadioProxy.sendCDMAFeatureCode(serial, featureCode);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#sendDtmf
-     * @param serial Serial number of request
-     * @param s String with single char having one of 12 values: 0-0, *, #
-     * @throws RemoteException
-     */
-    public void sendDtmf(int serial, String s) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.sendDtmf(serial, s);
-        } else {
-            mRadioProxy.sendDtmf(serial, s);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#sendUssd
-     * @param serial Serial number of request
-     * @param ussd String containing the USSD request in UTF-8 format
-     * @throws RemoteException
-     */
-    public void sendUssd(int serial, String ussd) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.sendUssd(serial, ussd);
-        } else {
-            mRadioProxy.sendUssd(serial, ussd);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#separateConnection
-     * @param serial Serial number of request
-     * @param gsmIndex Connection index
-     * @throws RemoteException
-     */
-    public void separateConnection(int serial, int gsmIndex) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.separateConnection(serial, gsmIndex);
-        } else {
-            mRadioProxy.separateConnection(serial, gsmIndex);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#setCallForward
-     * @param serial Serial number of request
-     * @param action One of CF_ACTION_*
-     * @param cfReason One of CF_REASON_*
-     * @param serviceClass Sum of SERVICE_CLASSS_*
-     * @param number Number
-     * @param timeSeconds Time in seconds
-     * @throws RemoteException
-     */
-    public void setCallForward(int serial, int action, int cfReason, int serviceClass,
-            String number, int timeSeconds) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            android.hardware.radio.voice.CallForwardInfo cfInfo =
-                    new android.hardware.radio.voice.CallForwardInfo();
-            cfInfo.status = action;
-            cfInfo.reason = cfReason;
-            cfInfo.serviceClass = serviceClass;
-            cfInfo.toa = PhoneNumberUtils.toaFromString(number);
-            cfInfo.number = RILUtils.convertNullToEmptyString(number);
-            cfInfo.timeSeconds = timeSeconds;
-            mVoiceProxy.setCallForward(serial, cfInfo);
-        } else {
-            android.hardware.radio.V1_0.CallForwardInfo cfInfo =
-                    new android.hardware.radio.V1_0.CallForwardInfo();
-            cfInfo.status = action;
-            cfInfo.reason = cfReason;
-            cfInfo.serviceClass = serviceClass;
-            cfInfo.toa = PhoneNumberUtils.toaFromString(number);
-            cfInfo.number = RILUtils.convertNullToEmptyString(number);
-            cfInfo.timeSeconds = timeSeconds;
-            mRadioProxy.setCallForward(serial, cfInfo);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#setCallWaiting
-     * @param serial Serial number of request
-     * @param enable True to enable, false to disable
-     * @param serviceClass Sum of SERVICE_CLASS_*
-     * @throws RemoteException
-     */
-    public void setCallWaiting(int serial, boolean enable, int serviceClass)
-            throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.setCallWaiting(serial, enable, serviceClass);
-        } else {
-            mRadioProxy.setCallWaiting(serial, enable, serviceClass);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#setClir
-     * @param serial Serial number of request
-     * @param status One of CLIR_*
-     * @throws RemoteException
-     */
-    public void setClir(int serial, int status) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.setClir(serial, status);
-        } else {
-            mRadioProxy.setClir(serial, status);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#setMute
-     * @param serial Serial number of request
-     * @param enable True to enable, false to disable
-     * @throws RemoteException
-     */
-    public void setMute(int serial, boolean enable) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.setMute(serial, enable);
-        } else {
-            mRadioProxy.setMute(serial, enable);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#setPreferredVoicePrivacy
-     * @param serial Serial number of request
-     * @param enable True is enhanced, false is normal voice privacy
-     * @throws RemoteException
-     */
-    public void setPreferredVoicePrivacy(int serial, boolean enable) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.setPreferredVoicePrivacy(serial, enable);
-        } else {
-            mRadioProxy.setPreferredVoicePrivacy(serial, enable);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#setTtyMode
-     * @param serial Serial number of request
-     * @param mode One of TTY_MODE_*
-     * @throws RemoteException
-     */
-    public void setTtyMode(int serial, int mode) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.setTtyMode(serial, mode);
-        } else {
-            mRadioProxy.setTTYMode(serial, mode);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#setVoNrEnabled
-     * @param serial Serial number of request
-     * @param enable True to enable, false to disable
-     * @throws RemoteException
-     */
-    public void setVoNrEnabled(int serial, boolean enable) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.setVoNrEnabled(serial, enable);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#startDtmf
-     * @param serial Serial number of request
-     * @param s String having a single character with one of 12 values: 0-9, *, #
-     * @throws RemoteException
-     */
-    public void startDtmf(int serial, String s) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.startDtmf(serial, s);
-        } else {
-            mRadioProxy.startDtmf(serial, s);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#stopDtmf
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void stopDtmf(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.stopDtmf(serial);
-        } else {
-            mRadioProxy.stopDtmf(serial);
-        }
-    }
-
-    /**
-     * Call IRadioVoice#switchWaitingOrHoldingAndActive
-     * @param serial Serial number of request
-     * @throws RemoteException
-     */
-    public void switchWaitingOrHoldingAndActive(int serial) throws RemoteException {
-        if (isEmpty()) return;
-        if (isAidl()) {
-            mVoiceProxy.switchWaitingOrHoldingAndActive(serial);
-        } else {
-            mRadioProxy.switchWaitingOrHoldingAndActive(serial);
-        }
-    }
-}
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index 5bc9d17..d60e357 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -47,7 +47,6 @@
 import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.Process;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.Settings;
 import android.provider.Telephony;
@@ -80,6 +79,8 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
 import com.android.internal.telephony.cdma.sms.UserData;
+import com.android.internal.telephony.uicc.UiccCard;
+import com.android.internal.telephony.uicc.UiccController;
 import com.android.telephony.Rlog;
 
 import java.io.FileDescriptor;
@@ -116,7 +117,7 @@
     protected static final int EVENT_SEND_SMS_COMPLETE = 2;
 
     /** Retry sending a previously failed SMS message */
-    protected static final int EVENT_SEND_RETRY = 3;
+    private static final int EVENT_SEND_RETRY = 3;
 
     /** Confirmation required for sending a large number of messages. */
     private static final int EVENT_SEND_LIMIT_REACHED_CONFIRMATION = 4;
@@ -136,8 +137,8 @@
     /** Confirmation required for third-party apps sending to an SMS short code. */
     private static final int EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE = 9;
 
-    /** New status report received. */
-    protected static final int EVENT_NEW_SMS_STATUS_REPORT = 10;
+    /** Handle status report from {@code CdmaInboundSmsHandler}. */
+    protected static final int EVENT_HANDLE_STATUS_REPORT = 10;
 
     // other
     protected static final int EVENT_NEW_ICC_SMS = 14;
@@ -157,10 +158,9 @@
     protected final LocalLog mLocalLog = new LocalLog(16);
 
     /** Maximum number of times to retry sending a failed SMS. */
-    protected static final int MAX_SEND_RETRIES = 3;
+    private static final int MAX_SEND_RETRIES = 3;
     /** Delay before next send attempt on a failed SMS, in milliseconds. */
-    @VisibleForTesting
-    public static final int SEND_RETRY_DELAY = 2000;
+    private static final int SEND_RETRY_DELAY = 2000;
     /** Message sending queue limit */
     private static final int MO_MSG_QUEUE_LIMIT = 5;
     /** SMS anomaly uuid -- CarrierMessagingService did not respond */
@@ -262,11 +262,9 @@
     protected abstract String getFormat();
 
     /**
-     * Called when a status report is received. This should correspond to a previously successful
-     * SEND.
-     *
-     * @param o AsyncResult object including a byte array for 3GPP status report PDU or SmsMessage
-     *          object for 3GPP2 status report.
+     * Pass the Message object to subclass to handle. Currently used to pass CDMA status reports
+     * from {@link com.android.internal.telephony.cdma.CdmaInboundSmsHandler}.
+     * @param o the SmsMessage containing the status report
      */
     protected void handleStatusReport(Object o) {
         Rlog.d(TAG, "handleStatusReport() called with no subclass.");
@@ -350,7 +348,7 @@
             break;
         }
 
-        case EVENT_NEW_SMS_STATUS_REPORT:
+        case EVENT_HANDLE_STATUS_REPORT:
             handleStatusReport(msg.obj);
             break;
 
@@ -421,7 +419,7 @@
                 logWithLocalLog("handleMessage: No response from " + mCarrierPackageName
                         + " for " + mCarrierMessagingTimeout + " ms");
                 AnomalyReporter.reportAnomaly(sAnomalyNoResponseFromCarrierMessagingService,
-                        "No response from " + mCarrierPackageName, mPhone.getCarrierId());
+                        "No response from " + mCarrierPackageName);
                 onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK);
             } else {
                 logWithLocalLog("handleMessage: received unexpected message " + msg.what);
@@ -523,8 +521,7 @@
                             runnable -> runnable.run(),
                             mSenderCallback);
                 } catch (RuntimeException e) {
-                    Rlog.e(TAG, "DataSmsSender::onServiceReady: Exception sending the SMS: "
-                            + e
+                    Rlog.e(TAG, "DataSmsSender::onServiceReady: Exception sending the SMS: " + e
                             + " " + SmsController.formatCrossStackMessageId(mTracker.mMessageId));
                     onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK);
                 }
@@ -572,7 +569,7 @@
             if (mCallbackCalled) {
                 logWithLocalLog("onSendSmsComplete: unexpected call");
                 AnomalyReporter.reportAnomaly(sAnomalyUnexpectedCallback,
-                        "Unexpected onSendSmsComplete", mPhone.getCarrierId());
+                        "Unexpected onSendSmsComplete");
                 return;
             }
             mCallbackCalled = true;
@@ -628,9 +625,8 @@
                                                           null /* exception*/)));
                 break;
             case CarrierMessagingService.SEND_STATUS_ERROR:
-                Rlog.d(TAG, "processSendSmsResponse: Sending SMS by CarrierMessagingService"
-                        + " failed. "
-                        + SmsController.formatCrossStackMessageId(tracker.mMessageId));
+                Rlog.d(TAG, "processSendSmsResponse: Sending SMS by CarrierMessagingService failed."
+                        + " " + SmsController.formatCrossStackMessageId(tracker.mMessageId));
                 sendMessage(obtainMessage(EVENT_SEND_SMS_COMPLETE,
                         new AsyncResult(tracker, smsResponse,
                                 new CommandException(CommandException.Error.GENERIC_FAILURE))));
@@ -739,7 +735,7 @@
             if (mCallbackCalled) {
                 logWithLocalLog("onSendMultipartSmsComplete: unexpected call");
                 AnomalyReporter.reportAnomaly(sAnomalyUnexpectedCallback,
-                        "Unexpected onSendMultipartSmsComplete", mPhone.getCarrierId());
+                        "Unexpected onSendMultipartSmsComplete");
                 return;
             }
             mCallbackCalled = true;
@@ -903,8 +899,7 @@
                     false /* fallbackToCs */,
                     SmsManager.RESULT_ERROR_NONE,
                     tracker.mMessageId,
-                    tracker.isFromDefaultSmsApplication(mContext),
-                    tracker.getInterval());
+                    tracker.isFromDefaultSmsApplication(mContext));
         } else {
             if (DBG) {
                 Rlog.d(TAG, "SMS send failed "
@@ -913,7 +908,7 @@
 
             int ss = mPhone.getServiceState().getState();
             int error = rilErrorToSmsManagerResult(
-                    ((CommandException) (ar.exception)).getCommandError(), tracker);
+                    ((CommandException) (ar.exception)).getCommandError());
 
             if (tracker.mImsRetry > 0 && ss != ServiceState.STATE_IN_SERVICE) {
                 // This is retry after failure over IMS but voice is not available.
@@ -939,8 +934,7 @@
                         false /* fallbackToCs */,
                         getNotInServiceError(ss),
                         tracker.mMessageId,
-                        tracker.isFromDefaultSmsApplication(mContext),
-                        tracker.getInterval());
+                        tracker.isFromDefaultSmsApplication(mContext));
             } else if (error == SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY
                     && tracker.mRetryCount < MAX_SEND_RETRIES) {
                 // Retry after a delay if needed.
@@ -962,8 +956,7 @@
                         SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY,
                         errorCode,
                         tracker.mMessageId,
-                        tracker.isFromDefaultSmsApplication(mContext),
-                        tracker.getInterval());
+                        tracker.isFromDefaultSmsApplication(mContext));
             } else {
                 int errorCode = (smsResponse != null) ? smsResponse.mErrorCode : NO_ERROR_CODE;
                 tracker.onFailed(mContext, error, errorCode);
@@ -974,15 +967,13 @@
                         error,
                         errorCode,
                         tracker.mMessageId,
-                        tracker.isFromDefaultSmsApplication(mContext),
-                        tracker.getInterval());
+                        tracker.isFromDefaultSmsApplication(mContext));
             }
         }
     }
 
     @SmsManager.Result
-    private static int rilErrorToSmsManagerResult(CommandException.Error rilError,
-            SmsTracker tracker) {
+    private static int rilErrorToSmsManagerResult(CommandException.Error rilError) {
         switch (rilError) {
             case RADIO_NOT_AVAILABLE:
                 return SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE;
@@ -1033,9 +1024,7 @@
             case BLOCKED_DUE_TO_CALL:
                 return SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL;
             default:
-                Rlog.d(TAG, "rilErrorToSmsManagerResult: " + rilError + " "
-                        + SmsController.formatCrossStackMessageId(tracker.mMessageId));
-                return SmsManager.RESULT_RIL_GENERIC_ERROR;
+                return SmsManager.RESULT_ERROR_GENERIC_FAILURE;
         }
     }
 
@@ -1256,7 +1245,7 @@
                          String callingPkg, boolean persistMessage, int priority,
                          boolean expectMore, int validityPeriod, boolean isForVvm,
                          long messageId) {
-        Rlog.d(TAG, "sendText id: " + SmsController.formatCrossStackMessageId(messageId));
+        Rlog.d(TAG, "sendText id: " + messageId);
         SmsMessageBase.SubmitPduBase pdu = getSubmitPdu(
                 scAddr, destAddr, text, (deliveryIntent != null), null, priority, validityPeriod);
         if (pdu != null) {
@@ -1269,8 +1258,8 @@
                 sendSubmitPdu(tracker);
             }
         } else {
-            Rlog.e(TAG, "SmsDispatcher.sendText(): getSubmitPdu() returned null "
-                    + SmsController.formatCrossStackMessageId(messageId));
+            Rlog.e(TAG, "SmsDispatcher.sendText(): getSubmitPdu() returned null" + " id: "
+                    + messageId);
             triggerSentIntentForFailure(sentIntent);
         }
     }
@@ -1510,14 +1499,13 @@
         String carrierPackage = getCarrierAppPackageName();
         if (carrierPackage != null) {
             Rlog.d(TAG, "Found carrier package " + carrierPackage
-                    + " "
-                    + SmsController.formatCrossStackMessageId(getMultiTrackermessageId(trackers)));
+                    + " id: " + getMultiTrackermessageId(trackers));
             MultipartSmsSender smsSender = new MultipartSmsSender(parts, trackers);
             smsSender.sendSmsByCarrierApp(carrierPackage,
                     new MultipartSmsSenderCallback(smsSender));
         } else {
-            Rlog.v(TAG, "No carrier package. "
-                    + SmsController.formatCrossStackMessageId(getMultiTrackermessageId(trackers)));
+            Rlog.v(TAG, "No carrier package."
+                    + " id: " + getMultiTrackermessageId(trackers));
             sendSubmitPdu(trackers);
         }
     }
@@ -1570,7 +1558,7 @@
                         messageId);
             } else {
                 Rlog.e(TAG, "CdmaSMSDispatcher.getNewSubmitPduTracker(): getSubmitPdu() returned "
-                        + "null " + SmsController.formatCrossStackMessageId(messageId));
+                        + "null" + " id: " + messageId);
                 return null;
             }
         } else {
@@ -1589,7 +1577,7 @@
                         messageId);
             } else {
                 Rlog.e(TAG, "GsmSMSDispatcher.getNewSubmitPduTracker(): getSubmitPdu() returned "
-                        + "null " + SmsController.formatCrossStackMessageId(messageId));
+                        + "null" + " id: " + messageId);
                 return null;
             }
         }
@@ -1700,9 +1688,8 @@
                                     trackers[0].getAppPackageName(),
                                     PackageManager.GET_SIGNATURES);
                 } catch (PackageManager.NameNotFoundException e) {
-                    Rlog.e(TAG, "Can't get calling app package info: refusing to send SMS "
-                            + SmsController.formatCrossStackMessageId(
-                                    getMultiTrackermessageId(trackers)));
+                    Rlog.e(TAG, "Can't get calling app package info: refusing to send SMS"
+                            + " id: " + getMultiTrackermessageId(trackers));
                     error = SmsManager.RESULT_ERROR_GENERIC_FAILURE;
                 }
             }
@@ -1753,9 +1740,8 @@
                 String simCountryIso =
                         mTelephonyManager.getSimCountryIsoForPhone(mPhone.getPhoneId());
                 if (simCountryIso == null || simCountryIso.length() != 2) {
-                    Rlog.e(TAG, "Can't get SIM country Iso: trying network country Iso "
-                            + SmsController.formatCrossStackMessageId(
-                                    getMultiTrackermessageId(trackers)));
+                    Rlog.e(TAG, "Can't get SIM country Iso: trying network country Iso"
+                            + " id: " + getMultiTrackermessageId(trackers));
                     simCountryIso =
                             mTelephonyManager.getNetworkCountryIso(mPhone.getPhoneId());
                 }
@@ -1769,9 +1755,8 @@
                 String networkCountryIso =
                         mTelephonyManager.getNetworkCountryIso(mPhone.getPhoneId());
                 if (networkCountryIso == null || networkCountryIso.length() != 2) {
-                    Rlog.e(TAG, "Can't get Network country Iso: trying SIM country Iso "
-                            + SmsController.formatCrossStackMessageId(
-                                    getMultiTrackermessageId(trackers)));
+                    Rlog.e(TAG, "Can't get Network country Iso: trying SIM country Iso"
+                            + " id: " + getMultiTrackermessageId(trackers));
                     networkCountryIso =
                             mTelephonyManager.getSimCountryIsoForPhone(mPhone.getPhoneId());
                 }
@@ -1793,9 +1778,8 @@
 
             // Do not allow any premium sms during SuW
             if (Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
-                Rlog.e(TAG, "Can't send premium sms during Setup Wizard "
-                        + SmsController.formatCrossStackMessageId(
-                                getMultiTrackermessageId(trackers)));
+                Rlog.e(TAG, "Can't send premium sms during Setup Wizard"
+                        + " id: " + getMultiTrackermessageId(trackers));
                 return false;
             }
 
@@ -1811,15 +1795,13 @@
 
             switch (premiumSmsPermission) {
                 case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW:
-                    Rlog.d(TAG, "User approved this app to send to premium SMS "
-                            + SmsController.formatCrossStackMessageId(
-                                    getMultiTrackermessageId(trackers)));
+                    Rlog.d(TAG, "User approved this app to send to premium SMS"
+                            + " id: " + getMultiTrackermessageId(trackers));
                     return true;
 
                 case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_NEVER_ALLOW:
-                    Rlog.w(TAG, "User denied this app from sending to premium SMS "
-                            + SmsController.formatCrossStackMessageId(
-                                    getMultiTrackermessageId(trackers)));
+                    Rlog.w(TAG, "User denied this app from sending to premium SMS"
+                            + " id: " + getMultiTrackermessageId(trackers));
                     Message msg = obtainMessage(EVENT_SENDING_NOT_ALLOWED, trackers);
                     sendMessage(msg);
                     return false;   // reject this message
@@ -1850,8 +1832,8 @@
         // one SmsTracker array is treated as one message for checking queue limit.
         if (mPendingTrackerCount >= MO_MSG_QUEUE_LIMIT) {
             // Deny sending message when the queue limit is reached.
-            Rlog.e(TAG, "Denied because queue limit reached "
-                    + SmsController.formatCrossStackMessageId(getMultiTrackermessageId(trackers)));
+            Rlog.e(TAG, "Denied because queue limit reached"
+                    + " id: " + getMultiTrackermessageId(trackers));
             handleSmsTrackersFailure(
                     trackers, SmsManager.RESULT_ERROR_LIMIT_EXCEEDED, NO_ERROR_CODE);
             return true;
@@ -1993,8 +1975,8 @@
         if (mSmsDispatchersController != null) {
             mSmsDispatchersController.sendRetrySms(tracker);
         } else {
-            Rlog.e(TAG, mSmsDispatchersController + " is null. Retry failed "
-                    + SmsController.formatCrossStackMessageId(tracker.mMessageId));
+            Rlog.e(TAG, mSmsDispatchersController + " is null. Retry failed"
+                    + " " + SmsController.formatCrossStackMessageId(tracker.mMessageId));
         }
     }
 
@@ -2012,8 +1994,7 @@
                     false /* fallbackToCs */,
                     error,
                     trackers[0].mMessageId,
-                    trackers[0].isFromDefaultSmsApplication(mContext),
-                    trackers[0].getInterval());
+                    trackers[0].isFromDefaultSmsApplication(mContext));
         }
     }
 
@@ -2053,7 +2034,7 @@
         public final SmsHeader mSmsHeader;
 
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-        private long mTimestamp = SystemClock.elapsedRealtime();
+        private long mTimestamp = System.currentTimeMillis();
         @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
         public Uri mMessageUri; // Uri of persisted message if we wrote one
 
@@ -2081,7 +2062,6 @@
 
         private Boolean mIsFromDefaultSmsApplication;
 
-        private int mCarrierId;
         // SMS anomaly uuid -- unexpected error from RIL
         private final UUID mAnomalyUnexpectedErrorFromRilUUID =
                 UUID.fromString("43043600-ea7a-44d2-9ae6-a58567ac7886");
@@ -2091,7 +2071,7 @@
                 AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri,
                 SmsHeader smsHeader, boolean expectMore, String fullMessageText, int subId,
                 boolean isText, boolean persistMessage, int userId, int priority,
-                int validityPeriod, boolean isForVvm, long messageId, int carrierId) {
+                int validityPeriod, boolean isForVvm, long messageId) {
             mData = data;
             mSentIntent = sentIntent;
             mDeliveryIntent = deliveryIntent;
@@ -2116,7 +2096,6 @@
             mValidityPeriod = validityPeriod;
             mIsForVvm = isForVvm;
             mMessageId = messageId;
-            mCarrierId = carrierId;
         }
 
         public HashMap<String, Object> getData() {
@@ -2180,15 +2159,6 @@
         }
 
         /**
-         * Returns the interval in milliseconds between sending the message out and current time.
-         * Called after receiving success/failure response to calculate the time
-         * to complete the SMS send to the network.
-         */
-        protected long getInterval() {
-            return SystemClock.elapsedRealtime() - mTimestamp;
-        }
-
-        /**
          * Persist a sent SMS if required:
          * 1. It is a text message
          * 2. SmsApplication tells us to persist: sent from apps that are not default-SMS app or
@@ -2300,12 +2270,10 @@
                         // with the one they passed to SmsManager.
                         fillIn.putExtra(MESSAGE_ID_EXTRA, mMessageId);
                     }
-                    fillIn.putExtra("format", mFormat);
-                    fillIn.putExtra("ims", mUsesImsServiceForIms);
                     mSentIntent.send(context, error, fillIn);
                 } catch (CanceledException ex) {
-                    Rlog.e(TAG, "Failed to send result "
-                            + SmsController.formatCrossStackMessageId(mMessageId));
+                    Rlog.e(TAG, "Failed to send result"
+                            + " " + SmsController.formatCrossStackMessageId(mMessageId));
                 }
             }
             reportAnomaly(error, errorCode);
@@ -2325,8 +2293,7 @@
                 default:
                     String message = "SMS failed";
                     Rlog.d(TAG, message + " with error " + error + ", errorCode " + errorCode);
-                    AnomalyReporter.reportAnomaly(
-                            generateUUID(error, errorCode), message, mCarrierId);
+                    AnomalyReporter.reportAnomaly(generateUUID(error, errorCode), message);
             }
         }
 
@@ -2369,8 +2336,6 @@
                         // Is multipart and last part
                         fillIn.putExtra(SEND_NEXT_MSG_EXTRA, true);
                     }
-                    fillIn.putExtra("format", mFormat);
-                    fillIn.putExtra("ims", mUsesImsServiceForIms);
                     mSentIntent.send(context, Activity.RESULT_OK, fillIn);
                 } catch (CanceledException ex) {
                     Rlog.e(TAG, "Failed to send result");
@@ -2401,7 +2366,7 @@
         return new SmsTracker(data, sentIntent, deliveryIntent, appInfo, destAddr, format,
                 unsentPartCount, anyPartFailed, messageUri, smsHeader, expectMore,
                 fullMessageText, getSubId(), isText, persistMessage, userId, priority,
-                validityPeriod, isForVvm, messageId, mPhone.getCarrierId());
+                validityPeriod, isForVvm, messageId);
     }
 
     protected SmsTracker getSmsTracker(String callingPackage, HashMap<String, Object> data,
@@ -2573,13 +2538,13 @@
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     protected String getCarrierAppPackageName() {
-        CarrierPrivilegesTracker cpt = mPhone.getCarrierPrivilegesTracker();
-        if (cpt == null) {
+        UiccCard card = UiccController.getInstance().getUiccCard(mPhone.getPhoneId());
+        if (card == null) {
             return null;
         }
-        List<String> carrierPackages =
-                cpt.getCarrierPackageNamesForIntent(
-                        new Intent(CarrierMessagingService.SERVICE_INTERFACE));
+
+        List<String> carrierPackages = card.getCarrierPackageNamesForIntent(
+            mContext.getPackageManager(), new Intent(CarrierMessagingService.SERVICE_INTERFACE));
         if (carrierPackages != null && carrierPackages.size() == 1) {
             return carrierPackages.get(0);
         }
diff --git a/src/java/com/android/internal/telephony/ServiceStateTracker.java b/src/java/com/android/internal/telephony/ServiceStateTracker.java
index 751d59a..e0b2e25 100755
--- a/src/java/com/android/internal/telephony/ServiceStateTracker.java
+++ b/src/java/com/android/internal/telephony/ServiceStateTracker.java
@@ -42,13 +42,16 @@
 import android.os.BaseBundle;
 import android.os.Build;
 import android.os.Handler;
+import android.os.IBinder;
 import android.os.Message;
 import android.os.Parcel;
 import android.os.PersistableBundle;
 import android.os.Registrant;
 import android.os.RegistrantList;
+import android.os.RemoteException;
 import android.os.SystemClock;
 import android.os.SystemProperties;
+import android.os.TimestampedValue;
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.preference.PreferenceManager;
@@ -66,12 +69,17 @@
 import android.telephony.CellIdentityTdscdma;
 import android.telephony.CellIdentityWcdma;
 import android.telephony.CellInfo;
+import android.telephony.CellSignalStrengthLte;
+import android.telephony.CellSignalStrengthNr;
 import android.telephony.DataSpecificRegistrationInfo;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhysicalChannelConfig;
 import android.telephony.RadioAccessFamily;
 import android.telephony.ServiceState;
 import android.telephony.ServiceState.RilRadioTechnology;
+import android.telephony.SignalStrength;
+import android.telephony.SignalStrengthUpdateRequest;
+import android.telephony.SignalThresholdInfo;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
@@ -92,10 +100,9 @@
 import com.android.internal.telephony.cdma.EriManager;
 import com.android.internal.telephony.cdnr.CarrierDisplayNameData;
 import com.android.internal.telephony.cdnr.CarrierDisplayNameResolver;
-import com.android.internal.telephony.data.AccessNetworksManager;
-import com.android.internal.telephony.data.DataNetwork;
-import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
 import com.android.internal.telephony.dataconnection.DataConnection;
+import com.android.internal.telephony.dataconnection.DcTracker;
+import com.android.internal.telephony.dataconnection.TransportManager;
 import com.android.internal.telephony.metrics.ServiceStateStats;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppState;
@@ -106,7 +113,6 @@
 import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccCardApplication;
 import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UiccProfile;
 import com.android.internal.telephony.util.ArrayUtils;
 import com.android.internal.telephony.util.NotificationChannelController;
@@ -118,17 +124,20 @@
 import java.io.PrintWriter;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.Comparator;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Objects;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
 import java.util.stream.Collectors;
 
 /**
@@ -141,6 +150,9 @@
 
     private static final String PROP_FORCE_ROAMING = "telephony.test.forceRoaming";
 
+    private static final long SIGNAL_STRENGTH_REFRESH_THRESHOLD_IN_MS =
+            TimeUnit.SECONDS.toMillis(10);
+
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private CommandsInterface mCi;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -182,6 +194,10 @@
 
     private final Set<Integer> mRadioPowerOffReasons = new HashSet();
 
+    @UnsupportedAppUsage
+    private SignalStrength mSignalStrength;
+    private long mSignalStrengthUpdatedTime;
+
     // TODO - this should not be public, right now used externally GsmConnetion.
     public RestrictedState mRestrictedState;
 
@@ -195,6 +211,13 @@
     @UnsupportedAppUsage
     private boolean mDesiredPowerState;
 
+    /**
+     * By default, strength polling is enabled.  However, if we're
+     * getting unsolicited signal strength updates from the radio, set
+     * value to true and don't bother polling any more.
+     */
+    private boolean mDontPollSignalStrength = false;
+
     @UnsupportedAppUsage
     private RegistrantList mVoiceRoamingOnRegistrants = new RegistrantList();
     @UnsupportedAppUsage
@@ -210,14 +233,12 @@
     @UnsupportedAppUsage
     private RegistrantList mNetworkAttachedRegistrants = new RegistrantList();
     private RegistrantList mNetworkDetachedRegistrants = new RegistrantList();
-    private RegistrantList mServiceStateChangedRegistrants = new RegistrantList();
     private RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
     private RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList();
     private RegistrantList mImsCapabilityChangedRegistrants = new RegistrantList();
     private RegistrantList mNrStateChangedRegistrants = new RegistrantList();
     private RegistrantList mNrFrequencyChangedRegistrants = new RegistrantList();
     private RegistrantList mCssIndicatorChangedRegistrants = new RegistrantList();
-    private final RegistrantList mBandwidthChangedRegistrants = new RegistrantList();
     private final RegistrantList mAirplaneModeChangedRegistrants = new RegistrantList();
     private final RegistrantList mAreaCodeChangedRegistrants = new RegistrantList();
 
@@ -225,23 +246,29 @@
     private boolean mPendingRadioPowerOffAfterDataOff = false;
     private int mPendingRadioPowerOffAfterDataOffTag = 0;
 
-    /** Waiting period before recheck gprs and voice registration. */
-    public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
+    /** Signal strength poll rate. */
+    private static final int POLL_PERIOD_MILLIS = 20 * 1000;
 
     /**
-     * The timer value to wait for all data networks to be torn down.
+     * The time we wait for IMS to deregister before executing a pending radio power off request.
      */
-    private static final long POWER_OFF_ALL_DATA_NETWORKS_DISCONNECTED_TIMEOUT =
-            TimeUnit.SECONDS.toMillis(10);
+    @VisibleForTesting
+    public static final int DELAY_RADIO_OFF_FOR_IMS_DEREG_TIMEOUT = 3 * 1000;
+
+    /** Waiting period before recheck gprs and voice registration. */
+    public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;
 
     /** GSM events */
     protected static final int EVENT_RADIO_STATE_CHANGED                    = 1;
     protected static final int EVENT_NETWORK_STATE_CHANGED                  = 2;
+    protected static final int EVENT_GET_SIGNAL_STRENGTH                    = 3;
     protected static final int EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION    = 4;
     protected static final int EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION    = 5;
     protected static final int EVENT_POLL_STATE_PS_IWLAN_REGISTRATION       = 6;
     protected static final int EVENT_POLL_STATE_OPERATOR                    = 7;
+    protected static final int EVENT_POLL_SIGNAL_STRENGTH                   = 10;
     protected static final int EVENT_NITZ_TIME                              = 11;
+    protected static final int EVENT_SIGNAL_STRENGTH_UPDATE                 = 12;
     protected static final int EVENT_POLL_STATE_NETWORK_SELECTION_MODE      = 14;
     protected static final int EVENT_GET_LOC_DONE                           = 15;
     protected static final int EVENT_SIM_RECORDS_LOADED                     = 16;
@@ -267,8 +294,7 @@
     public    static final int EVENT_ICC_CHANGED                       = 42;
     protected static final int EVENT_GET_CELL_INFO_LIST                = 43;
     protected static final int EVENT_UNSOL_CELL_INFO_LIST              = 44;
-    // Only sent if the IMS state is moving from true -> false and power off delay for IMS
-    // registration feature is enabled.
+    // Only sent if the IMS state is moving from true -> false
     protected static final int EVENT_CHANGE_IMS_STATE                  = 45;
     protected static final int EVENT_IMS_STATE_CHANGED                 = 46;
     protected static final int EVENT_IMS_STATE_DONE                    = 47;
@@ -282,13 +308,11 @@
     protected static final int EVENT_CELL_LOCATION_RESPONSE            = 56;
     protected static final int EVENT_CARRIER_CONFIG_CHANGED            = 57;
     private static final int EVENT_POLL_STATE_REQUEST                  = 58;
+    private static final int EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST  = 59;
+    private static final int EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST = 60;
+    private static final int EVENT_ON_DEVICE_IDLE_STATE_CHANGED         = 61;
     // Timeout event used when delaying radio power off to wait for IMS deregistration to happen.
-    private static final int EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT   = 62;
-    protected static final int EVENT_RESET_LAST_KNOWN_CELL_IDENTITY    = 63;
-    private static final int EVENT_REGISTER_DATA_NETWORK_EXISTING_CHANGED = 64;
-    // Telecom has un/registered a PhoneAccount that provides OTT voice calling capability, e.g.
-    // wi-fi calling.
-    protected static final int EVENT_TELECOM_VOICE_SERVICE_STATE_OVERRIDE_CHANGED = 65;
+    private static final int EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT    = 62;
 
     /**
      * The current service state.
@@ -360,11 +384,11 @@
 
     private final LocaleTracker mLocaleTracker;
 
-    private final LocalLog mRoamingLog = new LocalLog(8);
-    private final LocalLog mAttachLog = new LocalLog(8);
-    private final LocalLog mPhoneTypeLog = new LocalLog(8);
-    private final LocalLog mRatLog = new LocalLog(16);
-    private final LocalLog mRadioPowerLog = new LocalLog(16);
+    private final LocalLog mRoamingLog = new LocalLog(10);
+    private final LocalLog mAttachLog = new LocalLog(10);
+    private final LocalLog mPhoneTypeLog = new LocalLog(10);
+    private final LocalLog mRatLog = new LocalLog(20);
+    private final LocalLog mRadioPowerLog = new LocalLog(20);
     private final LocalLog mCdnrLogs = new LocalLog(64);
 
     private Pattern mOperatorNameStringPattern;
@@ -416,7 +440,7 @@
                 // just went from invalid to valid subId, so notify with current service
                 // state in case our service state was never broadcasted (we don't notify
                 // service states when the subId is invalid)
-                mPhone.notifyServiceStateChanged(mPhone.getServiceState());
+                mPhone.notifyServiceStateChanged(mSS);
             }
 
             boolean restoreSelection = !context.getResources().getBoolean(
@@ -470,7 +494,6 @@
     protected final GsmCdmaPhone mPhone;
 
     private CellIdentity mCellIdentity;
-    @Nullable private CellIdentity mLastKnownCellIdentity;
     private static final int MS_PER_HOUR = 60 * 60 * 1000;
     private final NitzStateMachine mNitzState;
 
@@ -559,17 +582,19 @@
     private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (action.equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
+            if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
                 int phoneId = intent.getExtras().getInt(CarrierConfigManager.EXTRA_SLOT_INDEX);
                 // Ignore the carrier config changed if the phoneId is not matched.
                 if (phoneId == mPhone.getPhoneId()) {
                     sendEmptyMessage(EVENT_CARRIER_CONFIG_CHANGED);
                 }
-            } else if (action.equals(Intent.ACTION_LOCALE_CHANGED)) {
+                return;
+            }
+
+            if (intent.getAction().equals(Intent.ACTION_LOCALE_CHANGED)) {
                 // Update emergency string or operator name, polling service state.
                 pollState();
-            } else if (action.equals(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED)) {
+            } else if (intent.getAction().equals(TelephonyManager.ACTION_NETWORK_COUNTRY_CHANGED)) {
                 String lastKnownNetworkCountry = intent.getStringExtra(
                         TelephonyManager.EXTRA_LAST_KNOWN_NETWORK_COUNTRY);
                 if (!mLastKnownNetworkCountry.equals(lastKnownNetworkCountry)) {
@@ -613,19 +638,30 @@
     private String mRegistrationDeniedReason;
     private String mCurrentCarrier = null;
 
-    private final AccessNetworksManager mAccessNetworksManager;
+    private final TransportManager mTransportManager;
     private final SparseArray<NetworkRegistrationManager> mRegStateManagers = new SparseArray<>();
 
+    /* list of LTE EARFCNs (E-UTRA Absolute Radio Frequency Channel Number,
+     * Reference: 3GPP TS 36.104 5.4.3)
+     * inclusive ranges for which the lte rsrp boost is applied */
+    private ArrayList<Pair<Integer, Integer>> mEarfcnPairListForRsrpBoost = null;
+    private int mLteRsrpBoost = 0; // offset which is reduced from the rsrp threshold
+                                   // while calculating signal strength level.
+
+    /* Ranges of NR ARFCNs (5G Absolute Radio Frequency Channel Number,
+     * Reference: 3GPP TS 38.104)
+     * inclusive ranges for which the corresponding nr rsrp boost is applied */
+    private ArrayList<Pair<Integer, Integer>> mNrarfcnRangeListForRsrpBoost = null;
+    private int[] mNrRsrpBoost;
+
+    private final Object mRsrpBoostLock = new Object();
+    private static final int INVALID_ARFCN = -1;
+
+    private final List<SignalRequestRecord> mSignalRequestRecords = new ArrayList<>();
+
     /* Last known TAC/LAC */
     private int mLastKnownAreaCode = CellInfo.UNAVAILABLE;
 
-    /**
-     * Indicating if there is any data network existing. This is used in airplane mode turning on
-     * scenario, where service state tracker should wait all data disconnected before powering
-     * down the modem.
-     */
-    private boolean mAnyDataExisting = false;
-
     public ServiceStateTracker(GsmCdmaPhone phone, CommandsInterface ci) {
         mNitzState = TelephonyComponentFactory.getInstance()
                 .inject(NitzStateMachine.class.getName())
@@ -637,13 +673,8 @@
 
         mCdnr = new CarrierDisplayNameResolver(mPhone);
 
-        // Create EriManager only if phone supports CDMA
-        if (UiccController.isCdmaSupported(mPhone.getContext())) {
-            mEriManager = TelephonyComponentFactory.getInstance().inject(EriManager.class.getName())
-                    .makeEriManager(mPhone, EriManager.ERI_FROM_XML);
-        } else {
-            mEriManager = null;
-        }
+        mEriManager = TelephonyComponentFactory.getInstance().inject(EriManager.class.getName())
+                .makeEriManager(mPhone, EriManager.ERI_FROM_XML);
 
         mRatRatcheter = new RatRatcheter(mPhone);
         mVoiceCapable = ((TelephonyManager) mPhone.getContext()
@@ -651,7 +682,11 @@
                 .isVoiceCapable();
         mUiccController = UiccController.getInstance();
 
+        mOutOfServiceSS = new ServiceState();
+        mOutOfServiceSS.setStateOutOfService();
+
         mUiccController.registerForIccChanged(this, EVENT_ICC_CHANGED, null);
+        mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
         mCi.registerForCellInfoList(this, EVENT_UNSOL_CELL_INFO_LIST, null);
         mCi.registerForPhysicalChannelConfiguration(this, EVENT_PHYSICAL_CHANNEL_CONFIG, null);
 
@@ -661,11 +696,9 @@
                 new android.os.HandlerExecutor(this), mOnSubscriptionsChangedListener);
         mRestrictedState = new RestrictedState();
 
-        mAccessNetworksManager = mPhone.getAccessNetworksManager();
-        mOutOfServiceSS = new ServiceState();
-        mOutOfServiceSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), false);
+        mTransportManager = mPhone.getTransportManager();
 
-        for (int transportType : mAccessNetworksManager.getAvailableTransports()) {
+        for (int transportType : mTransportManager.getAvailableTransports()) {
             mRegStateManagers.append(transportType, new NetworkRegistrationManager(
                     transportType, phone));
             mRegStateManagers.get(transportType).registerForNetworkRegistrationInfoChanged(
@@ -692,6 +725,7 @@
                 enableCellularOnBoot);
 
 
+        setSignalStrengthDefaultValues();
         mPhone.getCarrierActionAgent().registerForCarrierAction(CARRIER_ACTION_SET_RADIO_ENABLED,
                 this, EVENT_RADIO_POWER_FROM_CARRIER, null, false);
 
@@ -720,10 +754,6 @@
                 CarrierServiceStateTracker.CARRIER_EVENT_DATA_DEREGISTRATION, null);
         registerForImsCapabilityChanged(mCSST,
                 CarrierServiceStateTracker.CARRIER_EVENT_IMS_CAPABILITIES_CHANGED, null);
-
-        if (mPhone.isUsingNewDataStack()) {
-            sendEmptyMessage(EVENT_REGISTER_DATA_NETWORK_EXISTING_CHANGED);
-        }
     }
 
     @VisibleForTesting
@@ -747,7 +777,7 @@
         }
 
         // If we are previously in service, we need to notify that we are out of service now.
-        for (int transport : mAccessNetworksManager.getAvailableTransports()) {
+        for (int transport : mTransportManager.getAvailableTransports()) {
             if (mSS != null) {
                 NetworkRegistrationInfo nrs = mSS.getNetworkRegistrationInfo(
                         NetworkRegistrationInfo.DOMAIN_PS, transport);
@@ -759,11 +789,12 @@
         }
 
         mSS = new ServiceState();
-        mSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), false);
+        mSS.setStateOutOfService();
         mNewSS = new ServiceState();
-        mNewSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), false);
+        mNewSS.setStateOutOfService();
         mLastCellInfoReqTime = 0;
         mLastCellInfoList = null;
+        mSignalStrength = new SignalStrength();
         mStartedGprsRegCheck = false;
         mReportedGprsNoReg = false;
         mMdn = null;
@@ -773,8 +804,7 @@
         mLastNitzData = null;
         mNitzState.handleNetworkUnavailable();
         mCellIdentity = null;
-        mPhone.getSignalStrengthController().setSignalStrengthDefaultValues();
-        mLastKnownCellIdentity = null;
+        mSignalStrengthUpdatedTime = System.currentTimeMillis();
 
         //cancel any pending pollstate request on voice tech switching
         cancelPollState();
@@ -813,14 +843,14 @@
         // switching between GSM and CDMA phone), because the unsolicited signal strength
         // information might come late or even never come. This will get the accurate signal
         // strength information displayed on the UI.
-        mPhone.getSignalStrengthController().getSignalStrengthFromCi();
+        mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
         sendMessage(obtainMessage(EVENT_PHONE_TYPE_SWITCHED));
 
         logPhoneTypeChange();
 
         // Tell everybody that the registration state and RAT have changed.
         notifyVoiceRegStateRilRadioTechnologyChanged();
-        for (int transport : mAccessNetworksManager.getAvailableTransports()) {
+        for (int transport : mTransportManager.getAvailableTransports()) {
             notifyDataRegStateRilRadioTechnologyChanged(transport);
         }
     }
@@ -833,18 +863,8 @@
         setPowerStateToDesired();
     }
 
-    /**
-     * @return the timeout value in milliseconds that the framework will delay a pending radio power
-     * off command while waiting for an IMS deregistered indication.
-     */
-    @VisibleForTesting
-    public int getRadioPowerOffDelayTimeoutForImsRegistration() {
-        return mPhone.getContext().getResources().getInteger(
-                R.integer.config_delay_for_ims_dereg_millis);
-    }
-
     public void dispose() {
-        mPhone.getSignalStrengthController().dispose();
+        mCi.unSetOnSignalStrengthUpdate(this);
         mUiccController.unregisterForIccChanged(this);
         mCi.unregisterForCellInfoList(this);
         mCi.unregisterForPhysicalChannelConfiguration(this);
@@ -870,6 +890,23 @@
         return mLastPhysicalChannelConfigList;
     }
 
+    private SignalStrength mLastSignalStrength = null;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    protected boolean notifySignalStrength() {
+        boolean notified = false;
+        if (!mSignalStrength.equals(mLastSignalStrength)) {
+            try {
+                mPhone.notifySignalStrength();
+                notified = true;
+                mLastSignalStrength = mSignalStrength;
+            } catch (NullPointerException ex) {
+                loge("updateSignalStrength() Phone already destroyed: " + ex
+                        + "SignalStrength not notified");
+            }
+        }
+        return notified;
+    }
+
     /**
      * Notify all mVoiceRegStateOrRatChangedRegistrants using an
      * AsyncResult in msg.obj where AsyncResult#result contains the
@@ -1189,12 +1226,6 @@
         switch (msg.what) {
             case EVENT_SET_RADIO_POWER_OFF:
                 synchronized(this) {
-                    if (mPhone.isUsingNewDataStack()) {
-                        mPendingRadioPowerOffAfterDataOff = false;
-                        log("Wait for all data networks torn down timed out. Power off now.");
-                        hangupAndPowerOff();
-                        return;
-                    }
                     if (mPendingRadioPowerOffAfterDataOff &&
                             (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) {
                         if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
@@ -1318,6 +1349,8 @@
                 mPrevSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
                 mIsSimReady = true;
                 pollStateInternal(false);
+                // Signal strength polling stops when radio is off
+                queueNextSignalStrengthPoll();
                 break;
 
             case EVENT_RADIO_STATE_CHANGED:
@@ -1325,6 +1358,9 @@
                 if(!mPhone.isPhoneTypeGsm() &&
                         mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON) {
                     handleCdmaSubscriptionSource(mCdmaSSM.getCdmaSubscriptionSource());
+
+                    // Signal strength polling stops when radio is off.
+                    queueNextSignalStrengthPoll();
                 }
                 // This will do nothing in the 'radio not available' case
                 setPowerStateToDesired();
@@ -1336,6 +1372,20 @@
                 pollStateInternal(true);
                 break;
 
+            case EVENT_GET_SIGNAL_STRENGTH:
+                // This callback is called when signal strength is polled
+                // all by itself
+
+                if (!(mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON)) {
+                    // Polling will continue when radio turns back on
+                    return;
+                }
+                ar = (AsyncResult) msg.obj;
+                onSignalStrengthResult(ar);
+                queueNextSignalStrengthPoll();
+
+                break;
+
             case EVENT_GET_LOC_DONE:
                 ar = (AsyncResult) msg.obj;
                 if (ar.exception == null) {
@@ -1376,20 +1426,32 @@
                 }
                 break;
 
-            case EVENT_NITZ_TIME: {
+            case EVENT_POLL_SIGNAL_STRENGTH:
+                // Just poll signal strength...not part of pollState()
+
+                mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
+                break;
+
+            case EVENT_NITZ_TIME:
                 ar = (AsyncResult) msg.obj;
 
-                Object[] nitzArgs = (Object[])ar.result;
-                String nitzString = (String)nitzArgs[0];
-                long nitzReceiveTimeMs = ((Long)nitzArgs[1]).longValue();
-                long ageMs = 0;
-                if (nitzArgs.length >= 3) {
-                    ageMs = ((Long)nitzArgs[2]).longValue();
-                }
+                String nitzString = (String)((Object[])ar.result)[0];
+                long nitzReceiveTime = ((Long)((Object[])ar.result)[1]).longValue();
 
-                setTimeFromNITZString(nitzString, nitzReceiveTimeMs, ageMs);
+                setTimeFromNITZString(nitzString, nitzReceiveTime);
                 break;
-            }
+
+            case EVENT_SIGNAL_STRENGTH_UPDATE:
+                // This is a notification from CommandsInterface.setOnSignalStrengthUpdate
+
+                ar = (AsyncResult) msg.obj;
+
+                // The radio is telling us about signal strength changes
+                // we don't have to ask it
+                mDontPollSignalStrength = true;
+
+                onSignalStrengthResult(ar);
+                break;
 
             case EVENT_SIM_RECORDS_LOADED:
                 log("EVENT_SIM_RECORDS_LOADED: what=" + msg.what);
@@ -1471,34 +1533,7 @@
                 }
                 break;
 
-            case EVENT_REGISTER_DATA_NETWORK_EXISTING_CHANGED: {
-                mPhone.getDataNetworkController().registerDataNetworkControllerCallback(
-                        new DataNetworkControllerCallback(this::post) {
-                        @Override
-                        public void onAnyDataNetworkExistingChanged(boolean anyDataExisting) {
-                            if (mAnyDataExisting != anyDataExisting) {
-                                mAnyDataExisting = anyDataExisting;
-                                log("onAnyDataNetworkExistingChanged: anyDataExisting="
-                                        + anyDataExisting);
-                                if (!mAnyDataExisting) {
-                                    sendEmptyMessage(EVENT_ALL_DATA_DISCONNECTED);
-                                }
-                            }
-                        }
-                        });
-                break;
-            }
             case EVENT_ALL_DATA_DISCONNECTED:
-                if (mPhone.isUsingNewDataStack()) {
-                    log("EVENT_ALL_DATA_DISCONNECTED");
-                    if (mPendingRadioPowerOffAfterDataOff) {
-                        mPendingRadioPowerOffAfterDataOff = false;
-                        removeMessages(EVENT_SET_RADIO_POWER_OFF);
-                        if (DBG) log("EVENT_ALL_DATA_DISCONNECTED, turn radio off now.");
-                        hangupAndPowerOff();
-                    }
-                    return;
-                }
                 int dds = SubscriptionManager.getDefaultDataSubscriptionId();
                 ProxyController.getInstance().unregisterForAllDataDisconnected(dds, this);
                 synchronized(this) {
@@ -1694,7 +1729,7 @@
                     mPhone.notifyPhysicalChannelConfig(list);
                     // Notify NR frequency, NR connection status or bandwidths changed.
                     if (hasChanged) {
-                        mPhone.notifyServiceStateChanged(mPhone.getServiceState());
+                        mPhone.notifyServiceStateChanged(mSS);
                         TelephonyMetrics.getInstance().writeServiceStateChanged(
                                 mPhone.getPhoneId(), mSS);
                         mPhone.getVoiceCallSessionStats().onServiceStateChanged(mSS);
@@ -1726,27 +1761,81 @@
                 pollStateInternal(false);
                 break;
 
+            case EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST: {
+                Pair<SignalRequestRecord, Message> pair =
+                        (Pair<SignalRequestRecord, Message>) msg.obj;
+                SignalRequestRecord record = pair.first;
+                Message onCompleted = pair.second;
+                AsyncResult ret = AsyncResult.forMessage(onCompleted);
+
+                // TODO(b/177956310): Check subId to filter out old request until a better solution
+                boolean dupRequest = mSignalRequestRecords.stream().anyMatch(
+                        srr -> srr.mCallingUid == record.mCallingUid
+                                && srr.mSubId == record.mSubId);
+                if (dupRequest) {
+                    ret.exception = new IllegalStateException(
+                            "setSignalStrengthUpdateRequest called again with same subId");
+                    onCompleted.sendToTarget();
+                    break;
+                }
+
+                try {
+                    record.mRequest.getLiveToken().linkToDeath(record, 0);
+                } catch (RemoteException | NullPointerException ex) {
+                    ret.exception = new IllegalStateException(
+                            "Signal request client is already dead.");
+                    onCompleted.sendToTarget();
+                    break;
+                }
+
+                mSignalRequestRecords.add(record);
+                updateAlwaysReportSignalStrength();
+                updateReportingCriteria(getCarrierConfig());
+
+                onCompleted.sendToTarget();
+
+                // Always poll signal strength after setting the update request which has waken up
+                // modem if it was idle. An additional signal strength polling is almost cost free.
+                obtainMessage(EVENT_POLL_SIGNAL_STRENGTH).sendToTarget();
+                break;
+            }
+
+            case EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST: {
+                Pair<SignalRequestRecord, Message> pair =
+                        (Pair<SignalRequestRecord, Message>) msg.obj;
+                SignalRequestRecord record = pair.first;
+                Message onCompleted = pair.second;
+
+                // for loop with removal may cause ConcurrentModificationException
+                Iterator<SignalRequestRecord> it = mSignalRequestRecords.iterator();
+                while (it.hasNext()) {
+                    SignalRequestRecord srr = it.next();
+                    if (srr.mRequest.getLiveToken().equals(record.mRequest.getLiveToken())) {
+                        it.remove();
+                    }
+                }
+
+                updateAlwaysReportSignalStrength();
+                updateReportingCriteria(getCarrierConfig());
+
+                if (onCompleted != null) {
+                    AsyncResult ret = AsyncResult.forMessage(onCompleted);
+                    onCompleted.sendToTarget();
+                }
+                break;
+            }
+
+            case EVENT_ON_DEVICE_IDLE_STATE_CHANGED: {
+                updateReportingCriteria(getCarrierConfig());
+                break;
+            }
+
             case EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT: {
                 if (DBG) log("EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT triggered");
                 powerOffRadioSafely();
                 break;
             }
 
-            case EVENT_RESET_LAST_KNOWN_CELL_IDENTITY: {
-                if (DBG) log("EVENT_RESET_LAST_KNOWN_CELL_IDENTITY triggered");
-                mLastKnownCellIdentity = null;
-                break;
-            }
-
-            case EVENT_TELECOM_VOICE_SERVICE_STATE_OVERRIDE_CHANGED:
-                if (DBG) log("EVENT_TELECOM_VOICE_SERVICE_STATE_OVERRIDE_CHANGED");
-                // Similar to IMS, OTT voice state will only affect the merged service state if the
-                // CS voice service state of GsmCdma phone is not STATE_IN_SERVICE.
-                if (mSS.getState() != ServiceState.STATE_IN_SERVICE) {
-                    mPhone.notifyServiceStateChanged(mPhone.getServiceState());
-                }
-                break;
-
             default:
                 log("Unhandled message with number: " + msg.what);
                 break;
@@ -1938,7 +2027,7 @@
         if (ar.userObj != mPollingContext) return;
 
         if (ar.exception != null) {
-            CommandException.Error err = null;
+            CommandException.Error err=null;
 
             if (ar.exception instanceof IllegalStateException) {
                 log("handlePollStateResult exception " + ar.exception);
@@ -1948,22 +2037,15 @@
                 err = ((CommandException)(ar.exception)).getCommandError();
             }
 
-            if (mCi.getRadioState() != TelephonyManager.RADIO_POWER_ON) {
-                log("handlePollStateResult: Invalid response due to radio off or unavailable. "
-                        + "Set ServiceState to out of service.");
-                pollStateInternal(false);
-                return;
-            }
-
             if (err == CommandException.Error.RADIO_NOT_AVAILABLE) {
-                loge("handlePollStateResult: RIL returned RADIO_NOT_AVAILABLE when radio is on.");
+                // Radio has crashed or turned off
                 cancelPollState();
                 return;
             }
 
             if (err != CommandException.Error.OP_NOT_ALLOWED_BEFORE_REG_NW) {
-                loge("handlePollStateResult: RIL returned an error where it must succeed: "
-                        + ar.exception);
+                loge("RIL implementation has returned an error where it must succeed" +
+                        ar.exception);
             }
         } else try {
             handlePollStateResultMessage(what, ar);
@@ -2064,13 +2146,11 @@
                     }
                 }
 
-                if (mEriManager != null) {
-                    int roamingIndicator = mNewSS.getCdmaRoamingIndicator();
-                    mNewSS.setCdmaEriIconIndex(mEriManager.getCdmaEriIconIndex(roamingIndicator,
-                            mDefaultRoamingIndicator));
-                    mNewSS.setCdmaEriIconMode(mEriManager.getCdmaEriIconMode(roamingIndicator,
-                            mDefaultRoamingIndicator));
-                }
+                int roamingIndicator = mNewSS.getCdmaRoamingIndicator();
+                mNewSS.setCdmaEriIconIndex(mEriManager.getCdmaEriIconIndex(roamingIndicator,
+                        mDefaultRoamingIndicator));
+                mNewSS.setCdmaEriIconMode(mEriManager.getCdmaEriIconMode(roamingIndicator,
+                        mDefaultRoamingIndicator));
 
                 // NOTE: Some operator may require overriding mCdmaRoaming
                 // (set by the modem), depending on the mRoamingIndicator.
@@ -2103,14 +2183,23 @@
     private boolean updateNrFrequencyRangeFromPhysicalChannelConfigs(
             List<PhysicalChannelConfig> physicalChannelConfigs, ServiceState ss) {
         int newFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN;
+
         if (physicalChannelConfigs != null) {
+            DcTracker dcTracker = mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
             for (PhysicalChannelConfig config : physicalChannelConfigs) {
-                if (isNrPhysicalChannelConfig(config) && isInternetPhysicalChannelConfig(config)) {
-                    // Update the NR frequency range if there is an internet data connection
-                    // associated with this NR physical channel channel config.
-                    newFrequencyRange = ServiceState.getBetterNRFrequencyRange(
-                            newFrequencyRange, config.getFrequencyRange());
-                    break;
+                if (isNrPhysicalChannelConfig(config)) {
+                    // Update the frequency range of the NR parameters if there is an internet data
+                    // connection associate to this NR physical channel channel config.
+                    int[] contextIds = config.getContextIds();
+                    for (int cid : contextIds) {
+                        DataConnection dc = dcTracker.getDataConnectionByContextId(cid);
+                        if (dc != null && dc.getNetworkCapabilities().hasCapability(
+                                NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
+                            newFrequencyRange = ServiceState.getBetterNRFrequencyRange(
+                                    newFrequencyRange, config.getFrequencyRange());
+                            break;
+                        }
+                    }
                 }
             }
         }
@@ -2128,8 +2217,7 @@
 
         boolean hasNrSecondaryServingCell = false;
         for (PhysicalChannelConfig config : configs) {
-            if (isNrPhysicalChannelConfig(config) && isInternetPhysicalChannelConfig(config)
-                    && config.getConnectionStatus()
+            if (isNrPhysicalChannelConfig(config) && config.getConnectionStatus()
                     == PhysicalChannelConfig.CONNECTION_SECONDARY_SERVING) {
                 hasNrSecondaryServingCell = true;
                 break;
@@ -2137,7 +2225,7 @@
         }
 
         int oldNrState = regInfo.getNrState();
-        int newNrState;
+        int newNrState = oldNrState;
         if (hasNrSecondaryServingCell) {
             newNrState = NetworkRegistrationInfo.NR_STATE_CONNECTED;
         } else {
@@ -2155,25 +2243,6 @@
         return config.getNetworkType() == TelephonyManager.NETWORK_TYPE_NR;
     }
 
-    private boolean isInternetPhysicalChannelConfig(PhysicalChannelConfig config) {
-        for (int cid : config.getContextIds()) {
-            if (mPhone.isUsingNewDataStack()) {
-                if (mPhone.getDataNetworkController().isInternetNetwork(cid)) {
-                    return true;
-                }
-            } else {
-                DataConnection dc = mPhone.getDcTracker(
-                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .getDataConnectionByContextId(cid);
-                if (dc != null && dc.getNetworkCapabilities().hasCapability(
-                        NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
     /**
      * This combine PS registration states from cellular and IWLAN and generates the final data
      * reg state and rat for backward compatibility purpose. In reality there should be two separate
@@ -2190,7 +2259,7 @@
                 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
 
         // Check if any APN is preferred on IWLAN.
-        boolean isIwlanPreferred = mAccessNetworksManager.isAnyApnOnIwlan();
+        boolean isIwlanPreferred = mTransportManager.isAnyApnPreferredOnIwlan();
         serviceState.setIwlanPreferred(isIwlanPreferred);
         if (wlanPsRegState != null
                 && wlanPsRegState.getAccessNetworkTechnology()
@@ -2346,7 +2415,7 @@
                             && ServiceState.isPsOnlyTech(newDataRat))
                             || (ServiceState.isPsOnlyTech(oldDataRAT)
                             && ServiceState.isCdma(newDataRat))) {
-                        mPhone.getSignalStrengthController().getSignalStrengthFromCi();
+                        mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
                     }
 
                     // voice roaming state in done while handling EVENT_POLL_STATE_REGISTRATION_CDMA
@@ -2357,8 +2426,7 @@
                     mNewSS.setDataRoamingFromRegistration(isDataRoaming);
                 }
 
-                mPhone.getSignalStrengthController().updateServiceStateArfcnRsrpBoost(mNewSS,
-                        networkRegState.getCellIdentity());
+                updateServiceStateArfcnRsrpBoost(mNewSS, networkRegState.getCellIdentity());
                 break;
             }
 
@@ -2742,8 +2810,8 @@
         // override the operator name in home network. Also do this only for CDMA. This is temporary
         // and should be fixed in a proper way in a later release.
         if (!mPhone.isPhoneTypeGsm() && !mSS.getRoaming()) {
-            boolean hasBrandOverride = mUiccController.getUiccPort(getPhoneId()) != null
-                    && mUiccController.getUiccPort(getPhoneId()).getOperatorBrandOverride() != null;
+            boolean hasBrandOverride = mUiccController.getUiccCard(getPhoneId()) != null
+                    && mUiccController.getUiccCard(getPhoneId()).getOperatorBrandOverride() != null;
             if (!hasBrandOverride) {
                 PersistableBundle config = getCarrierConfig();
                 if (config.getBoolean(
@@ -2837,10 +2905,8 @@
         String wfcFlightSpnFormat = null;
         int combinedRegState = getCombinedRegState(mSS);
         if (mPhone.getImsPhone() != null && mPhone.getImsPhone().isWifiCallingEnabled()
-                && (combinedRegState == ServiceState.STATE_IN_SERVICE
-                && mSS.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_IWLAN)) {
-            // In Wi-Fi Calling mode (connected to WiFi and WFC enabled),
-            // show SPN or PLMN + WiFi Calling
+                && (combinedRegState == ServiceState.STATE_IN_SERVICE)) {
+            // In Wi-Fi Calling mode show SPN or PLMN + WiFi Calling
             //
             // 1) Show SPN + Wi-Fi Calling If SIM has SPN and SPN display condition
             //    is satisfied or SPN override is enabled for this carrier
@@ -3115,12 +3181,6 @@
             mRadioPowerLog.log(tmpLog);
         }
 
-        if (mDesiredPowerState && mDeviceShuttingDown) {
-            log("setPowerStateToDesired powering on of radio failed because the device is " +
-                    "powering off");
-            return;
-        }
-
         // If we want it on and it's off, turn it on
         if (mDesiredPowerState && !mRadioDisabledByCarrier
                 && (forceApply || mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF)) {
@@ -3128,14 +3188,13 @@
         } else if ((!mDesiredPowerState || mRadioDisabledByCarrier) && mCi.getRadioState()
                 == TelephonyManager.RADIO_POWER_ON) {
             // If it's on and available and we want it off gracefully
-            if (!mPhone.isUsingNewDataStack() && mImsRegistrationOnOff
-                    && getRadioPowerOffDelayTimeoutForImsRegistration() > 0) {
+            if (mImsRegistrationOnOff) {
                 if (DBG) log("setPowerStateToDesired: delaying power off until IMS dereg.");
                 startDelayRadioOffWaitingForImsDeregTimeout();
                 // Return early here as we do not want to hit the cancel timeout code below.
                 return;
             } else {
-                if (DBG) log("setPowerStateToDesired: powerOffRadioSafely()");
+                if (DBG) log("setPowerStateToDesired: powering off");
                 powerOffRadioSafely();
             }
         } else if (mDeviceShuttingDown
@@ -3172,7 +3231,7 @@
         }
         if (DBG) log("startDelayRadioOffWaitingForImsDeregTimeout: starting timer");
         sendEmptyMessageDelayed(EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT,
-                getRadioPowerOffDelayTimeoutForImsRegistration());
+                DELAY_RADIO_OFF_FOR_IMS_DEREG_TIMEOUT);
     }
 
     protected void onUpdateIccAvailability() {
@@ -3300,14 +3359,7 @@
 
         if (mImsRegistrationOnOff && !registered) {
             // moving to deregistered, only send this event if we need to re-evaluate
-            if (getRadioPowerOffDelayTimeoutForImsRegistration() > 0) {
-                // only send this event if the power off delay for IMS deregistration feature is
-                // enabled.
-                sendMessage(obtainMessage(EVENT_CHANGE_IMS_STATE));
-            } else {
-                log("setImsRegistrationState: EVENT_CHANGE_IMS_STATE not sent because power off "
-                        + "delay for IMS deregistration is not enabled.");
-            }
+            sendMessage(obtainMessage(EVENT_CHANGE_IMS_STATE));
         }
         mImsRegistrationOnOff = registered;
     }
@@ -3335,44 +3387,26 @@
 
     private void pollStateInternal(boolean modemTriggered) {
         mPollingContext = new int[1];
-        NetworkRegistrationInfo nri;
+        mPollingContext[0] = 0;
 
-        log("pollState: modemTriggered=" + modemTriggered + ", radioState=" + mCi.getRadioState());
+        log("pollState: modemTriggered=" + modemTriggered);
 
         switch (mCi.getRadioState()) {
             case TelephonyManager.RADIO_POWER_UNAVAILABLE:
-                // Preserve the IWLAN registration state, because that should not be affected by
-                // radio availability.
-                nri = mNewSS.getNetworkRegistrationInfo(
-                        NetworkRegistrationInfo.DOMAIN_PS,
-                        AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-                mNewSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), false);
-                // Add the IWLAN registration info back to service state.
-                if (nri != null) {
-                    mNewSS.addNetworkRegistrationInfo(nri);
-                }
-                mPhone.getSignalStrengthController().setSignalStrengthDefaultValues();
+                mNewSS.setStateOutOfService();
+                setSignalStrengthDefaultValues();
                 mLastNitzData = null;
                 mNitzState.handleNetworkUnavailable();
                 pollStateDone();
                 break;
 
             case TelephonyManager.RADIO_POWER_OFF:
-                // Preserve the IWLAN registration state, because that should not be affected by
-                // radio availability.
-                nri = mNewSS.getNetworkRegistrationInfo(
-                        NetworkRegistrationInfo.DOMAIN_PS,
-                        AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-                mNewSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), true);
-                // Add the IWLAN registration info back to service state.
-                if (nri != null) {
-                    mNewSS.addNetworkRegistrationInfo(nri);
-                }
-                mPhone.getSignalStrengthController().setSignalStrengthDefaultValues();
+                mNewSS.setStateOff();
+                setSignalStrengthDefaultValues();
                 mLastNitzData = null;
                 mNitzState.handleNetworkUnavailable();
-                // Don't poll when device is shutting down or the poll was not modemTriggered
-                // (they sent us new radio data) and the current network is not IWLAN
+                // don't poll when device is shutting down or the poll was not modemTrigged
+                // (they sent us new radio data) and current network is not IWLAN
                 if (mDeviceShuttingDown ||
                         (!modemTriggered && ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN
                         != mSS.getRilDataRadioTechnology())) {
@@ -3490,13 +3524,13 @@
                         && mNewSS.getState() != ServiceState.STATE_POWER_OFF;
 
         SparseBooleanArray hasDataAttached = new SparseBooleanArray(
-                mAccessNetworksManager.getAvailableTransports().length);
+                mTransportManager.getAvailableTransports().length);
         SparseBooleanArray hasDataDetached = new SparseBooleanArray(
-                mAccessNetworksManager.getAvailableTransports().length);
+                mTransportManager.getAvailableTransports().length);
         SparseBooleanArray hasRilDataRadioTechnologyChanged = new SparseBooleanArray(
-                mAccessNetworksManager.getAvailableTransports().length);
+                mTransportManager.getAvailableTransports().length);
         SparseBooleanArray hasDataRegStateChanged = new SparseBooleanArray(
-                mAccessNetworksManager.getAvailableTransports().length);
+                mTransportManager.getAvailableTransports().length);
         boolean anyDataRegChanged = false;
         boolean anyDataRatChanged = false;
         boolean hasAlphaRawChanged =
@@ -3504,7 +3538,7 @@
                         || !TextUtils.equals(mSS.getOperatorAlphaShortRaw(),
                         mNewSS.getOperatorAlphaShortRaw());
 
-        for (int transport : mAccessNetworksManager.getAvailableTransports()) {
+        for (int transport : mTransportManager.getAvailableTransports()) {
             NetworkRegistrationInfo oldNrs = mSS.getNetworkRegistrationInfo(
                     NetworkRegistrationInfo.DOMAIN_PS, transport);
             NetworkRegistrationInfo newNrs = mNewSS.getNetworkRegistrationInfo(
@@ -3598,8 +3632,6 @@
 
         boolean hasCssIndicatorChanged = (mSS.getCssIndicator() != mNewSS.getCssIndicator());
 
-        boolean hasBandwidthChanged = mSS.getCellBandwidths() != mNewSS.getCellBandwidths();
-
         boolean has4gHandoff = false;
         boolean hasMultiApnSupport = false;
         boolean hasLostMultiApnSupport = false;
@@ -3643,7 +3675,6 @@
                     + " hasCssIndicatorChanged = " + hasCssIndicatorChanged
                     + " hasNrFrequencyRangeChanged = " + hasNrFrequencyRangeChanged
                     + " hasNrStateChanged = " + hasNrStateChanged
-                    + " hasBandwidthChanged = " + hasBandwidthChanged
                     + " hasAirplaneModeOnlChanged = " + hasAirplaneModeOnChanged);
         }
 
@@ -3683,25 +3714,16 @@
             mRejectCode = mNewRejectCode;
         }
 
-        if (!Objects.equals(mSS, mNewSS)) {
-            mServiceStateChangedRegistrants.notifyRegistrants();
-        }
-
         ServiceState oldMergedSS = new ServiceState(mPhone.getServiceState());
-        mSS = new ServiceState(mNewSS);
 
-        mNewSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), false);
+        // swap mSS and mNewSS to put new state in mSS
+        ServiceState tss = mSS;
+        mSS = mNewSS;
+        mNewSS = tss;
+        // clean slate for next time
+        mNewSS.setStateOutOfService();
 
         mCellIdentity = primaryCellIdentity;
-        if (mSS.getState() == ServiceState.STATE_IN_SERVICE && primaryCellIdentity != null) {
-            mLastKnownCellIdentity = mCellIdentity;
-            removeMessages(EVENT_RESET_LAST_KNOWN_CELL_IDENTITY);
-        }
-
-        if (hasDeregistered && !hasMessages(EVENT_RESET_LAST_KNOWN_CELL_IDENTITY)) {
-            sendEmptyMessageDelayed(EVENT_RESET_LAST_KNOWN_CELL_IDENTITY,
-                    TimeUnit.DAYS.toMillis(1));
-        }
 
         int areaCode = getAreaCodeFromCellIdentity(mCellIdentity);
         if (areaCode != mLastKnownAreaCode && areaCode != CellInfo.UNAVAILABLE) {
@@ -3724,22 +3746,16 @@
 
         if (hasRegistered) {
             mNetworkAttachedRegistrants.notifyRegistrants();
-            mNitzState.handleNetworkAvailable();
         }
 
         if (hasDeregistered) {
             mNetworkDetachedRegistrants.notifyRegistrants();
-            mNitzState.handleNetworkUnavailable();
         }
 
         if (hasCssIndicatorChanged) {
             mCssIndicatorChangedRegistrants.notifyRegistrants();
         }
 
-        if (hasBandwidthChanged) {
-            mBandwidthChangedRegistrants.notifyRegistrants();
-        }
-
         if (hasRejectCauseChanged) {
             setNotification(CS_REJECT_CAUSE_ENABLED);
         }
@@ -3835,15 +3851,13 @@
 
         if (hasRilVoiceRadioTechnologyChanged) {
             shouldLogRatChange = true;
-            // TODO(b/178429976): Remove the dependency on SSC. Double check if the SS broadcast
-            // is really needed when CS/PS RAT change.
-            mPhone.getSignalStrengthController().notifySignalStrength();
+            notifySignalStrength();
         }
 
-        for (int transport : mAccessNetworksManager.getAvailableTransports()) {
+        for (int transport : mTransportManager.getAvailableTransports()) {
             if (hasRilDataRadioTechnologyChanged.get(transport)) {
                 shouldLogRatChange = true;
-                mPhone.getSignalStrengthController().notifySignalStrength();
+                notifySignalStrength();
             }
 
             if (hasDataRegStateChanged.get(transport)
@@ -3874,8 +3888,7 @@
         // because the signal strength might come earlier RAT and radio state
         // changed.
         if (hasAirplaneModeOffChanged) {
-            // TODO(b/178429976): Remove the dependency on SSC. This should be done in SSC.
-            mPhone.getSignalStrengthController().getSignalStrengthFromCi();
+            mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
         }
 
         if (shouldLogAttachedChange) {
@@ -3955,10 +3968,10 @@
                 }
             }
         } else if (mPhone.isPhoneTypeCdmaLte()) {
-            boolean hasBrandOverride = mUiccController.getUiccPort(getPhoneId()) != null
-                    && mUiccController.getUiccPort(getPhoneId()).getOperatorBrandOverride() != null;
+            boolean hasBrandOverride = mUiccController.getUiccCard(getPhoneId()) != null &&
+                    mUiccController.getUiccCard(getPhoneId()).getOperatorBrandOverride() != null;
             if (!hasBrandOverride && (mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON)
-                    && (mEriManager != null && mEriManager.isEriFileLoaded())
+                    && (mEriManager.isEriFileLoaded())
                     && (!ServiceState.isPsOnlyTech(mSS.getRilVoiceRadioTechnology())
                     || mPhone.getContext().getResources().getBoolean(com.android.internal.R
                     .bool.config_LTE_eri_for_network_name))) {
@@ -4085,9 +4098,9 @@
     }
 
     private String getOperatorBrandOverride() {
-        UiccPort uiccPort = mPhone.getUiccPort();
-        if (uiccPort == null) return null;
-        UiccProfile profile = uiccPort.getUiccProfile();
+        UiccCard card = mPhone.getUiccCard();
+        if (card == null) return null;
+        UiccProfile profile = card.getUiccProfile();
         if (profile == null) return null;
         return profile.getOperatorBrandOverride();
     }
@@ -4470,24 +4483,20 @@
     }
 
     /**
-     * Handle the NITZ string from the modem
-     *
-     * @param nitzString NITZ time string in the form "yy/mm/dd,hh:mm:ss(+/-)tz,dt"
-     * @param nitzReceiveTimeMs time according to {@link android.os.SystemClock#elapsedRealtime()}
-     *        when the RIL sent the NITZ time to the framework
-     * @param ageMs time in milliseconds indicating how long NITZ was cached in RIL and modem
+     * nitzReceiveTime is time_t that the NITZ time was posted
      */
-    private void setTimeFromNITZString(String nitzString, long nitzReceiveTimeMs, long ageMs) {
+    private void setTimeFromNITZString(String nitzString, long nitzReceiveTime) {
         long start = SystemClock.elapsedRealtime();
         if (DBG) {
-            Rlog.d(LOG_TAG, "NITZ: " + nitzString + "," + nitzReceiveTimeMs + ", ageMs=" + ageMs
-                    + " start=" + start + " delay=" + (start - nitzReceiveTimeMs));
+            Rlog.d(LOG_TAG, "NITZ: " + nitzString + "," + nitzReceiveTime
+                    + " start=" + start + " delay=" + (start - nitzReceiveTime));
         }
         NitzData newNitzData = NitzData.parse(nitzString);
         mLastNitzData = newNitzData;
         if (newNitzData != null) {
             try {
-                NitzSignal nitzSignal = new NitzSignal(nitzReceiveTimeMs, newNitzData, ageMs);
+                TimestampedValue<NitzData> nitzSignal =
+                        new TimestampedValue<>(nitzReceiveTime, newNitzData);
                 mNitzState.handleNitzReceived(nitzSignal);
             } finally {
                 if (DBG) {
@@ -4733,6 +4742,31 @@
         }
     }
 
+    private void queueNextSignalStrengthPoll() {
+        if (mDontPollSignalStrength) {
+            // The radio is telling us about signal strength changes
+            // we don't have to ask it
+            return;
+        }
+
+        // if there is no SIM present, do not poll signal strength
+        UiccCard uiccCard = UiccController.getInstance().getUiccCard(getPhoneId());
+        if (uiccCard == null || uiccCard.getCardState() == CardState.CARDSTATE_ABSENT) {
+            log("Not polling signal strength due to absence of SIM");
+            return;
+        }
+
+        Message msg;
+
+        msg = obtainMessage();
+        msg.what = EVENT_POLL_SIGNAL_STRENGTH;
+
+        long nextTime;
+
+        // TODO Don't poll signal strength if screen is off
+        sendMessageDelayed(msg, POLL_PERIOD_MILLIS);
+    }
+
     private void notifyCdmaSubscriptionInfoReady() {
         if (mCdmaForSubscriptionInfoReadyRegistrants != null) {
             if (DBG) log("CDMA_SUBSCRIPTION: call notifyRegistrants()");
@@ -4983,25 +5017,6 @@
     }
 
     /**
-     * Register for service state changed event.
-     *
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     */
-    public void registerForServiceStateChanged(Handler h, int what) {
-        mServiceStateChangedRegistrants.addUnique(h, what, null);
-    }
-
-    /**
-     * Unregister for service state changed event.
-     *
-     * @param h The handler.
-     */
-    public void unregisterForServiceStateChanged(Handler h) {
-        mServiceStateChangedRegistrants.remove(h);
-    }
-
-    /**
      * Clean up existing voice and data connection then turn off radio power.
      *
      * Hang up the existing voice calls to decrease call drop rate.
@@ -5009,20 +5024,6 @@
     public void powerOffRadioSafely() {
         synchronized (this) {
             if (!mPendingRadioPowerOffAfterDataOff) {
-                if (mPhone.isUsingNewDataStack()) {
-                    if (mAnyDataExisting) {
-                        log("powerOffRadioSafely: Tear down all data networks.");
-                        mPhone.getDataNetworkController().tearDownAllDataNetworks(
-                                DataNetwork.TEAR_DOWN_REASON_AIRPLANE_MODE_ON);
-                        sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF,
-                                POWER_OFF_ALL_DATA_NETWORKS_DISCONNECTED_TIMEOUT);
-                    } else {
-                        log("powerOffRadioSafely: No data is connected.");
-                        sendEmptyMessage(EVENT_ALL_DATA_DISCONNECTED);
-                    }
-                    mPendingRadioPowerOffAfterDataOff = true;
-                    return;
-                }
                 int dds = SubscriptionManager.getDefaultDataSubscriptionId();
                 // To minimize race conditions we call cleanUpAllConnections on
                 // both if else paths instead of before this isDisconnected test.
@@ -5031,7 +5032,7 @@
                         || (dds != mPhone.getSubId()
                         && ProxyController.getInstance().areAllDataDisconnected(dds)))) {
                     // To minimize race conditions we do this after isDisconnected
-                    for (int transport : mAccessNetworksManager.getAvailableTransports()) {
+                    for (int transport : mTransportManager.getAvailableTransports()) {
                         if (mPhone.getDcTracker(transport) != null) {
                             mPhone.getDcTracker(transport).cleanUpAllConnections(
                                     Phone.REASON_RADIO_TURNED_OFF);
@@ -5048,7 +5049,7 @@
                         mPhone.mCT.mBackgroundCall.hangupIfAlive();
                         mPhone.mCT.mForegroundCall.hangupIfAlive();
                     }
-                    for (int transport : mAccessNetworksManager.getAvailableTransports()) {
+                    for (int transport : mTransportManager.getAvailableTransports()) {
                         if (mPhone.getDcTracker(transport) != null) {
                             mPhone.getDcTracker(transport).cleanUpAllConnections(
                                     Phone.REASON_RADIO_TURNED_OFF);
@@ -5105,16 +5106,86 @@
         }
     }
 
+    /**
+     * Checks if the provided earfcn falls withing the range of earfcns.
+     *
+     * return int index in earfcnPairList if earfcn falls within the provided range; -1 otherwise.
+     */
+    private int containsEarfcnInEarfcnRange(ArrayList<Pair<Integer, Integer>> earfcnPairList,
+            int earfcn) {
+        int index = 0;
+        if (earfcnPairList != null) {
+            for (Pair<Integer, Integer> earfcnPair : earfcnPairList) {
+                if ((earfcn >= earfcnPair.first) && (earfcn <= earfcnPair.second)) {
+                    return index;
+                }
+                index++;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Convert the earfcnStringArray to list of pairs.
+     *
+     * Format of the earfcnsList is expected to be {"erafcn1_start-earfcn1_end",
+     * "earfcn2_start-earfcn2_end" ... }
+     */
+    ArrayList<Pair<Integer, Integer>> convertEarfcnStringArrayToPairList(String[] earfcnsList) {
+        ArrayList<Pair<Integer, Integer>> earfcnPairList = new ArrayList<Pair<Integer, Integer>>();
+
+        if (earfcnsList != null) {
+            int earfcnStart;
+            int earfcnEnd;
+            for (int i = 0; i < earfcnsList.length; i++) {
+                try {
+                    String[] earfcns = earfcnsList[i].split("-");
+                    if (earfcns.length != 2) {
+                        if (VDBG) {
+                            log("Invalid earfcn range format");
+                        }
+                        return null;
+                    }
+
+                    earfcnStart = Integer.parseInt(earfcns[0]);
+                    earfcnEnd = Integer.parseInt(earfcns[1]);
+
+                    if (earfcnStart > earfcnEnd) {
+                        if (VDBG) {
+                            log("Invalid earfcn range format");
+                        }
+                        return null;
+                    }
+
+                    earfcnPairList.add(new Pair<Integer, Integer>(earfcnStart, earfcnEnd));
+                } catch (PatternSyntaxException pse) {
+                    if (VDBG) {
+                        log("Invalid earfcn range format");
+                    }
+                    return null;
+                } catch (NumberFormatException nfe) {
+                    if (VDBG) {
+                        log("Invalid earfcn number format");
+                    }
+                    return null;
+                }
+            }
+        }
+
+        return earfcnPairList;
+    }
+
     private void onCarrierConfigChanged() {
         PersistableBundle config = getCarrierConfig();
         log("CarrierConfigChange " + config);
 
         // Load the ERI based on carrier config. Carrier might have their specific ERI.
-        if (mEriManager != null) {
-            mEriManager.loadEriFile();
-            mCdnr.updateEfForEri(getOperatorNameFromEri());
-        }
+        mEriManager.loadEriFile();
+        mCdnr.updateEfForEri(getOperatorNameFromEri());
 
+        updateArfcnLists(config);
+        updateReportingCriteria(config);
         updateOperatorNamePattern(config);
         mCdnr.updateEfFromCarrierConfig(config);
         mPhone.notifyCallForwardingIndicator();
@@ -5125,11 +5196,143 @@
         pollStateInternal(false);
     }
 
+    private void updateArfcnLists(PersistableBundle config) {
+        synchronized (mRsrpBoostLock) {
+            mLteRsrpBoost = config.getInt(CarrierConfigManager.KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0);
+            String[] earfcnsStringArrayForRsrpBoost = config.getStringArray(
+                    CarrierConfigManager.KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY);
+            mEarfcnPairListForRsrpBoost = convertEarfcnStringArrayToPairList(
+                    earfcnsStringArrayForRsrpBoost);
+
+            mNrRsrpBoost = config.getIntArray(
+                    CarrierConfigManager.KEY_NRARFCNS_RSRP_BOOST_INT_ARRAY);
+            String[] nrarfcnsStringArrayForRsrpBoost = config.getStringArray(
+                    CarrierConfigManager.KEY_BOOSTED_NRARFCNS_STRING_ARRAY);
+            mNrarfcnRangeListForRsrpBoost = convertEarfcnStringArrayToPairList(
+                    nrarfcnsStringArrayForRsrpBoost);
+
+            if ((mNrRsrpBoost == null && mNrarfcnRangeListForRsrpBoost != null)
+                    || (mNrRsrpBoost != null && mNrarfcnRangeListForRsrpBoost == null)
+                    || (mNrRsrpBoost != null && mNrarfcnRangeListForRsrpBoost != null
+                    && mNrRsrpBoost.length != mNrarfcnRangeListForRsrpBoost.size())) {
+                loge("Invalid parameters for NR RSRP boost");
+                mNrRsrpBoost = null;
+                mNrarfcnRangeListForRsrpBoost = null;
+            }
+        }
+    }
+
+    private void updateReportingCriteria(PersistableBundle config) {
+        int lteMeasurementEnabled = config.getInt(CarrierConfigManager
+                .KEY_PARAMETERS_USED_FOR_LTE_SIGNAL_BAR_INT, CellSignalStrengthLte.USE_RSRP);
+        mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
+                config.getIntArray(CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY),
+                AccessNetworkType.EUTRAN,
+                (lteMeasurementEnabled & CellSignalStrengthLte.USE_RSRP) != 0);
+        mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP,
+                config.getIntArray(CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY),
+                AccessNetworkType.UTRAN, true);
+        mPhone.setSignalStrengthReportingCriteria(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
+                config.getIntArray(CarrierConfigManager.KEY_GSM_RSSI_THRESHOLDS_INT_ARRAY),
+                AccessNetworkType.GERAN, true);
+
+        if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
+            mPhone.setSignalStrengthReportingCriteria(
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
+                    config.getIntArray(CarrierConfigManager.KEY_LTE_RSRQ_THRESHOLDS_INT_ARRAY),
+                    AccessNetworkType.EUTRAN,
+                    (lteMeasurementEnabled & CellSignalStrengthLte.USE_RSRQ) != 0);
+            mPhone.setSignalStrengthReportingCriteria(
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR,
+                    config.getIntArray(CarrierConfigManager.KEY_LTE_RSSNR_THRESHOLDS_INT_ARRAY),
+                    AccessNetworkType.EUTRAN,
+                    (lteMeasurementEnabled & CellSignalStrengthLte.USE_RSSNR) != 0);
+
+            int measurementEnabled = config.getInt(CarrierConfigManager
+                    .KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT, CellSignalStrengthNr.USE_SSRSRP);
+            mPhone.setSignalStrengthReportingCriteria(
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
+                    config.getIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY),
+                    AccessNetworkType.NGRAN,
+                    (measurementEnabled & CellSignalStrengthNr.USE_SSRSRP) != 0);
+            mPhone.setSignalStrengthReportingCriteria(
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
+                    config.getIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY),
+                    AccessNetworkType.NGRAN,
+                    (measurementEnabled & CellSignalStrengthNr.USE_SSRSRQ) != 0);
+            mPhone.setSignalStrengthReportingCriteria(
+                    SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR,
+                    config.getIntArray(CarrierConfigManager.KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY),
+                    AccessNetworkType.NGRAN,
+                    (measurementEnabled & CellSignalStrengthNr.USE_SSSINR) != 0);
+        }
+    }
+
+    private void updateServiceStateArfcnRsrpBoost(ServiceState serviceState,
+            CellIdentity cellIdentity) {
+        int rsrpBoost = 0;
+        int arfcn;
+
+        synchronized (mRsrpBoostLock) {
+            switch (cellIdentity.getType()) {
+                case CellInfo.TYPE_LTE:
+                    arfcn = ((CellIdentityLte) cellIdentity).getEarfcn();
+                    if (arfcn != INVALID_ARFCN
+                            && containsEarfcnInEarfcnRange(mEarfcnPairListForRsrpBoost,
+                            arfcn) != -1) {
+                        rsrpBoost = mLteRsrpBoost;
+                    }
+                    break;
+                case CellInfo.TYPE_NR:
+                    arfcn = ((CellIdentityNr) cellIdentity).getNrarfcn();
+                    if (arfcn != INVALID_ARFCN) {
+                        int index = containsEarfcnInEarfcnRange(mNrarfcnRangeListForRsrpBoost,
+                                arfcn);
+                        if (index != -1) {
+                            rsrpBoost = mNrRsrpBoost[index];
+                        }
+                    }
+                    break;
+                default:
+                    break;
+            }
+        }
+        serviceState.setArfcnRsrpBoost(rsrpBoost);
+    }
+
+    /**
+     * send signal-strength-changed notification if changed Called both for
+     * solicited and unsolicited signal strength updates
+     *
+     * @return true if the signal strength changed and a notification was sent.
+     */
+    protected boolean onSignalStrengthResult(AsyncResult ar) {
+
+        // This signal is used for both voice and data radio signal so parse
+        // all fields
+        // Under power off, let's suppress valid signal strength report, which is
+        // beneficial to avoid icon flickering.
+        if ((ar.exception == null) && (ar.result != null)
+                && mSS.getState() != ServiceState.STATE_POWER_OFF) {
+            mSignalStrength = (SignalStrength) ar.result;
+
+            PersistableBundle config = getCarrierConfig();
+            mSignalStrength.updateLevel(config, mSS);
+        } else {
+            log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
+            mSignalStrength = new SignalStrength();
+        }
+        mSignalStrengthUpdatedTime = System.currentTimeMillis();
+
+        boolean ssChanged = notifySignalStrength();
+
+        return ssChanged;
+    }
+
     /**
      * Hang up all voice call and turn off radio. Implemented by derived class.
      */
     protected void hangupAndPowerOff() {
-        if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF) return;
         // hang up all active voice calls
         if (!mPhone.isPhoneTypeGsm() || mPhone.isInCall()) {
             mPhone.mCT.mRingingCall.hangupIfAlive();
@@ -5249,6 +5452,50 @@
     }
 
     /**
+     * @return signal strength
+     */
+    public SignalStrength getSignalStrength() {
+        if (shouldRefreshSignalStrength()) {
+            log("SST.getSignalStrength() refreshing signal strength.");
+            obtainMessage(EVENT_POLL_SIGNAL_STRENGTH).sendToTarget();
+        }
+        return mSignalStrength;
+    }
+
+    private boolean shouldRefreshSignalStrength() {
+        long curTime = System.currentTimeMillis();
+
+        // If last signal strength is older than 10 seconds, or somehow if curTime is smaller
+        // than mSignalStrengthUpdatedTime (system time update), it's considered stale.
+        boolean isStale = (mSignalStrengthUpdatedTime > curTime)
+                || (curTime - mSignalStrengthUpdatedTime > SIGNAL_STRENGTH_REFRESH_THRESHOLD_IN_MS);
+        if (!isStale) return false;
+
+        List<SubscriptionInfo> subInfoList = SubscriptionController.getInstance()
+                .getActiveSubscriptionInfoList(mPhone.getContext().getOpPackageName(),
+                        mPhone.getContext().getAttributionTag());
+
+        if (!ArrayUtils.isEmpty(subInfoList)) {
+            for (SubscriptionInfo info : subInfoList) {
+                // If we have an active opportunistic subscription whose data is IN_SERVICE,
+                // we need to get signal strength to decide data switching threshold. In this case,
+                // we poll latest signal strength from modem.
+                if (info.isOpportunistic()) {
+                    TelephonyManager tm = TelephonyManager.from(mPhone.getContext())
+                            .createForSubscriptionId(info.getSubscriptionId());
+                    ServiceState ss = tm.getServiceState();
+                    if (ss != null
+                            && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) {
+                        return true;
+                    }
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
      * Registration point for subscription info ready
      * @param h handler to notify
      * @param what what code of message when delivered
@@ -5299,9 +5546,23 @@
         }
     }
 
-    /** Called when telecom has reported a voice service state change. */
-    public void onTelecomVoiceServiceStateOverrideChanged() {
-        sendMessage(obtainMessage(EVENT_TELECOM_VOICE_SERVICE_STATE_OVERRIDE_CHANGED));
+    private void dumpEarfcnPairList(PrintWriter pw, ArrayList<Pair<Integer, Integer>> pairList,
+            String name) {
+        pw.print(" " + name + "={");
+        if (pairList != null) {
+            int i = pairList.size();
+            for (Pair<Integer, Integer> earfcnPair : pairList) {
+                pw.print("(");
+                pw.print(earfcnPair.first);
+                pw.print(",");
+                pw.print(earfcnPair.second);
+                pw.print(")");
+                if ((--i) != 0) {
+                    pw.print(",");
+                }
+            }
+        }
+        pw.println("}");
     }
 
     private void dumpCellInfoList(PrintWriter pw) {
@@ -5329,6 +5590,9 @@
         pw.println(" mPollingContext=" + mPollingContext + " - " +
                 (mPollingContext != null ? mPollingContext[0] : ""));
         pw.println(" mDesiredPowerState=" + mDesiredPowerState);
+        pw.println(" mDontPollSignalStrength=" + mDontPollSignalStrength);
+        pw.println(" mSignalStrength=" + mSignalStrength);
+        pw.println(" mLastSignalStrength=" + mLastSignalStrength);
         pw.println(" mRestrictedState=" + mRestrictedState);
         pw.println(" mPendingRadioPowerOffAfterDataOff=" + mPendingRadioPowerOffAfterDataOff);
         pw.println(" mPendingRadioPowerOffAfterDataOffTag=" + mPendingRadioPowerOffAfterDataOffTag);
@@ -5337,7 +5601,6 @@
         dumpCellInfoList(pw);
         pw.flush();
         pw.println(" mAllowedNetworkTypes=" + mAllowedNetworkTypes);
-        pw.println(" mAnyDataExisting=" + mAnyDataExisting);
         pw.println(" mMaxDataCalls=" + mMaxDataCalls);
         pw.println(" mNewMaxDataCalls=" + mNewMaxDataCalls);
         pw.println(" mReasonDataDenied=" + mReasonDataDenied);
@@ -5380,12 +5643,16 @@
         pw.println(" mImsRegistered=" + mImsRegistered);
         pw.println(" mImsRegistrationOnOff=" + mImsRegistrationOnOff);
         pw.println(" pending radio off event="
-                + hasMessages(EVENT_POWER_OFF_RADIO_IMS_DEREG_TIMEOUT));
+                + hasMessages(DELAY_RADIO_OFF_FOR_IMS_DEREG_TIMEOUT));
         pw.println(" mRadioDisabledByCarrier" + mRadioDisabledByCarrier);
         pw.println(" mDeviceShuttingDown=" + mDeviceShuttingDown);
         pw.println(" mSpnUpdatePending=" + mSpnUpdatePending);
+        pw.println(" mLteRsrpBoost=" + mLteRsrpBoost);
+        pw.println(" mNrRsrpBoost=" + Arrays.toString(mNrRsrpBoost));
         pw.println(" mCellInfoMinIntervalMs=" + mCellInfoMinIntervalMs);
         pw.println(" mEriManager=" + mEriManager);
+        dumpEarfcnPairList(pw, mEarfcnPairListForRsrpBoost, "mEarfcnPairListForRsrpBoost");
+        dumpEarfcnPairList(pw, mNrarfcnRangeListForRsrpBoost, "mNrarfcnRangeListForRsrpBoost");
 
         mLocaleTracker.dump(fd, pw, args);
         IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "    ");
@@ -5470,13 +5737,6 @@
         final String homeMCC = homeNumeric.substring(0, 3);
         final String networkCountry = MccTable.countryCodeForMcc(networkMCC);
         final String homeCountry = MccTable.countryCodeForMcc(homeMCC);
-
-        if (mLocaleTracker != null && !TextUtils.isEmpty(mLocaleTracker.getCountryOverride())) {
-            log("inSameCountry:  countryOverride var set.  This should only be set for testing "
-                    + "purposes to override the device location.");
-            return mLocaleTracker.getCountryOverride().equals(homeCountry);
-        }
-
         if (networkCountry.isEmpty() || homeCountry.isEmpty()) {
             // Not a valid country
             return false;
@@ -5590,6 +5850,12 @@
         }
     }
 
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private void setSignalStrengthDefaultValues() {
+        mSignalStrength = new SignalStrength();
+        mSignalStrengthUpdatedTime = System.currentTimeMillis();
+    }
+
     protected String getHomeOperatorNumeric() {
         String numeric = ((TelephonyManager) mPhone.getContext().
                 getSystemService(Context.TELEPHONY_SERVICE)).
@@ -5626,7 +5892,7 @@
             }
             // operator info should be kept in SS
             String operator = mNewSS.getOperatorAlphaLong();
-            mNewSS.setOutOfService(mAccessNetworksManager.isInLegacyMode(), true);
+            mNewSS.setStateOff();
             if (resetIwlanRatVal) {
                 mNewSS.setDataRegState(ServiceState.STATE_IN_SERVICE);
                 NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
@@ -5636,7 +5902,7 @@
                         .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                         .build();
                 mNewSS.addNetworkRegistrationInfo(nri);
-                if (mAccessNetworksManager.isInLegacyMode()) {
+                if (mTransportManager.isInLegacyMode()) {
                     // If in legacy mode, simulate the behavior that IWLAN registration info
                     // is reported through WWAN transport.
                     nri = new NetworkRegistrationInfo.Builder()
@@ -5664,7 +5930,7 @@
         // unfortunate limitation we have when the device operates in legacy mode. In AP-assisted
         // mode, the WWAN registration will correctly report the actual cellular registration info
         // when the device camps on IWLAN.
-        if (mAccessNetworksManager.isInLegacyMode()) {
+        if (mTransportManager.isInLegacyMode()) {
             NetworkRegistrationInfo wwanNri = mNewSS.getNetworkRegistrationInfo(
                     NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
             if (wwanNri != null && wwanNri.getAccessNetworkTechnology()
@@ -5786,7 +6052,7 @@
     }
 
     String getCdmaEriText(int roamInd, int defRoamInd) {
-        return mEriManager != null ? mEriManager.getCdmaEriText(roamInd, defRoamInd) : "no ERI";
+        return mEriManager.getCdmaEriText(roamInd, defRoamInd);
     }
 
     private void updateOperatorNamePattern(PersistableBundle config) {
@@ -5938,25 +6204,6 @@
     }
 
     /**
-     * Registers for cell bandwidth changed.
-     * @param h handler to notify
-     * @param what what code of message when delivered
-     * @param obj placed in Message.obj
-     */
-    public void registerForBandwidthChanged(Handler h, int what, Object obj) {
-        Registrant r = new Registrant(h, what, obj);
-        mBandwidthChangedRegistrants.add(r);
-    }
-
-    /**
-     * Unregisters for cell bandwidth changed.
-     * @param h handler to notify
-     */
-    public void unregisterForBandwidthChanged(Handler h) {
-        mBandwidthChangedRegistrants.remove(h);
-    }
-
-    /**
      * Get the NR data connection context ids.
      *
      * @return data connection context ids.
@@ -6017,6 +6264,153 @@
     }
 
     /**
+     * Set a new request to update the signal strength thresholds.
+     */
+    public void setSignalStrengthUpdateRequest(int subId, int callingUid,
+            SignalStrengthUpdateRequest request, @NonNull Message onCompleted) {
+        SignalRequestRecord record = new SignalRequestRecord(subId, callingUid, request);
+        sendMessage(obtainMessage(EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST,
+                new Pair<SignalRequestRecord, Message>(record, onCompleted)));
+    }
+
+    /**
+     * Clear the previously set request.
+     */
+    public void clearSignalStrengthUpdateRequest(int subId, int callingUid,
+            SignalStrengthUpdateRequest request, @Nullable Message onCompleted) {
+        SignalRequestRecord record = new SignalRequestRecord(subId, callingUid, request);
+        sendMessage(obtainMessage(EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST,
+                new Pair<SignalRequestRecord, Message>(record, onCompleted)));
+    }
+
+    /**
+     * Align all the qualified thresholds set from applications to the {@code systemThresholds}
+     * and consolidate a new thresholds array, follow rules below:
+     * 1. All threshold values (whose interval is guaranteed to be larger than hysteresis) in
+     *    {@code systemThresholds} will keep as it.
+     * 2. Any threshold from apps that has interval less than hysteresis from any threshold in
+     *    {@code systemThresholds} will be removed.
+     * 3. The target thresholds will be {@code systemThresholds} + all qualified thresholds from
+     *    apps, sorted in ascending order.
+     */
+    int[] getConsolidatedSignalThresholds(int ran, int measurement,
+            int[] systemThresholds, int hysteresis) {
+
+        // TreeSet with comparator that will filter element with interval less than hysteresis
+        // from any current element
+        Set<Integer> target = new TreeSet<>((x, y) -> {
+            if (y >= x - hysteresis && y <= x + hysteresis) {
+                return 0;
+            }
+            return Integer.compare(x, y);
+        });
+
+        for (int systemThreshold : systemThresholds) {
+            target.add(systemThreshold);
+        }
+
+        final boolean isDeviceIdle = mPhone.isDeviceIdle();
+        final int curSubId = mPhone.getSubId();
+        // The total number of record is small (10~15 tops). With each request has at most 5
+        // SignalThresholdInfo which has at most 8 thresholds arrays. So the nested loop should
+        // not be a concern here.
+        for (SignalRequestRecord record : mSignalRequestRecords) {
+            if (curSubId != record.mSubId
+                    || (isDeviceIdle && !record.mRequest.isReportingRequestedWhileIdle())) {
+                continue;
+            }
+            for (SignalThresholdInfo info : record.mRequest.getSignalThresholdInfos()) {
+                if (isRanAndSignalMeasurementTypeMatch(ran, measurement, info)) {
+                    for (int appThreshold : info.getThresholds()) {
+                        target.add(appThreshold);
+                    }
+                }
+            }
+        }
+
+        int[] targetArray = new int[target.size()];
+        int i = 0;
+        for (int element : target) {
+            targetArray[i++] = element;
+        }
+        return targetArray;
+    }
+
+    boolean shouldHonorSystemThresholds() {
+        if (!mPhone.isDeviceIdle()) {
+            return true;
+        }
+
+        final int curSubId = mPhone.getSubId();
+        return mSignalRequestRecords.stream().anyMatch(
+                srr -> curSubId == srr.mSubId
+                        && srr.mRequest.isSystemThresholdReportingRequestedWhileIdle());
+    }
+
+    void onDeviceIdleStateChanged(boolean isDeviceIdle) {
+        sendMessage(obtainMessage(EVENT_ON_DEVICE_IDLE_STATE_CHANGED, isDeviceIdle));
+    }
+
+    boolean shouldEnableSignalThresholdForAppRequest(
+            @AccessNetworkConstants.RadioAccessNetworkType int ran,
+            @SignalThresholdInfo.SignalMeasurementType int measurement,
+            int subId,
+            boolean isDeviceIdle) {
+        for (SignalRequestRecord record : mSignalRequestRecords) {
+            if (subId != record.mSubId) {
+                continue;
+            }
+            for (SignalThresholdInfo info : record.mRequest.getSignalThresholdInfos()) {
+                if (isRanAndSignalMeasurementTypeMatch(ran, measurement, info)
+                        && (!isDeviceIdle || isSignalReportRequestedWhileIdle(record.mRequest))) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static boolean isRanAndSignalMeasurementTypeMatch(
+            @AccessNetworkConstants.RadioAccessNetworkType int ran,
+            @SignalThresholdInfo.SignalMeasurementType int measurement,
+            SignalThresholdInfo info) {
+        return ran == info.getRadioAccessNetworkType()
+                && measurement == info.getSignalMeasurementType();
+    }
+
+    private static boolean isSignalReportRequestedWhileIdle(SignalStrengthUpdateRequest request) {
+        return request.isSystemThresholdReportingRequestedWhileIdle()
+                || request.isReportingRequestedWhileIdle();
+    }
+
+    private class SignalRequestRecord implements IBinder.DeathRecipient {
+        final int mSubId; // subId the request originally applied to
+        final int mCallingUid;
+        final SignalStrengthUpdateRequest mRequest;
+
+        SignalRequestRecord(int subId, int uid, @NonNull SignalStrengthUpdateRequest request) {
+            this.mCallingUid = uid;
+            this.mSubId = subId;
+            this.mRequest = request;
+        }
+
+        @Override
+        public void binderDied() {
+            clearSignalStrengthUpdateRequest(mSubId, mCallingUid, mRequest, null /*onCompleted*/);
+        }
+    }
+
+    private void updateAlwaysReportSignalStrength() {
+        final int curSubId = mPhone.getSubId();
+        boolean alwaysReport = mSignalRequestRecords.stream().anyMatch(
+                srr -> srr.mSubId == curSubId && isSignalReportRequestedWhileIdle(srr.mRequest));
+
+        // TODO(b/177924721): TM#setAlwaysReportSignalStrength will be removed and we will not
+        // worry about unset flag which was set by other client.
+        mPhone.setAlwaysReportSignalStrength(alwaysReport);
+    }
+
+    /**
      * Registers for TAC/LAC changed event.
      * @param h handler to notify
      * @param what what code of message when delivered
@@ -6033,16 +6427,4 @@
     public void unregisterForAreaCodeChanged(Handler h) {
         mAreaCodeChangedRegistrants.remove(h);
     }
-
-    /**
-     * get last known cell identity
-     * If there is current registered network this value will be same as the registered cell
-     * identity. If the device goes out of service the previous cell identity is cached and
-     * will be returned. If the cache age of the cell identity is more than 24 hours
-     * it will be cleared and null will be returned.
-     * @return last known cell identity.
-     */
-    public @Nullable CellIdentity getLastKnownCellIdentity() {
-        return mLastKnownCellIdentity;
-    }
 }
diff --git a/src/java/com/android/internal/telephony/SignalStrengthController.java b/src/java/com/android/internal/telephony/SignalStrengthController.java
deleted file mode 100644
index fc378a2..0000000
--- a/src/java/com/android/internal/telephony/SignalStrengthController.java
+++ /dev/null
@@ -1,1115 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.PersistableBundle;
-import android.os.RemoteException;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.CarrierConfigManager;
-import android.telephony.CellIdentity;
-import android.telephony.CellIdentityLte;
-import android.telephony.CellIdentityNr;
-import android.telephony.CellInfo;
-import android.telephony.CellSignalStrengthLte;
-import android.telephony.CellSignalStrengthNr;
-import android.telephony.ServiceState;
-import android.telephony.SignalStrength;
-import android.telephony.SignalStrengthUpdateRequest;
-import android.telephony.SignalThresholdInfo;
-import android.telephony.SubscriptionInfo;
-import android.telephony.TelephonyManager;
-import android.util.LocalLog;
-import android.util.Pair;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.util.ArrayUtils;
-import com.android.internal.util.IndentingPrintWriter;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.PatternSyntaxException;
-
-/**
- * SignalStrengthController handles signal polling request and unsolicited signal strength update.
- */
-public class SignalStrengthController extends Handler {
-    private static final boolean DBG = false; /* STOPSHIP if true */
-    private static final String TAG = "SSCtr";
-
-    private static final long SIGNAL_STRENGTH_REFRESH_THRESHOLD_IN_MS =
-            TimeUnit.SECONDS.toMillis(10);
-    /** Signal strength poll rate. */
-    private static final long POLL_PERIOD_MILLIS = TimeUnit.SECONDS.toMillis(20);
-    private static final int INVALID_ARFCN = -1;
-
-    /** Required magnitude change between unsolicited SignalStrength reports. */
-    private static final int REPORTING_HYSTERESIS_DB = 2;
-    /** Minimum time between unsolicited SignalStrength reports. */
-    private static final int REPORTING_HYSTERESIS_MILLIS = 3000;
-    /**
-     * A threshold within which (inclusive) the application requested signal strength
-     * thresholds will be aligned with threholds set in advance (by system or other apps).
-     * Since the alignment applies to both directions, the value is set to halt of
-     * REPORTING_HYSTERESIS_DB to respect it while without introducing additional gaps for
-     * thresholds set by apps.
-     */
-    private static final int ALIGNMENT_HYSTERESIS_DB = 1;
-
-    private static final int EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST       = 1;
-    private static final int EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST     = 2;
-    private static final int EVENT_ON_DEVICE_IDLE_STATE_CHANGED             = 3;
-    private static final int EVENT_RIL_CONNECTED                            = 4;
-    private static final int EVENT_RADIO_AVAILABLE                          = 5;
-    private static final int EVENT_GET_SIGNAL_STRENGTH                      = 6;
-    private static final int EVENT_POLL_SIGNAL_STRENGTH                     = 7;
-    private static final int EVENT_SIGNAL_STRENGTH_UPDATE                   = 8;
-    private static final int EVENT_POLL_SIGNAL_STRENGTH_DONE                = 9;
-    private static final int EVENT_CARRIER_CONFIG_CHANGED                   = 10;
-
-    @NonNull
-    private final Phone mPhone;
-    @NonNull
-    private final CommandsInterface mCi;
-
-    @NonNull
-    private SignalStrength mSignalStrength;
-    private long mSignalStrengthUpdatedTime;
-    @Nullable
-    private SignalStrength mLastSignalStrength = null;
-
-    /**
-     * List of LTE EARFCNs (E-UTRAN Absolute Radio Frequency Channel Number,
-     * Reference: 3GPP TS 36.104 5.4.3)
-     * inclusive ranges for which the lte rsrp boost is applied
-     */
-    @Nullable
-    private ArrayList<Pair<Integer, Integer>> mEarfcnPairListForRsrpBoost = null;
-    /**
-     * Offset which is reduced from the rsrp threshold while calculating signal strength level.
-     */
-    private int mLteRsrpBoost = 0;
-    /**
-     * Ranges of NR ARFCNs (5G Absolute Radio Frequency Channel Number,
-     * Reference: 3GPP TS 38.104)
-     * inclusive ranges for which the corresponding nr rsrp boost is applied
-     */
-    @Nullable
-    private ArrayList<Pair<Integer, Integer>> mNrarfcnRangeListForRsrpBoost = null;
-    @Nullable
-    private int[] mNrRsrpBoost = null;
-    @NonNull
-    private final Object mRsrpBoostLock = new Object();
-
-    @NonNull
-    private final List<SignalRequestRecord> mSignalRequestRecords = new ArrayList<>();
-
-    @NonNull
-    private PersistableBundle mCarrierConfig;
-
-    @NonNull
-    private final LocalLog mLocalLog = new LocalLog(64);
-
-    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)) {
-                int phoneId = intent.getExtras().getInt(CarrierConfigManager.EXTRA_SLOT_INDEX);
-                // Ignore the carrier config changed if the phoneId is not matched.
-                if (phoneId == mPhone.getPhoneId()) {
-                    sendEmptyMessage(EVENT_CARRIER_CONFIG_CHANGED);
-                }
-            }
-        }
-    };
-
-    public SignalStrengthController(@NonNull Phone phone) {
-        mPhone = phone;
-        mCi = mPhone.mCi;
-
-        mCi.registerForRilConnected(this, EVENT_RIL_CONNECTED, null);
-        mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null);
-        mCi.setOnSignalStrengthUpdate(this, EVENT_SIGNAL_STRENGTH_UPDATE, null);
-        setSignalStrengthDefaultValues();
-
-        mCarrierConfig = getCarrierConfig();
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        mPhone.getContext().registerReceiver(mBroadcastReceiver, filter);
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        if (DBG) log("received event " + msg.what);
-        AsyncResult ar;
-
-        switch (msg.what) {
-            case EVENT_RIL_CONNECTED: // fall through
-            case EVENT_RADIO_AVAILABLE:
-                onReset();
-                break;
-            case EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST: {
-                Pair<SignalRequestRecord, Message> pair =
-                        (Pair<SignalRequestRecord, Message>) msg.obj;
-                SignalRequestRecord record = pair.first;
-                Message onCompleted = pair.second;
-                AsyncResult ret = AsyncResult.forMessage(onCompleted);
-
-                // TODO(b/177956310): Check subId to filter out old request until a better solution
-                boolean dupRequest = mSignalRequestRecords.stream().anyMatch(
-                        srr -> srr.mCallingUid == record.mCallingUid
-                                && srr.mSubId == record.mSubId);
-                if (dupRequest) {
-                    ret.exception = new IllegalStateException(
-                            "setSignalStrengthUpdateRequest called again with same subId");
-                    onCompleted.sendToTarget();
-                    break;
-                }
-
-                try {
-                    record.mRequest.getLiveToken().linkToDeath(record, 0);
-                } catch (RemoteException | NullPointerException ex) {
-                    ret.exception = new IllegalStateException(
-                            "Signal request client is already dead.");
-                    onCompleted.sendToTarget();
-                    break;
-                }
-
-                mSignalRequestRecords.add(record);
-
-                updateAlwaysReportSignalStrength();
-                updateReportingCriteria();
-
-                onCompleted.sendToTarget();
-                break;
-            }
-
-            case EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST: {
-                Pair<SignalRequestRecord, Message> pair =
-                        (Pair<SignalRequestRecord, Message>) msg.obj;
-                SignalRequestRecord record = pair.first;
-                Message onCompleted = pair.second;
-
-                // for loop with removal may cause ConcurrentModificationException
-                Iterator<SignalRequestRecord> it = mSignalRequestRecords.iterator();
-                while (it.hasNext()) {
-                    SignalRequestRecord srr = it.next();
-                    if (srr.mRequest.getLiveToken().equals(record.mRequest.getLiveToken())) {
-                        it.remove();
-                    }
-                }
-
-                updateAlwaysReportSignalStrength();
-                updateReportingCriteria();
-
-                if (onCompleted != null) {
-                    AsyncResult ret = AsyncResult.forMessage(onCompleted);
-                    onCompleted.sendToTarget();
-                }
-                break;
-            }
-
-            case EVENT_ON_DEVICE_IDLE_STATE_CHANGED: {
-                updateReportingCriteria();
-                break;
-            }
-
-            case EVENT_POLL_SIGNAL_STRENGTH_DONE: // fall through
-            case EVENT_GET_SIGNAL_STRENGTH: {
-                // This callback is called when signal strength is polled
-                // all by itself
-
-                if (!(mCi.getRadioState() == TelephonyManager.RADIO_POWER_ON)) {
-                    // Polling will continue when radio turns back on
-                    return;
-                }
-                ar = (AsyncResult) msg.obj;
-                onSignalStrengthResult(ar);
-                break;
-            }
-
-            case EVENT_POLL_SIGNAL_STRENGTH: {
-                // Just poll signal strength...not part of pollState()
-
-                mCi.getSignalStrength(obtainMessage(EVENT_POLL_SIGNAL_STRENGTH_DONE));
-                break;
-            }
-
-            case EVENT_SIGNAL_STRENGTH_UPDATE: {
-                // This is a notification from CommandsInterface.setOnSignalStrengthUpdate
-
-                ar = (AsyncResult) msg.obj;
-                onSignalStrengthResult(ar);
-                break;
-            }
-
-            case EVENT_CARRIER_CONFIG_CHANGED: {
-                onCarrierConfigChanged();
-                break;
-            }
-
-            default:
-                log("Unhandled message with number: " + msg.what);
-                break;
-        }
-    }
-
-    void dispose() {
-        mCi.unSetOnSignalStrengthUpdate(this);
-    }
-
-    /**
-     * Called when RIL is connected during boot up or after modem restart. Set the default criteria
-     * so that modem can start with default state before updated criteria is ready.
-     */
-    private void onReset() {
-        setDefaultSignalStrengthReportingCriteria();
-    }
-
-    void getSignalStrengthFromCi() {
-        mCi.getSignalStrength(obtainMessage(EVENT_GET_SIGNAL_STRENGTH));
-    }
-
-    /**
-     * send signal-strength-changed notification if changed Called both for
-     * solicited and unsolicited signal strength updates
-     *
-     * @return true if the signal strength changed and a notification was sent.
-     */
-    private boolean onSignalStrengthResult(@NonNull AsyncResult ar) {
-
-        // This signal is used for both voice and data radio signal so parse
-        // all fields
-
-        if ((ar.exception == null) && (ar.result != null)) {
-            mSignalStrength = (SignalStrength) ar.result;
-
-            if (mPhone.getServiceStateTracker() != null) {
-                mSignalStrength.updateLevel(mCarrierConfig, mPhone.getServiceStateTracker().mSS);
-            }
-        } else {
-            log("onSignalStrengthResult() Exception from RIL : " + ar.exception);
-            mSignalStrength = new SignalStrength();
-        }
-        mSignalStrengthUpdatedTime = System.currentTimeMillis();
-
-        boolean ssChanged = notifySignalStrength();
-
-        return ssChanged;
-    }
-
-    /**
-     * @return signal strength
-     */
-    @NonNull
-    public SignalStrength getSignalStrength() {
-        if (shouldRefreshSignalStrength()) {
-            log("getSignalStrength() refreshing signal strength.");
-            obtainMessage(EVENT_POLL_SIGNAL_STRENGTH).sendToTarget();
-        }
-        return mSignalStrength;
-    }
-
-    private boolean shouldRefreshSignalStrength() {
-        long curTime = System.currentTimeMillis();
-
-        // If last signal strength is older than 10 seconds, or somehow if curTime is smaller
-        // than mSignalStrengthUpdatedTime (system time update), it's considered stale.
-        boolean isStale = (mSignalStrengthUpdatedTime > curTime)
-                || (curTime - mSignalStrengthUpdatedTime > SIGNAL_STRENGTH_REFRESH_THRESHOLD_IN_MS);
-        if (!isStale) return false;
-
-        List<SubscriptionInfo> subInfoList = SubscriptionController.getInstance()
-                .getActiveSubscriptionInfoList(mPhone.getContext().getOpPackageName(),
-                        mPhone.getContext().getAttributionTag());
-
-        if (!ArrayUtils.isEmpty(subInfoList)) {
-            for (SubscriptionInfo info : subInfoList) {
-                // If we have an active opportunistic subscription whose data is IN_SERVICE,
-                // we need to get signal strength to decide data switching threshold. In this case,
-                // we poll latest signal strength from modem.
-                if (info.isOpportunistic()) {
-                    TelephonyManager tm = TelephonyManager.from(mPhone.getContext())
-                            .createForSubscriptionId(info.getSubscriptionId());
-                    ServiceState ss = tm.getServiceState();
-                    if (ss != null
-                            && ss.getDataRegistrationState() == ServiceState.STATE_IN_SERVICE) {
-                        return true;
-                    }
-                }
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Update signal strength reporting criteria from the carrier config
-     */
-    @VisibleForTesting
-    public void updateReportingCriteria() {
-        List<SignalThresholdInfo> signalThresholdInfos = new ArrayList<>();
-
-        int[] gsmRssiThresholds = mCarrierConfig.getIntArray(
-                CarrierConfigManager.KEY_GSM_RSSI_THRESHOLDS_INT_ARRAY);
-        if (gsmRssiThresholds != null) {
-            signalThresholdInfos.add(
-                    createSignalThresholdsInfo(
-                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
-                            gsmRssiThresholds,
-                            AccessNetworkConstants.AccessNetworkType.GERAN,
-                            true));
-        }
-
-        int[] wcdmaRscpThresholds = mCarrierConfig.getIntArray(
-                CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY);
-        if (wcdmaRscpThresholds != null) {
-            signalThresholdInfos.add(
-                    createSignalThresholdsInfo(
-                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP,
-                            wcdmaRscpThresholds,
-                            AccessNetworkConstants.AccessNetworkType.UTRAN,
-                            true));
-        }
-
-        int lteMeasurementEnabled = mCarrierConfig.getInt(CarrierConfigManager
-                .KEY_PARAMETERS_USED_FOR_LTE_SIGNAL_BAR_INT, CellSignalStrengthLte.USE_RSRP);
-        int[] lteRsrpThresholds = mCarrierConfig.getIntArray(
-                CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY);
-        if (lteRsrpThresholds != null) {
-            signalThresholdInfos.add(
-                    createSignalThresholdsInfo(
-                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
-                            lteRsrpThresholds,
-                            AccessNetworkConstants.AccessNetworkType.EUTRAN,
-                            (lteMeasurementEnabled & CellSignalStrengthLte.USE_RSRP) != 0));
-        }
-
-        if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            int[] lteRsrqThresholds = mCarrierConfig.getIntArray(
-                    CarrierConfigManager.KEY_LTE_RSRQ_THRESHOLDS_INT_ARRAY);
-            if (lteRsrqThresholds != null) {
-                signalThresholdInfos.add(
-                        createSignalThresholdsInfo(
-                                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
-                                lteRsrqThresholds,
-                                AccessNetworkConstants.AccessNetworkType.EUTRAN,
-                                (lteMeasurementEnabled & CellSignalStrengthLte.USE_RSRQ) != 0));
-            }
-
-            int[] lteRssnrThresholds = mCarrierConfig.getIntArray(
-                    CarrierConfigManager.KEY_LTE_RSSNR_THRESHOLDS_INT_ARRAY);
-            if (lteRssnrThresholds != null) {
-                signalThresholdInfos.add(
-                        createSignalThresholdsInfo(
-                                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR,
-                                lteRssnrThresholds,
-                                AccessNetworkConstants.AccessNetworkType.EUTRAN,
-                                (lteMeasurementEnabled & CellSignalStrengthLte.USE_RSSNR) != 0));
-            }
-
-            int nrMeasurementEnabled = mCarrierConfig.getInt(CarrierConfigManager
-                    .KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT, CellSignalStrengthNr.USE_SSRSRP);
-            int[] nrSsrsrpThresholds = mCarrierConfig.getIntArray(
-                    CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY);
-            if (nrSsrsrpThresholds != null) {
-                signalThresholdInfos.add(
-                        createSignalThresholdsInfo(
-                                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
-                                nrSsrsrpThresholds,
-                                AccessNetworkConstants.AccessNetworkType.NGRAN,
-                                (nrMeasurementEnabled & CellSignalStrengthNr.USE_SSRSRP) != 0));
-            }
-
-            int[] nrSsrsrqThresholds = mCarrierConfig.getIntArray(
-                    CarrierConfigManager.KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY);
-            if (nrSsrsrqThresholds != null) {
-                signalThresholdInfos.add(
-                        createSignalThresholdsInfo(
-                                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
-                                nrSsrsrqThresholds,
-                                AccessNetworkConstants.AccessNetworkType.NGRAN,
-                                (nrMeasurementEnabled & CellSignalStrengthNr.USE_SSRSRQ) != 0));
-            }
-
-            int[] nrSssinrThresholds = mCarrierConfig.getIntArray(
-                    CarrierConfigManager.KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY);
-            if (nrSssinrThresholds != null) {
-                signalThresholdInfos.add(
-                        createSignalThresholdsInfo(
-                                SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR,
-                                nrSssinrThresholds,
-                                AccessNetworkConstants.AccessNetworkType.NGRAN,
-                                (nrMeasurementEnabled & CellSignalStrengthNr.USE_SSSINR) != 0));
-            }
-        }
-
-        consolidatedAndSetReportingCriteria(signalThresholdInfos);
-    }
-
-    private void setDefaultSignalStrengthReportingCriteria() {
-        List<SignalThresholdInfo> signalThresholdInfos = new ArrayList<>();
-
-        signalThresholdInfos.add(
-                createSignalThresholdsInfo(
-                        SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
-                        AccessNetworkThresholds.GERAN,
-                        AccessNetworkConstants.AccessNetworkType.GERAN,
-                        true));
-        signalThresholdInfos.add(
-                createSignalThresholdsInfo(
-                        SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP,
-                        AccessNetworkThresholds.UTRAN,
-                        AccessNetworkConstants.AccessNetworkType.UTRAN,
-                        true));
-        signalThresholdInfos.add(
-                createSignalThresholdsInfo(
-                        SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP,
-                        AccessNetworkThresholds.EUTRAN_RSRP,
-                        AccessNetworkConstants.AccessNetworkType.EUTRAN,
-                        true));
-        signalThresholdInfos.add(
-                createSignalThresholdsInfo(
-                        SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI,
-                        AccessNetworkThresholds.CDMA2000,
-                        AccessNetworkConstants.AccessNetworkType.CDMA2000,
-                        true));
-
-        if (mPhone.getHalVersion().greaterOrEqual(RIL.RADIO_HAL_VERSION_1_5)) {
-            signalThresholdInfos.add(
-                    createSignalThresholdsInfo(
-                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ,
-                            AccessNetworkThresholds.EUTRAN_RSRQ,
-                            AccessNetworkConstants.AccessNetworkType.EUTRAN,
-                            false));
-            signalThresholdInfos.add(
-                    createSignalThresholdsInfo(
-                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSNR,
-                            AccessNetworkThresholds.EUTRAN_RSSNR,
-                            AccessNetworkConstants.AccessNetworkType.EUTRAN,
-                            true));
-
-            // Defaultly we only need SSRSRP for NGRAN signal criteria reporting
-            signalThresholdInfos.add(
-                    createSignalThresholdsInfo(
-                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRP,
-                            AccessNetworkThresholds.NGRAN_SSRSRP,
-                            AccessNetworkConstants.AccessNetworkType.NGRAN,
-                            true));
-            signalThresholdInfos.add(
-                    createSignalThresholdsInfo(
-                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
-                            AccessNetworkThresholds.NGRAN_SSRSRQ,
-                            AccessNetworkConstants.AccessNetworkType.NGRAN,
-                            false));
-            signalThresholdInfos.add(
-                    createSignalThresholdsInfo(
-                            SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR,
-                            AccessNetworkThresholds.NGRAN_SSSINR,
-                            AccessNetworkConstants.AccessNetworkType.NGRAN,
-                            false));
-        }
-
-        consolidatedAndSetReportingCriteria(signalThresholdInfos);
-    }
-
-    private void consolidatedAndSetReportingCriteria(
-            @NonNull List<SignalThresholdInfo> signalThresholdInfos) {
-        List<SignalThresholdInfo> consolidatedSignalThresholdInfos = new ArrayList<>(
-                signalThresholdInfos.size());
-        for (SignalThresholdInfo signalThresholdInfo : signalThresholdInfos) {
-            final int ran = signalThresholdInfo.getRadioAccessNetworkType();
-            final int measurementType = signalThresholdInfo.getSignalMeasurementType();
-            final boolean isEnabledForSystem = signalThresholdInfo.isEnabled();
-            int[] consolidatedThresholds =
-                    getConsolidatedSignalThresholds(
-                            ran,
-                            measurementType,
-                            isEnabledForSystem && shouldHonorSystemThresholds()
-                                    ? signalThresholdInfo.getThresholds()
-                                    : new int[]{},
-                            ALIGNMENT_HYSTERESIS_DB);
-            boolean isEnabledForAppRequest =
-                    shouldEnableSignalThresholdForAppRequest(
-                            ran,
-                            measurementType,
-                            mPhone.getSubId(),
-                            mPhone.isDeviceIdle());
-            consolidatedSignalThresholdInfos.add(
-                    new SignalThresholdInfo.Builder()
-                            .setRadioAccessNetworkType(ran)
-                            .setSignalMeasurementType(measurementType)
-                            .setHysteresisMs(REPORTING_HYSTERESIS_MILLIS)
-                            .setHysteresisDb(REPORTING_HYSTERESIS_DB)
-                            .setThresholds(consolidatedThresholds, true /*isSystem*/)
-                            .setIsEnabled(isEnabledForSystem || isEnabledForAppRequest)
-                            .build());
-        }
-        mCi.setSignalStrengthReportingCriteria(consolidatedSignalThresholdInfos, null);
-
-        localLog("setSignalStrengthReportingCriteria consolidatedSignalThresholdInfos="
-                        + consolidatedSignalThresholdInfos);
-    }
-
-    void setSignalStrengthDefaultValues() {
-        mSignalStrength = new SignalStrength();
-        mSignalStrengthUpdatedTime = System.currentTimeMillis();
-    }
-
-    boolean notifySignalStrength() {
-        boolean notified = false;
-        if (!mSignalStrength.equals(mLastSignalStrength)) {
-            try {
-                mPhone.notifySignalStrength();
-                notified = true;
-                mLastSignalStrength = mSignalStrength;
-            } catch (NullPointerException ex) {
-                log("updateSignalStrength() Phone already destroyed: " + ex
-                        + "SignalStrength not notified");
-            }
-        }
-        return notified;
-    }
-
-    /**
-     * Print the SignalStrengthController states into the given stream.
-     *
-     * @param fd The raw file descriptor that the dump is being sent to.
-     * @param pw A PrintWriter to which the dump is to be set.
-     * @param args Additional arguments to the dump request.
-     */
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("SignalStrengthController - phoneId: " + mPhone.getPhoneId());
-        pw.println("SignalStrengthController - Log Begin ----");
-        mLocalLog.dump(fd, pw, args);
-        pw.println("SignalStrengthController - Log End ----");
-
-        final IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
-        ipw.increaseIndent();
-        pw.println("mSignalRequestRecords=" + mSignalRequestRecords);
-        pw.println(" mLastSignalStrength=" + mLastSignalStrength);
-        pw.println(" mSignalStrength=" + mSignalStrength);
-        pw.println(" mLteRsrpBoost=" + mLteRsrpBoost);
-        pw.println(" mNrRsrpBoost=" + Arrays.toString(mNrRsrpBoost));
-        pw.println(" mEarfcnPairListForRsrpBoost=" + mEarfcnPairListForRsrpBoost);
-        pw.println(" mNrarfcnRangeListForRsrpBoost=" + mNrarfcnRangeListForRsrpBoost);
-        ipw.decreaseIndent();
-        ipw.flush();
-    }
-
-    /**
-     * Set a new request to update the signal strength thresholds.
-     */
-    public void setSignalStrengthUpdateRequest(int subId, int callingUid,
-            @NonNull SignalStrengthUpdateRequest request, @NonNull Message onCompleted) {
-        SignalRequestRecord record = new SignalRequestRecord(subId, callingUid, request);
-        sendMessage(obtainMessage(EVENT_SET_SIGNAL_STRENGTH_UPDATE_REQUEST,
-                new Pair<SignalRequestRecord, Message>(record, onCompleted)));
-
-        localLog("setSignalStrengthUpdateRequest"
-                + " subId=" + subId
-                + " callingUid=" + callingUid
-                + " request=" + request);
-    }
-
-    /**
-     * Clear the previously set request.
-     */
-    public void clearSignalStrengthUpdateRequest(int subId, int callingUid,
-            @NonNull SignalStrengthUpdateRequest request, @Nullable Message onCompleted) {
-        SignalRequestRecord record = new SignalRequestRecord(subId, callingUid, request);
-        sendMessage(obtainMessage(EVENT_CLEAR_SIGNAL_STRENGTH_UPDATE_REQUEST,
-                new Pair<SignalRequestRecord, Message>(record, onCompleted)));
-
-        localLog("clearSignalStrengthUpdateRequest"
-                + " subId=" + subId
-                + " callingUid=" + callingUid
-                + " request=" + request);
-    }
-
-    /**
-     * Align all the qualified thresholds set from applications to the {@code systemThresholds}
-     * and consolidate a new thresholds array, follow rules below:
-     * 1. All threshold values (whose interval is guaranteed to be larger than hysteresis) in
-     *    {@code systemThresholds} will keep as it.
-     * 2. Any threshold from apps that has interval less than hysteresis from any threshold in
-     *    {@code systemThresholds} will be removed.
-     * 3. The target thresholds will be {@code systemThresholds} + all qualified thresholds from
-     *    apps, sorted in ascending order.
-     */
-    @VisibleForTesting
-    @NonNull
-    public int[] getConsolidatedSignalThresholds(int ran, int measurement,
-            @Nullable int[] systemThresholds, int hysteresis) {
-
-        // TreeSet with comparator that will filter element with interval less than hysteresis
-        // from any current element
-        Set<Integer> target = new TreeSet<>((x, y) -> {
-            if (y >= x - hysteresis && y <= x + hysteresis) {
-                return 0;
-            }
-            return Integer.compare(x, y);
-        });
-
-        if (systemThresholds != null) {
-            for (int systemThreshold : systemThresholds) {
-                target.add(systemThreshold);
-            }
-        }
-
-        final boolean isDeviceIdle = mPhone.isDeviceIdle();
-        final int curSubId = mPhone.getSubId();
-        // The total number of record is small (10~15 tops). With each request has at most 5
-        // SignalThresholdInfo which has at most 8 thresholds arrays. So the nested loop should
-        // not be a concern here.
-        for (SignalRequestRecord record : mSignalRequestRecords) {
-            if (curSubId != record.mSubId
-                    || (isDeviceIdle && !record.mRequest.isReportingRequestedWhileIdle())) {
-                continue;
-            }
-            for (SignalThresholdInfo info : record.mRequest.getSignalThresholdInfos()) {
-                if (isRanAndSignalMeasurementTypeMatch(ran, measurement, info)) {
-                    for (int appThreshold : info.getThresholds()) {
-                        target.add(appThreshold);
-                    }
-                }
-            }
-        }
-
-        int[] targetArray = new int[target.size()];
-        int i = 0;
-        for (int element : target) {
-            targetArray[i++] = element;
-        }
-        return targetArray;
-    }
-
-    /**
-     * Return true if system thresholds should be honored when consolidating.
-     */
-    @VisibleForTesting
-    public boolean shouldHonorSystemThresholds() {
-        if (!mPhone.isDeviceIdle()) {
-            return true;
-        }
-
-        final int curSubId = mPhone.getSubId();
-        return mSignalRequestRecords.stream().anyMatch(
-                srr -> curSubId == srr.mSubId
-                        && srr.mRequest.isSystemThresholdReportingRequestedWhileIdle());
-    }
-
-    void onDeviceIdleStateChanged(boolean isDeviceIdle) {
-        sendMessage(obtainMessage(EVENT_ON_DEVICE_IDLE_STATE_CHANGED, isDeviceIdle));
-
-        localLog("onDeviceIdleStateChanged isDeviceIdle=" + isDeviceIdle);
-    }
-
-    /**
-     * Return true if signal threshold should be enabled due to the apps requests.
-     */
-    @VisibleForTesting
-    public boolean shouldEnableSignalThresholdForAppRequest(
-            @AccessNetworkConstants.RadioAccessNetworkType int ran,
-            @SignalThresholdInfo.SignalMeasurementType int measurement,
-            int subId,
-            boolean isDeviceIdle) {
-        for (SignalRequestRecord record : mSignalRequestRecords) {
-            if (subId != record.mSubId) {
-                continue;
-            }
-            for (SignalThresholdInfo info : record.mRequest.getSignalThresholdInfos()) {
-                if (isRanAndSignalMeasurementTypeMatch(ran, measurement, info)
-                        && (!isDeviceIdle || isSignalReportRequestedWhileIdle(record.mRequest))) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private static boolean isRanAndSignalMeasurementTypeMatch(
-            @AccessNetworkConstants.RadioAccessNetworkType int ran,
-            @SignalThresholdInfo.SignalMeasurementType int measurement,
-            @NonNull SignalThresholdInfo info) {
-        return ran == info.getRadioAccessNetworkType()
-                && measurement == info.getSignalMeasurementType();
-    }
-
-    private static boolean isSignalReportRequestedWhileIdle(
-            @NonNull SignalStrengthUpdateRequest request) {
-        return request.isSystemThresholdReportingRequestedWhileIdle()
-                || request.isReportingRequestedWhileIdle();
-    }
-
-    /**
-     * Gets the carrier configuration values for a particular subscription.
-     *
-     * @return A {@link PersistableBundle} containing the config for the given subId,
-     *         or default values for an invalid subId.
-     */
-    @NonNull
-    private PersistableBundle getCarrierConfig() {
-        CarrierConfigManager configManager = (CarrierConfigManager) mPhone.getContext()
-                .getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        if (configManager != null) {
-            // If an invalid subId is used, this bundle will contain default values.
-            PersistableBundle config = configManager.getConfigForSubId(mPhone.getSubId());
-            if (config != null) {
-                return config;
-            }
-        }
-        // Return static default defined in CarrierConfigManager.
-        return CarrierConfigManager.getDefaultConfig();
-    }
-
-    private class SignalRequestRecord implements IBinder.DeathRecipient {
-        final int mSubId; // subId the request originally applied to
-        final int mCallingUid;
-        @NonNull
-        final SignalStrengthUpdateRequest mRequest;
-
-        SignalRequestRecord(int subId, int uid, @NonNull SignalStrengthUpdateRequest request) {
-            this.mCallingUid = uid;
-            this.mSubId = subId;
-            this.mRequest = request;
-        }
-
-        @Override
-        public void binderDied() {
-            localLog("binderDied record=" + this);
-            clearSignalStrengthUpdateRequest(mSubId, mCallingUid, mRequest, null /*onCompleted*/);
-        }
-
-        @Override
-        public String toString() {
-            StringBuffer sb = new StringBuffer("SignalRequestRecord {");
-            sb.append("mSubId=").append(mSubId);
-            sb.append(" mCallingUid=").append(mCallingUid);
-            sb.append(" mRequest=").append(mRequest).append("}");
-            return sb.toString();
-        }
-    }
-
-    private void updateAlwaysReportSignalStrength() {
-        final int curSubId = mPhone.getSubId();
-        boolean alwaysReport = mSignalRequestRecords.stream().anyMatch(
-                srr -> srr.mSubId == curSubId && isSignalReportRequestedWhileIdle(srr.mRequest));
-
-        // TODO(b/177924721): TM#setAlwaysReportSignalStrength will be removed and we will not
-        // worry about unset flag which was set by other client.
-        mPhone.setAlwaysReportSignalStrength(alwaysReport);
-    }
-
-    void updateArfcnLists() {
-        synchronized (mRsrpBoostLock) {
-            mLteRsrpBoost = mCarrierConfig.getInt(
-                    CarrierConfigManager.KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0);
-            String[] earfcnsStringArrayForRsrpBoost = mCarrierConfig.getStringArray(
-                    CarrierConfigManager.KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY);
-            mEarfcnPairListForRsrpBoost = convertEarfcnStringArrayToPairList(
-                    earfcnsStringArrayForRsrpBoost);
-
-            mNrRsrpBoost = mCarrierConfig.getIntArray(
-                    CarrierConfigManager.KEY_NRARFCNS_RSRP_BOOST_INT_ARRAY);
-            String[] nrarfcnsStringArrayForRsrpBoost = mCarrierConfig.getStringArray(
-                    CarrierConfigManager.KEY_BOOSTED_NRARFCNS_STRING_ARRAY);
-            mNrarfcnRangeListForRsrpBoost = convertEarfcnStringArrayToPairList(
-                    nrarfcnsStringArrayForRsrpBoost);
-
-            if ((mNrRsrpBoost == null && mNrarfcnRangeListForRsrpBoost != null)
-                    || (mNrRsrpBoost != null && mNrarfcnRangeListForRsrpBoost == null)
-                    || (mNrRsrpBoost != null && mNrarfcnRangeListForRsrpBoost != null
-                    && mNrRsrpBoost.length != mNrarfcnRangeListForRsrpBoost.size())) {
-                loge("Invalid parameters for NR RSRP boost");
-                mNrRsrpBoost = null;
-                mNrarfcnRangeListForRsrpBoost = null;
-            }
-        }
-    }
-
-    // package private access from ServiceStateTracker
-    // TODO(b/219572311): Maintains ArfcnRsrpBoost here only without forwarding by ServiceState
-    void updateServiceStateArfcnRsrpBoost(@NonNull ServiceState serviceState,
-            @Nullable CellIdentity cellIdentity) {
-        if (cellIdentity == null) return;
-
-        int rsrpBoost = 0;
-        int arfcn;
-
-        synchronized (mRsrpBoostLock) {
-            switch (cellIdentity.getType()) {
-                case CellInfo.TYPE_LTE:
-                    arfcn = ((CellIdentityLte) cellIdentity).getEarfcn();
-                    if (arfcn != INVALID_ARFCN
-                            && containsEarfcnInEarfcnRange(mEarfcnPairListForRsrpBoost,
-                            arfcn) != -1) {
-                        rsrpBoost = mLteRsrpBoost;
-                    }
-                    break;
-                case CellInfo.TYPE_NR:
-                    arfcn = ((CellIdentityNr) cellIdentity).getNrarfcn();
-                    if (arfcn != INVALID_ARFCN) {
-                        int index = containsEarfcnInEarfcnRange(mNrarfcnRangeListForRsrpBoost,
-                                arfcn);
-                        if (index != -1 && mNrRsrpBoost != null) {
-                            rsrpBoost = mNrRsrpBoost[index];
-                        }
-                    }
-                    break;
-                default:
-                    break;
-            }
-        }
-        serviceState.setArfcnRsrpBoost(rsrpBoost);
-    }
-
-    /**
-     * Checks if the provided earfcn falls within the range of earfcns.
-     *
-     * return int index in earfcnPairList if earfcn falls within the provided range; -1 otherwise.
-     */
-    private static int containsEarfcnInEarfcnRange(
-            @Nullable ArrayList<Pair<Integer, Integer>> earfcnPairList, int earfcn) {
-        int index = 0;
-        if (earfcnPairList != null) {
-            for (Pair<Integer, Integer> earfcnPair : earfcnPairList) {
-                if ((earfcn >= earfcnPair.first) && (earfcn <= earfcnPair.second)) {
-                    return index;
-                }
-                index++;
-            }
-        }
-
-        return -1;
-    }
-
-    /**
-     * Convert the earfcnStringArray to list of pairs.
-     *
-     * Format of the earfcnsList is expected to be {"erafcn1_start-earfcn1_end",
-     * "earfcn2_start-earfcn2_end" ... }
-     */
-    @Nullable
-    private static ArrayList<Pair<Integer, Integer>> convertEarfcnStringArrayToPairList(
-            @Nullable String[] earfcnsList) {
-        ArrayList<Pair<Integer, Integer>> earfcnPairList = new ArrayList<Pair<Integer, Integer>>();
-
-        if (earfcnsList != null) {
-            int earfcnStart;
-            int earfcnEnd;
-            for (int i = 0; i < earfcnsList.length; i++) {
-                try {
-                    String[] earfcns = earfcnsList[i].split("-");
-                    if (earfcns.length != 2) {
-                        if (DBG) {
-                            log("Invalid earfcn range format");
-                        }
-                        return null;
-                    }
-
-                    earfcnStart = Integer.parseInt(earfcns[0]);
-                    earfcnEnd = Integer.parseInt(earfcns[1]);
-
-                    if (earfcnStart > earfcnEnd) {
-                        if (DBG) {
-                            log("Invalid earfcn range format");
-                        }
-                        return null;
-                    }
-
-                    earfcnPairList.add(new Pair<Integer, Integer>(earfcnStart, earfcnEnd));
-                } catch (PatternSyntaxException pse) {
-                    if (DBG) {
-                        log("Invalid earfcn range format");
-                    }
-                    return null;
-                } catch (NumberFormatException nfe) {
-                    if (DBG) {
-                        log("Invalid earfcn number format");
-                    }
-                    return null;
-                }
-            }
-        }
-
-        return earfcnPairList;
-    }
-
-    private void onCarrierConfigChanged() {
-        mCarrierConfig = getCarrierConfig();
-        log("Carrier Config changed.");
-
-        updateArfcnLists();
-        updateReportingCriteria();
-    }
-
-    private static SignalThresholdInfo createSignalThresholdsInfo(
-            int measurementType, @NonNull int[] thresholds, int ran, boolean isEnabled) {
-        return new SignalThresholdInfo.Builder()
-                .setSignalMeasurementType(measurementType)
-                .setThresholds(thresholds)
-                .setRadioAccessNetworkType(ran)
-                .setIsEnabled(isEnabled)
-                .build();
-    }
-
-    /**
-     * dBm thresholds that correspond to changes in signal strength indications.
-     */
-    private static final class AccessNetworkThresholds {
-
-        /**
-         * List of dBm thresholds for GERAN {@link AccessNetworkConstants.AccessNetworkType}.
-         *
-         * Calculated from GSM asu level thresholds - TS 27.007 Sec 8.5
-         */
-        public static final int[] GERAN = new int[]{
-                -109,
-                -103,
-                -97,
-                -89,
-        };
-
-        /**
-         * List of default dBm thresholds for UTRAN
-         * {@link AccessNetworkConstants.AccessNetworkType}.
-         *
-         * These thresholds are taken from the WCDMA RSCP defaults in {@link CarrierConfigManager}.
-         * See TS 27.007 Sec 8.69.
-         */
-        public static final int[] UTRAN = new int[]{
-                -114, /* SIGNAL_STRENGTH_POOR */
-                -104, /* SIGNAL_STRENGTH_MODERATE */
-                -94,  /* SIGNAL_STRENGTH_GOOD */
-                -84   /* SIGNAL_STRENGTH_GREAT */
-        };
-
-        /**
-         * List of default dBm RSRP thresholds for EUTRAN
-         * {@link AccessNetworkConstants.AccessNetworkType}.
-         *
-         * These thresholds are taken from the LTE RSRP defaults in {@link CarrierConfigManager}.
-         */
-        public static final int[] EUTRAN_RSRP = new int[]{
-                -128, /* SIGNAL_STRENGTH_POOR */
-                -118, /* SIGNAL_STRENGTH_MODERATE */
-                -108, /* SIGNAL_STRENGTH_GOOD */
-                -98,  /* SIGNAL_STRENGTH_GREAT */
-        };
-
-        /**
-         * List of default dB RSRQ thresholds for EUTRAN
-         * {@link AccessNetworkConstants.AccessNetworkType}.
-         *
-         * These thresholds are taken from the LTE RSRQ defaults in {@link CarrierConfigManager}.
-         */
-        public static final int[] EUTRAN_RSRQ = new int[]{
-                -20,  /* SIGNAL_STRENGTH_POOR */
-                -17,  /* SIGNAL_STRENGTH_MODERATE */
-                -14,  /* SIGNAL_STRENGTH_GOOD */
-                -11   /* SIGNAL_STRENGTH_GREAT */
-        };
-
-        /**
-         * List of default dB RSSNR thresholds for EUTRAN
-         * {@link AccessNetworkConstants.AccessNetworkType}.
-         *
-         * These thresholds are taken from the LTE RSSNR defaults in {@link CarrierConfigManager}.
-         */
-        public static final int[] EUTRAN_RSSNR = new int[]{
-                -3,  /* SIGNAL_STRENGTH_POOR */
-                1,   /* SIGNAL_STRENGTH_MODERATE */
-                5,   /* SIGNAL_STRENGTH_GOOD */
-                13   /* SIGNAL_STRENGTH_GREAT */
-        };
-
-        /**
-         * List of dBm thresholds for CDMA2000 {@link AccessNetworkConstants.AccessNetworkType}.
-         *
-         * These correspond to EVDO level thresholds.
-         */
-        public static final int[] CDMA2000 = new int[]{
-                -105,
-                -90,
-                -75,
-                -65
-        };
-
-        /**
-         * List of dB thresholds for NGRAN {@link AccessNetworkConstants.AccessNetworkType} SSRSRP
-         */
-        public static final int[] NGRAN_SSRSRP = new int[]{
-                -110, /* SIGNAL_STRENGTH_POOR */
-                -90, /* SIGNAL_STRENGTH_MODERATE */
-                -80, /* SIGNAL_STRENGTH_GOOD */
-                -65,  /* SIGNAL_STRENGTH_GREAT */
-        };
-
-        /**
-         * List of dB thresholds for NGRAN {@link AccessNetworkConstants.AccessNetworkType} SSRSRQ
-         */
-        public static final int[] NGRAN_SSRSRQ = new int[]{
-                -31, /* SIGNAL_STRENGTH_POOR */
-                -19, /* SIGNAL_STRENGTH_MODERATE */
-                -7, /* SIGNAL_STRENGTH_GOOD */
-                6  /* SIGNAL_STRENGTH_GREAT */
-        };
-
-        /**
-         * List of dB thresholds for NGRAN {@link AccessNetworkConstants.AccessNetworkType} SSSINR
-         */
-        public static final int[] NGRAN_SSSINR = new int[]{
-                -5, /* SIGNAL_STRENGTH_POOR */
-                5, /* SIGNAL_STRENGTH_MODERATE */
-                15, /* SIGNAL_STRENGTH_GOOD */
-                30  /* SIGNAL_STRENGTH_GREAT */
-        };
-    }
-
-    private static void log(String msg) {
-        if (DBG) Rlog.d(TAG, msg);
-    }
-
-    private static void loge(String msg) {
-        Rlog.e(TAG, msg);
-    }
-
-    /** Print to both Radio log and LocalLog, used only for critical but non-sensitive msg. */
-    private void localLog(String msg) {
-        Rlog.d(TAG, msg);
-        mLocalLog.log(TAG + ": " + msg);
-    }
-}
diff --git a/src/java/com/android/internal/telephony/SimActivationTracker.java b/src/java/com/android/internal/telephony/SimActivationTracker.java
index 80d23e8..2daf858 100644
--- a/src/java/com/android/internal/telephony/SimActivationTracker.java
+++ b/src/java/com/android/internal/telephony/SimActivationTracker.java
@@ -64,8 +64,8 @@
      * @see android.telephony.TelephonyManager#SIM_ACTIVATION_STATE_RESTRICTED
      */
     private int mDataActivationState;
-    private final LocalLog mVoiceActivationStateLog = new LocalLog(8);
-    private final LocalLog mDataActivationStateLog = new LocalLog(8);
+    private final LocalLog mVoiceActivationStateLog = new LocalLog(10);
+    private final LocalLog mDataActivationStateLog = new LocalLog(10);
     private final BroadcastReceiver mReceiver;
 
     public SimActivationTracker(Phone phone) {
diff --git a/src/java/com/android/internal/telephony/SimIndication.java b/src/java/com/android/internal/telephony/SimIndication.java
deleted file mode 100644
index f3ece16..0000000
--- a/src/java/com/android/internal/telephony/SimIndication.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_RECORDS_RECEIVED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SIM_REFRESH;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_EVENT_NOTIFY;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_PROACTIVE_COMMAND;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_SESSION_END;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED;
-
-import android.hardware.radio.sim.IRadioSimIndication;
-import android.os.AsyncResult;
-
-import com.android.internal.telephony.uicc.IccRefreshResponse;
-import com.android.internal.telephony.uicc.ReceivedPhonebookRecords;
-import com.android.internal.telephony.uicc.SimPhonebookRecord;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Interface declaring unsolicited radio indications for SIM APIs.
- */
-public class SimIndication extends IRadioSimIndication.Stub {
-    private final RIL mRil;
-
-    public SimIndication(RIL ril) {
-        mRil = ril;
-    }
-
-    /**
-     * Indicates when the carrier info to encrypt IMSI is being requested.
-     * @param indicationType Type of radio indication
-     */
-    public void carrierInfoForImsiEncryption(int indicationType) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION, null);
-
-        mRil.mCarrierInfoForImsiEncryptionRegistrants.notifyRegistrants(
-                new AsyncResult(null, null, null));
-    }
-
-    /**
-     * Indicates when CDMA subscription source changed.
-     * @param indicationType Type of radio indication
-     * @param cdmaSource New CdmaSubscriptionSource
-     */
-    public void cdmaSubscriptionSourceChanged(int indicationType, int cdmaSource) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
-
-        int[] response = new int[]{cdmaSource};
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CDMA_SUBSCRIPTION_SOURCE_CHANGED, response);
-
-        mRil.mCdmaSubscriptionChangedRegistrants.notifyRegistrants(
-                new AsyncResult(null, response, null));
-    }
-
-    /**
-     * Indicates when the phonebook is changed.
-     * @param indicationType Type of radio indication
-     */
-    public void simPhonebookChanged(int indicationType) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) {
-            mRil.unsljLog(RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_CHANGED);
-        }
-
-        mRil.mSimPhonebookChangedRegistrants.notifyRegistrants();
-    }
-
-    /**
-     * Indicates the content of all the used records in the SIM phonebook.
-     * @param indicationType Type of radio indication
-     * @param status Status of PbReceivedStatus
-     * @param records Content of the SIM phonebook records
-     */
-    public void simPhonebookRecordsReceived(int indicationType, byte status,
-            android.hardware.radio.sim.PhonebookRecordInfo[] records) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
-
-        List<SimPhonebookRecord> simPhonebookRecords = new ArrayList<>();
-
-        for (android.hardware.radio.sim.PhonebookRecordInfo record : records) {
-            simPhonebookRecords.add(RILUtils.convertHalPhonebookRecordInfo(record));
-        }
-
-        if (RIL.RILJ_LOGD) {
-            mRil.unsljLogRet(RIL_UNSOL_RESPONSE_SIM_PHONEBOOK_RECORDS_RECEIVED,
-                    "status = " + status + " received " + records.length + " records");
-        }
-
-        mRil.mSimPhonebookRecordsReceivedRegistrants.notifyRegistrants(new AsyncResult(
-                null, new ReceivedPhonebookRecords(status, simPhonebookRecords), null));
-    }
-
-    /**
-     * Indicates that file(s) on the SIM have been updated, or the SIM has been reinitialized.
-     * @param indicationType Type of radio indication
-     * @param refreshResult Result of SIM refresh
-     */
-    public void simRefresh(int indicationType,
-            android.hardware.radio.sim.SimRefreshResult refreshResult) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
-
-        IccRefreshResponse response = new IccRefreshResponse();
-        response.refreshResult = refreshResult.type;
-        response.efId = refreshResult.efId;
-        response.aid = refreshResult.aid;
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_SIM_REFRESH, response);
-
-        mRil.mIccRefreshRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
-    }
-
-    /**
-     * Indicates that SIM state changed.
-     * @param indicationType Type of radio indication
-     */
-    public void simStatusChanged(int indicationType) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_SIM_STATUS_CHANGED);
-
-        mRil.mIccStatusChangedRegistrants.notifyRegistrants();
-    }
-
-    /**
-     * Indicates when SIM notifies applications some event happens.
-     * @param indicationType Type of radio indication
-     * @param cmd SAT/USAT commands or responses sent by ME to SIM or commands handled by ME,
-     *        represented as byte array starting with first byte of response data for command tag.
-     *        Refer to TS 102.223 section 9.4 for command types
-     */
-    public void stkEventNotify(int indicationType, String cmd) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_STK_EVENT_NOTIFY);
-
-        if (mRil.mCatEventRegistrant != null) {
-            mRil.mCatEventRegistrant.notifyRegistrant(new AsyncResult(null, cmd, null));
-        }
-    }
-
-    /**
-     * Indicates when SIM issue a STK proactive command to applications.
-     * @param indicationType Type of radio indication
-     * @param cmd SAT/USAT proactive represented as byte array starting with command tag.
-     *        Refer to TS 102.223 section 9.4 for command types
-     */
-    public void stkProactiveCommand(int indicationType, String cmd) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_STK_PROACTIVE_COMMAND);
-
-        if (mRil.mCatProCmdRegistrant != null) {
-            mRil.mCatProCmdRegistrant.notifyRegistrant(new AsyncResult(null, cmd, null));
-        }
-    }
-
-    /**
-     * Indicates when STK session is terminated by SIM.
-     * @param indicationType Type of radio indication
-     */
-    public void stkSessionEnd(int indicationType) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_STK_SESSION_END);
-
-        if (mRil.mCatSessionEndRegistrant != null) {
-            mRil.mCatSessionEndRegistrant.notifyRegistrant(new AsyncResult(null, null, null));
-        }
-    }
-
-    /**
-     * Indicated when there is a change in subscription status.
-     * @param indicationType Type of radio indication
-     * @param activate false for subscription deactivated, true for subscription activated
-     */
-    public void subscriptionStatusChanged(int indicationType, boolean activate) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
-
-        int[] response = new int[]{activate ? 1 : 0};
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_UICC_SUBSCRIPTION_STATUS_CHANGED, response);
-
-        mRil.mSubscriptionStatusRegistrants.notifyRegistrants(
-                new AsyncResult(null, response, null));
-    }
-
-    /**
-     * Report change of whether uiccApplications are enabled or disabled.
-     * @param indicationType Type of radio indication
-     * @param enabled Whether uiccApplications are enabled or disabled
-     */
-    public void uiccApplicationsEnablementChanged(int indicationType, boolean enabled) {
-        mRil.processIndication(RIL.SIM_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) {
-            mRil.unsljLogRet(RIL_UNSOL_UICC_APPLICATIONS_ENABLEMENT_CHANGED, enabled);
-        }
-
-        mRil.mUiccApplicationsEnablementRegistrants.notifyResult(enabled);
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return IRadioSimIndication.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return IRadioSimIndication.VERSION;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/SimResponse.java b/src/java/com/android/internal/telephony/SimResponse.java
deleted file mode 100644
index b0099fb..0000000
--- a/src/java/com/android/internal/telephony/SimResponse.java
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.hardware.radio.RadioError;
-import android.hardware.radio.RadioResponseInfo;
-import android.hardware.radio.sim.IRadioSimResponse;
-import android.telephony.CarrierRestrictionRules;
-import android.telephony.TelephonyManager;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.uicc.AdnCapacity;
-import com.android.internal.telephony.uicc.IccCardStatus;
-import com.android.internal.telephony.uicc.IccIoResult;
-
-import java.util.ArrayList;
-
-/**
- * Interface declaring response functions to solicited radio requests for SIM APIs.
- */
-public class SimResponse extends IRadioSimResponse.Stub {
-    private final RIL mRil;
-
-    public SimResponse(RIL ril) {
-        mRil = ril;
-    }
-
-    private void responseIccIo(RadioResponseInfo responseInfo,
-            android.hardware.radio.sim.IccIoResult result) {
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
-
-        if (rr != null) {
-            IccIoResult ret = new IccIoResult(result.sw1, result.sw2, result.simResponse);
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for
-     * radio request which take long time to respond.
-     * For more details, refer https://source.android.com/devices/tech/connect/ril.html
-     * @param serial Serial no. of the request whose acknowledgement is sent.
-     */
-    public void acknowledgeRequest(int serial) {
-        mRil.processRequestAck(serial);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error.
-     * @param enabled whether UICC applications are enabled.
-     */
-    public void areUiccApplicationsEnabledResponse(RadioResponseInfo responseInfo,
-            boolean enabled) {
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
-
-        if (rr != null) {
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, enabled);
-            }
-            mRil.processResponseDone(rr, responseInfo, enabled);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param remainingAttempts Number of retries remaining, must be equal to -1 if unknown.
-     */
-    public void changeIccPin2ForAppResponse(RadioResponseInfo responseInfo, int remainingAttempts) {
-        RadioResponse.responseInts(RIL.SIM_SERVICE, mRil, responseInfo, remainingAttempts);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param remainingAttempts Number of retries remaining, must be equal to -1 if unknown.
-     */
-    public void changeIccPinForAppResponse(RadioResponseInfo responseInfo, int remainingAttempts) {
-        RadioResponse.responseInts(RIL.SIM_SERVICE, mRil, responseInfo, remainingAttempts);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error.
-     */
-    public void enableUiccApplicationsResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.SIM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param carrierRestrictions Carrier restriction information.
-     * @param multiSimPolicy Policy for multi-sim devices.
-     */
-    public void getAllowedCarriersResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.sim.CarrierRestrictions carrierRestrictions,
-            int multiSimPolicy) {
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
-        if (rr == null) {
-            return;
-        }
-        CarrierRestrictionRules ret;
-        int policy = CarrierRestrictionRules.MULTISIM_POLICY_NONE;
-        if (multiSimPolicy
-                == android.hardware.radio.sim.SimLockMultiSimPolicy.ONE_VALID_SIM_MUST_BE_PRESENT) {
-            policy = CarrierRestrictionRules.MULTISIM_POLICY_ONE_VALID_SIM_MUST_BE_PRESENT;
-        }
-
-        int carrierRestrictionDefault =
-                CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_NOT_ALLOWED;
-        if (!carrierRestrictions.allowedCarriersPrioritized) {
-            carrierRestrictionDefault = CarrierRestrictionRules.CARRIER_RESTRICTION_DEFAULT_ALLOWED;
-        }
-
-        ret = CarrierRestrictionRules.newBuilder()
-                .setAllowedCarriers(RILUtils.convertHalCarrierList(
-                        carrierRestrictions.allowedCarriers))
-                .setExcludedCarriers(RILUtils.convertHalCarrierList(
-                        carrierRestrictions.excludedCarriers))
-                .setDefaultCarrierRestriction(carrierRestrictionDefault)
-                .setMultiSimPolicy(policy)
-                .build();
-
-        if (responseInfo.error == RadioError.NONE) {
-            RadioResponse.sendMessageResponse(rr.mResult, ret);
-        }
-        mRil.processResponseDone(rr, responseInfo, ret);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param mdn MDN if CDMA subscription is available
-     * @param hSid is a comma separated list of H_SID (Home SID) if
-     *        CDMA subscription is available, in decimal format
-     * @param hNid is a comma separated list of H_NID (Home NID) if
-     *        CDMA subscription is available, in decimal format
-     * @param min MIN (10 digits, MIN2+MIN1) if CDMA subscription is available
-     * @param prl PRL version if CDMA subscription is available
-     */
-    public void getCdmaSubscriptionResponse(RadioResponseInfo responseInfo, String mdn,
-            String hSid, String hNid, String min, String prl) {
-        RadioResponse.responseStrings(
-                RIL.SIM_SERVICE, mRil, responseInfo, mdn, hSid, hNid, min, prl);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param source CDMA subscription source
-     */
-    public void getCdmaSubscriptionSourceResponse(RadioResponseInfo responseInfo, int source) {
-        RadioResponse.responseInts(RIL.SIM_SERVICE, mRil, responseInfo, source);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param response 0 is the TS 27.007 service class bit vector of services for which the
-     *        specified barring facility is active. "0" means "disabled for all"
-     */
-    public void getFacilityLockForAppResponse(RadioResponseInfo responseInfo, int response) {
-        RadioResponse.responseInts(RIL.SIM_SERVICE, mRil, responseInfo, response);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param cardStatus ICC card status as defined by CardStatus
-     */
-    public void getIccCardStatusResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.sim.CardStatus cardStatus) {
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
-
-        if (rr != null) {
-            IccCardStatus iccCardStatus = RILUtils.convertHalCardStatus(cardStatus);
-            mRil.riljLog("responseIccCardStatus: from AIDL: " + iccCardStatus);
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, iccCardStatus);
-            }
-            mRil.processResponseDone(rr, responseInfo, iccCardStatus);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param imsi String containing the IMSI
-     */
-    public void getImsiForAppResponse(RadioResponseInfo responseInfo, String imsi) {
-        RadioResponse.responseString(RIL.SIM_SERVICE, mRil, responseInfo, imsi);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error.
-     * @param pbCapacity Contains the adn, email, anr capacities in the sim card.
-     */
-    public void getSimPhonebookCapacityResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.sim.PhonebookCapacity pbCapacity) {
-        AdnCapacity capacity = RILUtils.convertHalPhonebookCapacity(pbCapacity);
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
-        if (rr != null) {
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, capacity);
-            }
-            mRil.processResponseDone(rr, responseInfo, capacity);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error.
-     */
-    public void getSimPhonebookRecordsResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.SIM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void iccCloseLogicalChannelResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.SIM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param iccIo ICC IO operation response as defined by IccIoResult
-     */
-    public void iccIoForAppResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.sim.IccIoResult iccIo) {
-        responseIccIo(responseInfo, iccIo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param channelId session id of the logical channel.
-     * @param selectResponse Contains the select response for the open channel command with one
-     *        byte per integer
-     */
-    public void iccOpenLogicalChannelResponse(RadioResponseInfo responseInfo, int channelId,
-            byte[] selectResponse) {
-        ArrayList<Integer> arr = new ArrayList<>();
-        arr.add(channelId);
-        for (int i = 0; i < selectResponse.length; i++) {
-            arr.add((int) selectResponse[i]);
-        }
-        RadioResponse.responseIntArrayList(RIL.SIM_SERVICE, mRil, responseInfo, arr);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param iccIo ICC IO operation response as defined by IccIoResult
-     */
-    public void iccTransmitApduBasicChannelResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.sim.IccIoResult iccIo) {
-        responseIccIo(responseInfo, iccIo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param iccIo ICC IO operation response as defined by IccIoResult
-     */
-    public void iccTransmitApduLogicalChannelResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.sim.IccIoResult iccIo) {
-        responseIccIo(responseInfo, iccIo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void reportStkServiceIsRunningResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.SIM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param iccIo ICC IO operation response as defined by IccIoResult
-     */
-    public void requestIccSimAuthenticationResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.sim.IccIoResult iccIo) {
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
-
-        if (rr != null) {
-            IccIoResult ret = new IccIoResult(iccIo.sw1, iccIo.sw2,
-                    TextUtils.isEmpty(iccIo.simResponse) ? null : iccIo.simResponse.getBytes());
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * This method is deprecated and should not be used.
-     *
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param response response string of the challenge/response algo for ISIM auth in base64 format
-     */
-    public void requestIsimAuthenticationResponse(RadioResponseInfo responseInfo, String response) {
-        // TODO (b/199433581): remove this method
-        throw new RuntimeException("Inexplicable response received for requestIsimAuthentication");
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param commandResponse SAT/USAT response in hexadecimal format
-     *        string starting with first byte of response
-     */
-    public void sendEnvelopeResponse(RadioResponseInfo responseInfo, String commandResponse) {
-        RadioResponse.responseString(RIL.SIM_SERVICE, mRil, responseInfo, commandResponse);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param iccIo ICC IO operation response as defined by IccIoResult
-     */
-    public void sendEnvelopeWithStatusResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.sim.IccIoResult iccIo) {
-        responseIccIo(responseInfo, iccIo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void sendTerminalResponseToSimResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.SIM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setAllowedCarriersResponse(RadioResponseInfo responseInfo) {
-        int ret = TelephonyManager.SET_CARRIER_RESTRICTION_ERROR;
-        RILRequest rr = mRil.processResponse(RIL.SIM_SERVICE, responseInfo);
-        if (rr != null) {
-            mRil.riljLog("setAllowedCarriersResponse - error = " + responseInfo.error);
-
-            if (responseInfo.error == RadioError.NONE) {
-                ret = TelephonyManager.SET_CARRIER_RESTRICTION_SUCCESS;
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setCarrierInfoForImsiEncryptionResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.SIM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setCdmaSubscriptionSourceResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.SIM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param retry 0 is the number of retries remaining, or -1 if unknown
-     */
-    public void setFacilityLockForAppResponse(RadioResponseInfo responseInfo, int retry) {
-        RadioResponse.responseInts(RIL.SIM_SERVICE, mRil, responseInfo, retry);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setSimCardPowerResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.SIM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setUiccSubscriptionResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.SIM_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param remainingAttempts Number of retries remaining, must be equal to -1 if unknown.
-     */
-    public void supplyIccPin2ForAppResponse(RadioResponseInfo responseInfo, int remainingAttempts) {
-        RadioResponse.responseInts(RIL.SIM_SERVICE, mRil, responseInfo, remainingAttempts);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param remainingAttempts Number of retries remaining, must be equal to -1 if unknown.
-     */
-    public void supplyIccPinForAppResponse(RadioResponseInfo responseInfo, int remainingAttempts) {
-        RadioResponse.responseInts(RIL.SIM_SERVICE, mRil, responseInfo, remainingAttempts);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param remainingAttempts Number of retries remaining, must be equal to -1 if unknown.
-     */
-    public void supplyIccPuk2ForAppResponse(RadioResponseInfo responseInfo, int remainingAttempts) {
-        RadioResponse.responseInts(RIL.SIM_SERVICE, mRil, responseInfo, remainingAttempts);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param remainingAttempts Number of retries remaining, must be equal to -1 if unknown.
-     */
-    public void supplyIccPukForAppResponse(RadioResponseInfo responseInfo, int remainingAttempts) {
-        RadioResponse.responseInts(RIL.SIM_SERVICE, mRil, responseInfo, remainingAttempts);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param persoType SIM Personalisation type
-     * @param remainingRetries postiive values indicates number of retries remaining,
-     * must be equal to -1 if number of retries is infinite.
-     */
-    public void supplySimDepersonalizationResponse(RadioResponseInfo responseInfo, int persoType,
-            int remainingRetries) {
-        RadioResponse.responseInts(
-                RIL.SIM_SERVICE, mRil, responseInfo, persoType, remainingRetries);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error.
-     * @param updatedRecordIndex The index of the updated record.
-     */
-    public void updateSimPhonebookRecordsResponse(RadioResponseInfo responseInfo,
-            int updatedRecordIndex) {
-        RadioResponse.responseInts(RIL.SIM_SERVICE, mRil, responseInfo, updatedRecordIndex);
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return IRadioSimResponse.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return IRadioSimResponse.VERSION;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/SlidingWindowEventCounter.java b/src/java/com/android/internal/telephony/SlidingWindowEventCounter.java
index 149e425..7540ce6 100644
--- a/src/java/com/android/internal/telephony/SlidingWindowEventCounter.java
+++ b/src/java/com/android/internal/telephony/SlidingWindowEventCounter.java
@@ -17,7 +17,6 @@
 package com.android.internal.telephony;
 
 import android.annotation.IntRange;
-import android.annotation.NonNull;
 import android.os.SystemClock;
 import android.util.LongArrayQueue;
 
@@ -33,10 +32,10 @@
     private final int mNumOccurrences;
     private final LongArrayQueue mTimestampQueueMillis;
 
-    public SlidingWindowEventCounter(@IntRange(from = 0) final long windowSizeMillis,
+    public SlidingWindowEventCounter(@IntRange(from = 1) final long windowSizeMillis,
             @IntRange(from = 2) final int numOccurrences) {
-        if (windowSizeMillis < 0) {
-            throw new IllegalArgumentException("windowSizeMillis must be greater or equal to 0");
+        if (windowSizeMillis <= 0) {
+            throw new IllegalArgumentException("windowSizeMillis must be greater than 0");
         }
         if (numOccurrences <= 1) {
             throw new IllegalArgumentException("numOccurrences must be greater than 1");
@@ -78,41 +77,11 @@
     public synchronized boolean isInWindow() {
         return (mTimestampQueueMillis.size() == mNumOccurrences)
                 && mTimestampQueueMillis.peekFirst()
-                + mWindowSizeMillis > mTimestampQueueMillis.peekLast();
+                + mWindowSizeMillis >= mTimestampQueueMillis.peekLast();
     }
 
     @VisibleForTesting
-    int getQueuedNumOccurrences() {
+    int getNumOccurrences() {
         return mTimestampQueueMillis.size();
     }
-
-    /**
-     * @return the time span in ms of the sliding window.
-     */
-    public synchronized long getWindowSizeMillis() {
-        return mWindowSizeMillis;
-    }
-
-    /**
-     * @return the least number of occurrences for {@link #isInWindow} to be true.
-     */
-    public synchronized int getNumOccurrences() {
-        return mNumOccurrences;
-    }
-
-    /**
-     * Get the event frequency description.
-     *
-     * @return A string describing the anomaly event
-     */
-    public @NonNull String getFrequencyString() {
-        return String.format("%d times within %d ms.", mNumOccurrences, mWindowSizeMillis);
-    }
-
-    @Override
-    public String toString() {
-        return String.format("SlidingWindowEventCounter=[windowSizeMillis=" + mWindowSizeMillis
-                + ", numOccurrences=" + mNumOccurrences
-                + ", timestampQueueMillis=" + mTimestampQueueMillis + "]");
-    }
 }
diff --git a/src/java/com/android/internal/telephony/SubscriptionController.java b/src/java/com/android/internal/telephony/SubscriptionController.java
index 7e762d7..2243e48 100644
--- a/src/java/com/android/internal/telephony/SubscriptionController.java
+++ b/src/java/com/android/internal/telephony/SubscriptionController.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.telephony;
 
-import static android.Manifest.permission.READ_PHONE_NUMBERS;
-import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.telephony.TelephonyManager.MULTISIM_ALLOWED;
 import static android.telephony.TelephonyManager.SET_OPPORTUNISTIC_SUB_REMOTE_SERVICE_EXCEPTION;
@@ -33,9 +31,10 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
-import android.content.pm.PackageManager;
 import android.database.ContentObserver;
 import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 import android.net.Uri;
 import android.os.Binder;
 import android.os.Build;
@@ -47,7 +46,6 @@
 import android.os.TelephonyServiceManager.ServiceRegisterer;
 import android.os.UserHandle;
 import android.provider.Settings;
-import android.provider.Telephony.SimInfo;
 import android.telecom.PhoneAccountHandle;
 import android.telecom.TelecomManager;
 import android.telephony.AnomalyReporter;
@@ -56,14 +54,11 @@
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.SubscriptionManager.SimDisplayNameSource;
-import android.telephony.SubscriptionManager.UsageSetting;
 import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.TelephonyManager;
 import android.telephony.TelephonyRegistryManager;
 import android.telephony.UiccAccessRule;
-import android.telephony.UiccPortInfo;
 import android.telephony.UiccSlotInfo;
-import android.telephony.UiccSlotMapping;
 import android.telephony.euicc.EuiccManager;
 import android.text.TextUtils;
 import android.util.EventLog;
@@ -73,8 +68,7 @@
 import com.android.ims.ImsManager;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.IccCardConstants.State;
-import com.android.internal.telephony.data.DataEnabledOverride;
-import com.android.internal.telephony.data.PhoneSwitcher;
+import com.android.internal.telephony.dataconnection.DataEnabledOverride;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.telephony.uicc.UiccCard;
@@ -101,6 +95,7 @@
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 /**
  * Implementation of the ISub interface.
@@ -120,13 +115,13 @@
  */
 public class SubscriptionController extends ISub.Stub {
     private static final String LOG_TAG = "SubscriptionController";
-    private static final boolean DBG = false;
+    private static final boolean DBG = true;
     private static final boolean VDBG = Rlog.isLoggable(LOG_TAG, Log.VERBOSE);
     private static final boolean DBG_CACHE = false;
     private static final int DEPRECATED_SETTING = -1;
     private static final ParcelUuid INVALID_GROUP_UUID =
             ParcelUuid.fromString(CarrierConfigManager.REMOVE_GROUP_UUID_STRING);
-    private final LocalLog mLocalLog = new LocalLog(128);
+    private final LocalLog mLocalLog = new LocalLog(200);
     private static final int SUB_ID_FOUND = 1;
     private static final int NO_ENTRY_FOR_SLOT_INDEX = -1;
     private static final int SUB_ID_NOT_IN_SLOT = -2;
@@ -306,8 +301,7 @@
             SubscriptionManager.DATA_ENABLED_OVERRIDE_RULES,
             SubscriptionManager.UICC_APPLICATIONS_ENABLED,
             SubscriptionManager.IMS_RCS_UCE_ENABLED,
-            SubscriptionManager.CROSS_SIM_CALLING_ENABLED,
-            SubscriptionManager.NR_ADVANCED_CALLING_ENABLED
+            SubscriptionManager.CROSS_SIM_CALLING_ENABLED
     ));
 
     public static SubscriptionController init(Context c) {
@@ -553,6 +547,9 @@
                 SubscriptionManager.NUMBER));
         int dataRoaming = cursor.getInt(cursor.getColumnIndexOrThrow(
                 SubscriptionManager.DATA_ROAMING));
+        // Get the blank bitmap for this SubInfoRecord
+        Bitmap iconBitmap = BitmapFactory.decodeResource(mContext.getResources(),
+                com.android.internal.R.drawable.ic_sim_card_multi_24px_clr);
         String mcc = cursor.getString(cursor.getColumnIndexOrThrow(
                 SubscriptionManager.MCC_STRING));
         String mnc = cursor.getString(cursor.getColumnIndexOrThrow(
@@ -590,8 +587,6 @@
                 SubscriptionManager.GROUP_UUID));
         int profileClass = cursor.getInt(cursor.getColumnIndexOrThrow(
                 SubscriptionManager.PROFILE_CLASS));
-        int portIndex = cursor.getInt(cursor.getColumnIndexOrThrow(
-                SubscriptionManager.PORT_INDEX));
         int subType = cursor.getInt(cursor.getColumnIndexOrThrow(
                 SubscriptionManager.SUBSCRIPTION_TYPE));
         String groupOwner = getOptionalStringFromCursor(cursor, SubscriptionManager.GROUP_OWNER,
@@ -599,9 +594,6 @@
         boolean areUiccApplicationsEnabled = cursor.getInt(cursor.getColumnIndexOrThrow(
                 SubscriptionManager.UICC_APPLICATIONS_ENABLED)) == 1;
 
-        int usageSetting = cursor.getInt(cursor.getColumnIndexOrThrow(
-                SubscriptionManager.USAGE_SETTING));
-
         if (VDBG) {
             String iccIdToPrint = SubscriptionInfo.givePrintableIccid(iccId);
             String cardIdToPrint = SubscriptionInfo.givePrintableIccid(cardId);
@@ -612,13 +604,11 @@
                     + " countIso:" + countryIso + " isEmbedded:"
                     + isEmbedded + " accessRules:" + Arrays.toString(accessRules)
                     + " carrierConfigAccessRules: " + Arrays.toString(carrierConfigAccessRules)
-                    + " cardId:" + cardIdToPrint + " portIndex:" + portIndex
-                    + " publicCardId:" + publicCardId
+                    + " cardId:" + cardIdToPrint + " publicCardId:" + publicCardId
                     + " isOpportunistic:" + isOpportunistic + " groupUUID:" + groupUUID
                     + " profileClass:" + profileClass + " subscriptionType: " + subType
                     + " carrierConfigAccessRules:" + carrierConfigAccessRules
-                    + " areUiccApplicationsEnabled: " + areUiccApplicationsEnabled
-                    + " usageSetting: " + usageSetting);
+                    + " areUiccApplicationsEnabled: " + areUiccApplicationsEnabled);
         }
 
         // If line1number has been set to a different number, use it instead.
@@ -626,14 +616,11 @@
         if (!TextUtils.isEmpty(line1Number) && !line1Number.equals(number)) {
             number = line1Number;
         }
-        // FIXME(b/210771052): constructing a complete SubscriptionInfo requires a port index,
-        // but the port index isn't available here. Should it actually be part of SubscriptionInfo?
         SubscriptionInfo info = new SubscriptionInfo(id, iccId, simSlotIndex, displayName,
-                carrierName, nameSource, iconTint, number, dataRoaming, /* icon= */ null,
-                mcc, mnc, countryIso, isEmbedded, accessRules, cardId, publicCardId,
-                isOpportunistic, groupUUID, /* isGroupDisabled= */ false , carrierId, profileClass,
-                subType, groupOwner, carrierConfigAccessRules, areUiccApplicationsEnabled,
-                portIndex, usageSetting);
+                carrierName, nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc,
+                countryIso, isEmbedded, accessRules, cardId, publicCardId, isOpportunistic,
+                groupUUID, false /* isGroupDisabled */, carrierId, profileClass, subType,
+                groupOwner, carrierConfigAccessRules, areUiccApplicationsEnabled);
         info.setAssociatedPlmns(ehplmns, hplmns);
         return info;
     }
@@ -889,10 +876,6 @@
                     if (DBG) {
                         logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex="
                                 + slotIndex + " subId=" + si);
-                    } else {
-                        logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex="
-                                + slotIndex + " subId=" + conditionallyRemoveIdentifiers(si, false,
-                                false));
                     }
                     return conditionallyRemoveIdentifiers(si, callingPackage, callingFeatureId,
                             "getActiveSubscriptionInfoForSimSlotIndex");
@@ -1179,12 +1162,9 @@
         for (UiccSlot uiccSlot : uiccSlots) {
             if (uiccSlot != null && uiccSlot.getCardState() != null
                     && uiccSlot.getCardState().isCardPresent()
-                    && !uiccSlot.isEuicc()) {
-                // Non euicc slots will have single port, so use default port index.
-                String iccId = uiccSlot.getIccId(TelephonyManager.DEFAULT_PORT_INDEX);
-                if (!TextUtils.isEmpty(iccId)) {
-                    ret.add(IccUtils.stripTrailingFs(iccId));
-                }
+                    && !uiccSlot.isEuicc()
+                    && !TextUtils.isEmpty(uiccSlot.getIccId())) {
+                ret.add(IccUtils.stripTrailingFs(uiccSlot.getIccId()));
             }
         }
 
@@ -1271,7 +1251,7 @@
             if (i > 0) {
                 whereClause.append(",");
             }
-            whereClause.append("'").append(embeddedIccids[i]).append("'");
+            whereClause.append("\"").append(embeddedIccids[i]).append("\"");
         }
         whereClause.append(")");
 
@@ -1367,12 +1347,6 @@
             String selection = SubscriptionManager.ICC_ID + "=?";
             String[] args;
             if (isSubscriptionForRemoteSim(subscriptionType)) {
-                PackageManager packageManager = mContext.getPackageManager();
-                if (!packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) {
-                    logel("[addSubInfo] Remote SIM can only be added when FEATURE_AUTOMOTIVE"
-                            + " is supported");
-                    return -1;
-                }
                 selection += " AND " + SubscriptionManager.SUBSCRIPTION_TYPE + "=?";
                 args = new String[]{uniqueId, Integer.toString(subscriptionType)};
             } else {
@@ -1382,8 +1356,7 @@
             Cursor cursor = resolver.query(SubscriptionManager.CONTENT_URI,
                     new String[]{SubscriptionManager.UNIQUE_KEY_SUBSCRIPTION_ID,
                             SubscriptionManager.SIM_SLOT_INDEX, SubscriptionManager.NAME_SOURCE,
-                            SubscriptionManager.ICC_ID, SubscriptionManager.CARD_ID,
-                            SubscriptionManager.PORT_INDEX},
+                            SubscriptionManager.ICC_ID, SubscriptionManager.CARD_ID},
                     selection, args, null);
 
             boolean setDisplayName = false;
@@ -1410,7 +1383,6 @@
                         int nameSource = cursor.getInt(2);
                         String oldIccId = cursor.getString(3);
                         String oldCardId = cursor.getString(4);
-                        int oldPortIndex = cursor.getInt(5);
                         ContentValues value = new ContentValues();
 
                         if (slotIndex != oldSimInfoId) {
@@ -1430,15 +1402,6 @@
                             }
                         }
 
-                        //update portIndex for pSim
-                        UiccSlot slot = mUiccController.getUiccSlotForPhone(slotIndex);
-                        if (slot != null && !slot.isEuicc()) {
-                            int portIndex = slot.getPortIndexFromIccId(uniqueId);
-                            if (portIndex != oldPortIndex) {
-                                value.put(SubscriptionManager.PORT_INDEX, portIndex);
-                            }
-                        }
-
                         if (value.size() > 0) {
                             resolver.update(SubscriptionManager.getUriForSubscriptionId(subId),
                                     value, null, null);
@@ -1756,18 +1719,11 @@
                     value.put(SubscriptionManager.CARD_ID, cardId);
                 }
             }
-            UiccSlot slot = mUiccController.getUiccSlotForPhone(slotIndex);
-            if (slot != null) {
-                value.put(SubscriptionManager.PORT_INDEX, slot.getPortIndexFromIccId(uniqueId));
-            }
         }
         value.put(SubscriptionManager.ALLOWED_NETWORK_TYPES,
                 "user=" + RadioAccessFamily.getRafFromNetworkType(
                         RILConstants.PREFERRED_NETWORK_MODE));
 
-        value.put(SubscriptionManager.USAGE_SETTING,
-                SubscriptionManager.USAGE_SETTING_UNKNOWN);
-
         Uri uri = resolver.insert(SubscriptionManager.CONTENT_URI, value);
 
         // Refresh the Cache of Active Subscription Info List
@@ -2311,7 +2267,6 @@
             case SubscriptionManager.DATA_ROAMING:
             case SubscriptionManager.IMS_RCS_UCE_ENABLED:
             case SubscriptionManager.CROSS_SIM_CALLING_ENABLED:
-            case SubscriptionManager.NR_ADVANCED_CALLING_ENABLED:
                 values.put(propKey, cursor.getInt(columnIndex));
                 break;
             case SubscriptionManager.DISPLAY_NAME:
@@ -2829,8 +2784,7 @@
         if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
             throw new RuntimeException("setDefaultVoiceSubId called with DEFAULT_SUB_ID");
         }
-
-        logdl("[setDefaultVoiceSubId] subId=" + subId);
+        if (DBG) logdl("[setDefaultVoiceSubId] subId=" + subId);
 
         int previousDefaultSub = getDefaultSubId();
 
@@ -2844,21 +2798,16 @@
 
         TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
         PhoneAccountHandle currentHandle = telecomManager.getUserSelectedOutgoingPhoneAccount();
-        logd("[setDefaultVoiceSubId] current phoneAccountHandle=" + currentHandle);
 
         if (!Objects.equals(currentHandle, newHandle)) {
             telecomManager.setUserSelectedOutgoingPhoneAccount(newHandle);
             logd("[setDefaultVoiceSubId] change to phoneAccountHandle=" + newHandle);
         } else {
-            logd("[setDefaultVoiceSubId] default phoneAccountHandle not changed.");
+            logd("[setDefaultVoiceSubId] default phone account not changed");
         }
 
         if (previousDefaultSub != getDefaultSubId()) {
             sendDefaultChangedBroadcast(getDefaultSubId());
-            logd(String.format("[setDefaultVoiceSubId] change to subId=%d", getDefaultSubId()));
-        } else {
-            logd(String.format("[setDefaultVoiceSubId] default subId not changed. subId=%d",
-                    previousDefaultSub));
         }
     }
 
@@ -3074,9 +3023,9 @@
     private void validateSubId(int subId) {
         if (DBG) logd("validateSubId subId: " + subId);
         if (!SubscriptionManager.isValidSubscriptionId(subId)) {
-            throw new IllegalArgumentException("Invalid sub id passed as parameter");
+            throw new RuntimeException("Invalid sub id passed as parameter");
         } else if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
-            throw new IllegalArgumentException("Default sub id passed as parameter");
+            throw new RuntimeException("Default sub id passed as parameter");
         }
     }
 
@@ -3115,33 +3064,26 @@
      */
     @Override
     public int[] getActiveSubIdList(boolean visibleOnly) {
-        enforceReadPrivilegedPhoneState("getActiveSubIdList");
+        List<Integer> allSubs = getActiveSubIdArrayList();
 
-        final long token = Binder.clearCallingIdentity();
-        try {
-            List<Integer> allSubs = getActiveSubIdArrayList();
-
-            if (visibleOnly) {
-                // Grouped opportunistic subscriptions should be hidden.
-                allSubs = allSubs.stream().filter(subId -> isSubscriptionVisible(subId))
-                        .collect(Collectors.toList());
-            }
-
-            int[] subIdArr = new int[allSubs.size()];
-            int i = 0;
-            for (int sub : allSubs) {
-                subIdArr[i] = sub;
-                i++;
-            }
-
-            if (VDBG) {
-                logdl("[getActiveSubIdList] allSubs=" + allSubs + " subIdArr.length="
-                        + subIdArr.length);
-            }
-            return subIdArr;
-        } finally {
-            Binder.restoreCallingIdentity(token);
+        if (visibleOnly) {
+            // Grouped opportunistic subscriptions should be hidden.
+            allSubs = allSubs.stream().filter(subId -> isSubscriptionVisible(subId))
+                    .collect(Collectors.toList());
         }
+
+        int[] subIdArr = new int[allSubs.size()];
+        int i = 0;
+        for (int sub : allSubs) {
+            subIdArr[i] = sub;
+            i++;
+        }
+
+        if (VDBG) {
+            logdl("[getActiveSubIdList] allSubs=" + allSubs + " subIdArr.length="
+                    + subIdArr.length);
+        }
+        return subIdArr;
     }
 
     @Override
@@ -3263,13 +3205,9 @@
             case SubscriptionManager.IMS_RCS_UCE_ENABLED:
             case SubscriptionManager.CROSS_SIM_CALLING_ENABLED:
             case SubscriptionManager.VOIMS_OPT_IN_STATUS:
-            case SubscriptionManager.NR_ADVANCED_CALLING_ENABLED:
-            case SubscriptionManager.USAGE_SETTING:
                 value.put(propKey, Integer.parseInt(propValue));
                 break;
             case SubscriptionManager.ALLOWED_NETWORK_TYPES:
-            case SimInfo.COLUMN_PHONE_NUMBER_SOURCE_CARRIER:
-            case SimInfo.COLUMN_PHONE_NUMBER_SOURCE_IMS:
                 value.put(propKey, propValue);
                 break;
             default:
@@ -3354,13 +3292,9 @@
                         case SubscriptionManager.GROUP_UUID:
                         case SubscriptionManager.DATA_ENABLED_OVERRIDE_RULES:
                         case SubscriptionManager.ALLOWED_NETWORK_TYPES:
-                        case SubscriptionManager.D2D_STATUS_SHARING:
                         case SubscriptionManager.VOIMS_OPT_IN_STATUS:
+                        case SubscriptionManager.D2D_STATUS_SHARING:
                         case SubscriptionManager.D2D_STATUS_SHARING_SELECTED_CONTACTS:
-                        case SubscriptionManager.NR_ADVANCED_CALLING_ENABLED:
-                        case SimInfo.COLUMN_PHONE_NUMBER_SOURCE_CARRIER:
-                        case SimInfo.COLUMN_PHONE_NUMBER_SOURCE_IMS:
-                        case SubscriptionManager.USAGE_SETTING:
                             resultValue = cursor.getString(0);
                             break;
                         default:
@@ -3948,9 +3882,9 @@
         selection.append(SubscriptionManager.ICC_ID);
         selection.append(" IN (");
         for (int i = 0; i < iccIds.length - 1; i++) {
-            selection.append("'" + iccIds[i] + "', ");
+            selection.append("\"" + iccIds[i] + "\", ");
         }
-        selection.append("'" + iccIds[iccIds.length - 1] + "'");
+        selection.append("\"" + iccIds[iccIds.length - 1] + "\"");
         selection.append(")");
 
         return selection.toString();
@@ -4137,8 +4071,7 @@
         // Can't find the existing SIM.
         if (slotInfo == null) return false;
 
-        // this for physical slot which has only one port
-        if (enable && !slotInfo.getPorts().stream().findFirst().get().isActive()) {
+        if (enable && !slotInfo.getIsActive()) {
             // We need to send intents to Euicc if we are turning on an inactive slot.
             // Euicc will decide whether to ask user to switch to DSDS, or change SIM
             // slot mapping.
@@ -4155,11 +4088,7 @@
                     PhoneConfigurationManager.getInstance().switchMultiSimConfig(
                             mTelephonyManager.getSupportedModemCount());
                 } else {
-                    List<UiccSlotMapping> slotMapping = new ArrayList<>();
-                    // As this is single sim mode, set port index to 0 and logical slot index is 0
-                    slotMapping.add(new UiccSlotMapping(TelephonyManager.DEFAULT_PORT_INDEX,
-                            physicalSlotIndex, 0));
-                    UiccController.getInstance().switchSlots(slotMapping, null);
+                    UiccController.getInstance().switchSlots(new int[]{physicalSlotIndex}, null);
                 }
             }
             return true;
@@ -4197,15 +4126,34 @@
                         + physicalSlotIndex, enabled ? 1 : 0);
     }
 
+    private int getPhysicalSlotIndex(boolean isEmbedded, int subId) {
+        UiccSlotInfo[] slotInfos = mTelephonyManager.getUiccSlotsInfo();
+        int logicalSlotIndex = getSlotIndex(subId);
+        int physicalSlotIndex = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
+        boolean isLogicalSlotIndexValid = SubscriptionManager.isValidSlotIndex(logicalSlotIndex);
+
+        for (int i = 0; i < slotInfos.length; i++) {
+            // If we can know the logicalSlotIndex from subId, we should find the exact matching
+            // physicalSlotIndex. However for some cases like inactive eSIM, the logicalSlotIndex
+            // will be -1. In this case, we assume there's only one eSIM, and return the
+            // physicalSlotIndex of that eSIM.
+            if ((isLogicalSlotIndexValid && slotInfos[i].getLogicalSlotIdx() == logicalSlotIndex)
+                    || (!isLogicalSlotIndexValid && slotInfos[i].getIsEuicc() && isEmbedded)) {
+                physicalSlotIndex = i;
+                break;
+            }
+        }
+
+        return physicalSlotIndex;
+    }
+
     private int getPhysicalSlotIndexFromLogicalSlotIndex(int logicalSlotIndex) {
         int physicalSlotIndex = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
         UiccSlotInfo[] slotInfos = mTelephonyManager.getUiccSlotsInfo();
         for (int i = 0; i < slotInfos.length; i++) {
-            for (UiccPortInfo portInfo : slotInfos[i].getPorts()) {
-                if (portInfo.getLogicalSlotIndex() == logicalSlotIndex) {
-                    physicalSlotIndex = i;
-                    break;
-                }
+            if (slotInfos[i].getLogicalSlotIdx() == logicalSlotIndex) {
+                physicalSlotIndex = i;
+                break;
             }
         }
 
@@ -4597,148 +4545,6 @@
         }
     }
 
-    /*
-     * Returns the phone number for the given {@code subId} and {@code source},
-     * or an empty string if not available.
-     */
-    @Override
-    public String getPhoneNumber(int subId, int source,
-            String callingPackage, String callingFeatureId) {
-        TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(
-                mContext, subId, Binder.getCallingUid(), "getPhoneNumber",
-                READ_PHONE_NUMBERS, READ_PRIVILEGED_PHONE_STATE);
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            String number = getPhoneNumber(subId, source);
-            return number == null ? "" : number;
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /*
-     * Returns the phone number for the given {@code subId} or an empty string if not available.
-     *
-     * <p>Built up on getPhoneNumber(int subId, int source) this API picks the 1st available
-     * source based on a priority order.
-     */
-    @Override
-    public String getPhoneNumberFromFirstAvailableSource(int subId,
-            String callingPackage, String callingFeatureId) {
-        TelephonyPermissions.enforceAnyPermissionGrantedOrCarrierPrivileges(
-                mContext, subId, Binder.getCallingUid(), "getPhoneNumberFromFirstAvailableSource",
-                READ_PHONE_NUMBERS, READ_PRIVILEGED_PHONE_STATE);
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            String numberFromCarrier = getPhoneNumber(
-                    subId, SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER);
-            if (!TextUtils.isEmpty(numberFromCarrier)) {
-                return numberFromCarrier;
-            }
-            String numberFromUicc = getPhoneNumber(
-                    subId, SubscriptionManager.PHONE_NUMBER_SOURCE_UICC);
-            if (!TextUtils.isEmpty(numberFromUicc)) {
-                return numberFromUicc;
-            }
-            String numberFromIms = getPhoneNumber(
-                    subId, SubscriptionManager.PHONE_NUMBER_SOURCE_IMS);
-            if (!TextUtils.isEmpty(numberFromIms)) {
-                return numberFromIms;
-            }
-            return "";
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    // Internal helper method for implementing getPhoneNumber() API.
-    @Nullable
-    private String getPhoneNumber(int subId, int source) {
-        if (source == SubscriptionManager.PHONE_NUMBER_SOURCE_UICC) {
-            Phone phone = PhoneFactory.getPhone(getPhoneId(subId));
-            return phone != null ? phone.getLine1Number() : null;
-        }
-        if (source == SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER) {
-            return getSubscriptionProperty(subId, SimInfo.COLUMN_PHONE_NUMBER_SOURCE_CARRIER);
-        }
-        if (source == SubscriptionManager.PHONE_NUMBER_SOURCE_IMS) {
-            return getSubscriptionProperty(subId, SimInfo.COLUMN_PHONE_NUMBER_SOURCE_IMS);
-        }
-        throw new IllegalArgumentException("setPhoneNumber doesn't accept source " + source);
-    }
-
-    /**
-     * Sets the phone number for the given {@code subId}.
-     *
-     * <p>The only accepted {@code source} is {@link
-     * SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER}.
-     */
-    @Override
-    public void setPhoneNumber(int subId, int source, String number,
-            String callingPackage, String callingFeatureId) {
-        if (source != SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER) {
-            throw new IllegalArgumentException("setPhoneNumber doesn't accept source " + source);
-        }
-        if (!TelephonyPermissions.checkCarrierPrivilegeForSubId(mContext, subId)) {
-            throw new SecurityException("setPhoneNumber for CARRIER needs carrier privilege");
-        }
-        if (number == null) {
-            throw new NullPointerException("invalid number null");
-        }
-
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            setSubscriptionProperty(subId, SimInfo.COLUMN_PHONE_NUMBER_SOURCE_CARRIER, number);
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-    }
-
-    /**
-     * Set the Usage Setting for this subscription.
-     *
-     * @param usageSetting the cellular usage setting
-     * @param subId the unique SubscriptionInfo index in database
-     * @param callingPackage the package making the IPC
-     * @return the number of records updated
-     *
-     * @throws SecurityException if doesn't have required permission.
-     */
-    @Override
-    public int setUsageSetting(@UsageSetting int usageSetting, int subId, String callingPackage) {
-        try {
-            TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivilege(
-                    mContext, subId, callingPackage);
-        } catch (SecurityException e) {
-            enforceCarrierPrivilegeOnInactiveSub(subId, callingPackage,
-                    "Caller requires permission on sub " + subId);
-        }
-
-        if (usageSetting < SubscriptionManager.USAGE_SETTING_DEFAULT
-                || usageSetting > SubscriptionManager.USAGE_SETTING_DATA_CENTRIC) {
-            throw new IllegalArgumentException("setUsageSetting: Invalid usage setting: "
-                    + usageSetting);
-        }
-
-        final long token = Binder.clearCallingIdentity();
-        int ret;
-        try {
-            ret = setSubscriptionProperty(subId, SubscriptionManager.USAGE_SETTING,
-                    String.valueOf(usageSetting));
-
-            // ret is the number of records updated in the DB, which should always be 1.
-            // TODO(b/205027930): move this check prior to the database mutation request
-            if (ret != 1) throw new IllegalArgumentException(
-                    "Invalid SubscriptionId for setUsageSetting");
-        } finally {
-            Binder.restoreCallingIdentity(token);
-            // FIXME(b/205726099) return void
-        }
-        return ret;
-    }
-
     /**
      * @hide
      */
@@ -4787,7 +4593,7 @@
     /**
      * @hide
      */
-    public static void invalidateActiveDataSubIdCaches() {
+    protected static void invalidateActiveDataSubIdCaches() {
         if (sCachingEnabled) {
             SubscriptionManager.invalidateActiveDataSubIdCaches();
         }
diff --git a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
index 3ab229a..36751a3 100644
--- a/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
+++ b/src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java
@@ -27,7 +27,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
-import android.content.res.Resources;
 import android.os.AsyncResult;
 import android.os.Build;
 import android.os.Handler;
@@ -38,13 +37,13 @@
 import android.os.UserHandle;
 import android.preference.PreferenceManager;
 import android.service.carrier.CarrierIdentifier;
+import android.service.carrier.CarrierService;
 import android.service.euicc.EuiccProfileInfo;
 import android.service.euicc.EuiccService;
 import android.service.euicc.GetEuiccProfileInfoListResult;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
-import android.telephony.SubscriptionManager.UsageSetting;
 import android.telephony.TelephonyManager;
 import android.telephony.TelephonyManager.SimState;
 import android.telephony.UiccAccessRule;
@@ -59,7 +58,6 @@
 import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UiccSlot;
 import com.android.telephony.Rlog;
 
@@ -67,7 +65,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.concurrent.CopyOnWriteArraySet;
 
 /**
  *@hide
@@ -122,28 +119,6 @@
     private int mCurrentlyActiveUserId;
     private CarrierServiceBindHelper mCarrierServiceBindHelper;
 
-    private volatile boolean shouldRetryUpdateEmbeddedSubscriptions = false;
-    private final CopyOnWriteArraySet<Integer> retryUpdateEmbeddedSubscriptionCards =
-        new CopyOnWriteArraySet<>();
-    private final BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
-                // The LPA may not have been ready before user unlock, and so previous attempts
-                // to refresh the list of embedded subscriptions may have failed. This retries
-                // the refresh operation after user unlock.
-                if (shouldRetryUpdateEmbeddedSubscriptions) {
-                    logd("Retrying refresh embedded subscriptions after user unlock.");
-                    for (int cardId : retryUpdateEmbeddedSubscriptionCards){
-                        requestEmbeddedSubscriptionInfoListRefresh(cardId, null);
-                    }
-                    retryUpdateEmbeddedSubscriptionCards.clear();
-                    sContext.unregisterReceiver(mUserUnlockedReceiver);
-                }
-            }
-        }
-    };
-
     /**
      * Runnable with a boolean parameter. This is used in
      * updateEmbeddedSubscriptions(List<Integer> cardIds, @Nullable UpdateEmbeddedSubsCallback).
@@ -168,10 +143,6 @@
         mEuiccManager = (EuiccManager) sContext.getSystemService(Context.EUICC_SERVICE);
 
         mCarrierServiceBindHelper = new CarrierServiceBindHelper(sContext);
-
-        sContext.registerReceiver(
-                mUserUnlockedReceiver, new IntentFilter(Intent.ACTION_USER_UNLOCKED));
-
         initializeCarrierApps();
 
         PhoneConfigurationManager.registerForMultiSimConfigChange(
@@ -216,12 +187,12 @@
     }
 
     /**
-     * Update subscriptions if needed when there's a change in inactive port.
-     * @param prevActivePhoneId is the corresponding phoneId of the port if port was previously
+     * Update subscriptions if needed when there's a change in inactive slot.
+     * @param prevActivePhoneId is the corresponding phoneId of the slot if slot was previously
      *                          active. It could be INVALID if it was already inactive.
-     * @param iccId iccId in that port, if any.
+     * @param iccId iccId in that slot, if any.
      */
-    public void updateInternalIccStateForInactivePort(int prevActivePhoneId, String iccId) {
+    public void updateInternalIccStateForInactiveSlot(int prevActivePhoneId, String iccId) {
         sendMessage(obtainMessage(EVENT_INACTIVE_SLOT_ICC_STATE_CHANGED, prevActivePhoneId,
                 0, iccId));
     }
@@ -248,16 +219,12 @@
         for (int i = 0; i < TelephonyManager.getDefault().getActiveModemCount(); i++) {
             UiccSlot slot = UiccController.getInstance().getUiccSlotForPhone(i);
             int slotId = UiccController.getInstance().getSlotIdFromPhoneId(i);
-            // When psim card is absent there is no port object even the port state is active.
-            // We should check the slot state for psim and port state for esim(MEP eUICC).
-            if  (sIccId[i] == null || slot == null || !slot.isActive()
-                    || (slot.isEuicc() && UiccController.getInstance().getUiccPort(i) == null)) {
+            if  (sIccId[i] == null || slot == null || !slot.isActive()) {
                 if (sIccId[i] == null) {
                     logd("Wait for SIM " + i + " Iccid");
                 } else {
-                    logd(String.format("Wait for port corresponding to phone %d to be active, "
-                        + "slotId is %d" + " , portIndex is %d", i, slotId,
-                            slot.getPortIndexFromPhoneId(i)));
+                    logd(String.format("Wait for slot corresponding to phone %d to be active, "
+                            + "slotId is %d", i, slotId));
                 }
                 return false;
             }
@@ -294,7 +261,7 @@
                 break;
 
             case EVENT_INACTIVE_SLOT_ICC_STATE_CHANGED:
-                handleInactivePortIccStateChange(msg.arg1, (String) msg.obj);
+                handleInactiveSlotIccStateChange(msg.arg1, (String) msg.obj);
                 break;
 
             case EVENT_SIM_LOCKED:
@@ -448,10 +415,9 @@
         }
 
         // ICCID is not available in IccRecords by the time SIM Ready event received
-        // hence get ICCID from UiccPort.
-        UiccPort port = UiccController.getInstance().getUiccPort(phoneId);
-        String iccId = (port == null) ? null : IccUtils.stripTrailingFs(port.getIccId());
-
+        // hence get ICCID from UiccSlot.
+        UiccSlot uiccSlot = UiccController.getInstance().getUiccSlotForPhone(phoneId);
+        String iccId = (uiccSlot != null) ? IccUtils.stripTrailingFs(uiccSlot.getIccId()) : null;
         if (!TextUtils.isEmpty(iccId)) {
             sIccId[phoneId] = iccId;
             updateSubscriptionInfoByIccId(phoneId, true /* updateEmbeddedSubs */);
@@ -476,9 +442,8 @@
         boolean uiccAppsDisabled = areUiccAppsDisabledOnCard(phoneId);
         if (iccCard.isEmptyProfile() || uiccAppsDisabled) {
             if (uiccAppsDisabled) {
-                UiccPort port = UiccController.getInstance().getUiccPort(phoneId);
-                String iccId = (port == null) ? null : port.getIccId();
-                sInactiveIccIds[phoneId] = IccUtils.stripTrailingFs(iccId);
+                UiccSlot slot = UiccController.getInstance().getUiccSlotForPhone(phoneId);
+                sInactiveIccIds[phoneId] = IccUtils.stripTrailingFs(slot.getIccId());
             }
             isFinalState = true;
             // ICC_NOT_READY is a terminal state for
@@ -506,15 +471,10 @@
         // cardStatus (since IRadio 1.2). Amd upon cardStatus change we'll receive another
         // handleSimNotReady so this will be evaluated again.
         UiccSlot slot = UiccController.getInstance().getUiccSlotForPhone(phoneId);
-        if (slot == null) return false;
-        UiccPort port = UiccController.getInstance().getUiccPort(phoneId);
-        String iccId = (port == null) ? null : port.getIccId();
-        if (iccId == null) {
-            return false;
-        }
+        if (slot == null || slot.getIccId() == null) return false;
         SubscriptionInfo info =
                 mSubscriptionController.getSubInfoForIccId(
-                        IccUtils.stripTrailingFs(iccId));
+                        IccUtils.stripTrailingFs(slot.getIccId()));
         return info != null && !info.areUiccApplicationsEnabled();
     }
 
@@ -631,72 +591,12 @@
         updateCarrierServices(phoneId, IccCardConstants.INTENT_VALUE_ICC_LOADED);
     }
 
-    /**
-     * Calculate the usage setting based on the carrier request.
-     *
-     * @param currentUsageSetting the current setting in the subscription DB
-     * @param preferredUsageSetting provided by the carrier config
-     * @return the calculated usage setting.
-     */
-    @VisibleForTesting
-    @UsageSetting public int calculateUsageSetting(
-            @UsageSetting int currentUsageSetting, @UsageSetting int preferredUsageSetting) {
-        int defaultUsageSetting;
-        int[] supportedUsageSettings;
-
-        //  Load the resources to provide the device capability
-        try {
-            defaultUsageSetting = sContext.getResources().getInteger(
-                com.android.internal.R.integer.config_default_cellular_usage_setting);
-            supportedUsageSettings = sContext.getResources().getIntArray(
-                com.android.internal.R.array.config_supported_cellular_usage_settings);
-            // If usage settings are not supported, return the default setting, which is UNKNOWN.
-            if (supportedUsageSettings == null
-                    || supportedUsageSettings.length < 1) return currentUsageSetting;
-        } catch (Resources.NotFoundException nfe) {
-            loge("Failed to load usage setting resources!");
-            return currentUsageSetting;
-        }
-
-        // If the current setting is invalid, including the first time the value is set,
-        // update it to default (this will trigger a change in the DB).
-        if (currentUsageSetting < SubscriptionManager.USAGE_SETTING_DEFAULT
-                || currentUsageSetting > SubscriptionManager.USAGE_SETTING_DATA_CENTRIC) {
-            logd("Updating usage setting for current subscription");
-            currentUsageSetting = SubscriptionManager.USAGE_SETTING_DEFAULT;
-        }
-
-        // Range check the inputs, and on failure, make no changes
-        if (preferredUsageSetting < SubscriptionManager.USAGE_SETTING_DEFAULT
-                || preferredUsageSetting > SubscriptionManager.USAGE_SETTING_DATA_CENTRIC) {
-            loge("Invalid usage setting!" + preferredUsageSetting);
-            return currentUsageSetting;
-        }
-
-        // Default is always allowed
-        if (preferredUsageSetting == SubscriptionManager.USAGE_SETTING_DEFAULT) {
-            return preferredUsageSetting;
-        }
-
-        // Forced setting must be explicitly supported
-        for (int i = 0; i < supportedUsageSettings.length; i++) {
-            if (preferredUsageSetting == supportedUsageSettings[i]) return preferredUsageSetting;
-        }
-
-        // If the preferred setting is not possible, just keep the current setting.
-        return currentUsageSetting;
-    }
-
     private void restoreSimSpecificSettingsForPhone(int phoneId) {
         SubscriptionManager subManager = SubscriptionManager.from(sContext);
         subManager.restoreSimSpecificSettingsForIccIdFromBackup(sIccId[phoneId]);
     }
 
     private void updateCarrierServices(int phoneId, String simState) {
-        if (!SubscriptionManager.isValidPhoneId(phoneId)) {
-            logd("Ignore updateCarrierServices request with invalid phoneId " + phoneId);
-            return;
-        }
         CarrierConfigManager configManager =
                 (CarrierConfigManager) sContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
         configManager.updateConfigForPhoneId(phoneId, simState);
@@ -710,10 +610,10 @@
     }
 
     /**
-     * PhoneId is the corresponding phoneId of the port if port was previously active.
+     * PhoneId is the corresponding phoneId of the slot if slot was previously active.
      * It could be INVALID if it was already inactive.
      */
-    private void handleInactivePortIccStateChange(int phoneId, String iccId) {
+    private void handleInactiveSlotIccStateChange(int phoneId, String iccId) {
         if (SubscriptionManager.isValidPhoneId(phoneId)) {
             // If phoneId is valid, it means the physical slot was previously active in that
             // phoneId. In this case, found the subId and set its phoneId to invalid.
@@ -759,12 +659,8 @@
             }
             String iccId = sInactiveIccIds[phoneId] != null
                     ? sInactiveIccIds[phoneId] : sIccId[phoneId];
-            ContentValues value = new ContentValues();
+            ContentValues value = new ContentValues(1);
             value.put(SubscriptionManager.UICC_APPLICATIONS_ENABLED, true);
-            if (isSimAbsent) {
-                // When sim is absent, set the port index to invalid port index -1;
-                value.put(SubscriptionManager.PORT_INDEX, TelephonyManager.INVALID_PORT_INDEX);
-            }
             sContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value,
                     SubscriptionManager.ICC_ID + "=\'" + iccId + "\'", null);
             sInactiveIccIds[phoneId] = null;
@@ -914,7 +810,6 @@
         // Do nothing if eUICCs are disabled. (Previous entries may remain in the cache, but they
         // are filtered out of list calls as long as EuiccManager.isEnabled returns false).
         if (!mEuiccManager.isEnabled()) {
-            if (DBG) logd("updateEmbeddedSubscriptions: eUICC not enabled");
             callback.run(false /* hasChanges */);
             return;
         }
@@ -959,9 +854,7 @@
         if (DBG) logd("updateEmbeddedSubscriptionsCache");
 
         if (result == null) {
-            if (DBG) logd("updateEmbeddedSubscriptionsCache: IPC to the eUICC controller failed");
-            retryUpdateEmbeddedSubscriptionCards.add(cardId);
-            shouldRetryUpdateEmbeddedSubscriptions = true;
+            // IPC to the eUICC controller failed.
             return false;
         }
 
@@ -1047,8 +940,6 @@
                         SubscriptionManager.NAME_SOURCE_CARRIER);
             }
             values.put(SubscriptionManager.PROFILE_CLASS, embeddedProfile.getProfileClass());
-            values.put(SubscriptionManager.PORT_INDEX,
-                    getEmbeddedProfilePortIndex(embeddedProfile.getIccid()));
             CarrierIdentifier cid = embeddedProfile.getCarrierIdentifier();
             if (cid != null) {
                 // Due to the limited subscription information, carrier id identified here might
@@ -1075,7 +966,7 @@
             }
             hasChanges = true;
             contentResolver.update(SubscriptionManager.CONTENT_URI, values,
-                    SubscriptionManager.ICC_ID + "='" + embeddedProfile.getIccid() + "'", null);
+                    SubscriptionManager.ICC_ID + "=\"" + embeddedProfile.getIccid() + "\"", null);
 
             // refresh Cached Active Subscription Info List
             mSubscriptionController.refreshCachedActiveSubscriptionInfoList();
@@ -1095,7 +986,7 @@
                 SubscriptionInfo info = existingSubscriptions.get(i);
                 if (info.isEmbedded()) {
                     if (DBG) logd("Removing embedded subscription of IccId " + info.getIccId());
-                    iccidsToRemove.add("'" + info.getIccId() + "'");
+                    iccidsToRemove.add("\"" + info.getIccId() + "\"");
                 }
             }
             String whereClause = SubscriptionManager.ICC_ID + " IN ("
@@ -1113,16 +1004,6 @@
         return hasChanges;
     }
 
-    private int getEmbeddedProfilePortIndex(String iccId) {
-        UiccSlot[] slots = UiccController.getInstance().getUiccSlots();
-        for (UiccSlot slot : slots) {
-            if (slot != null && slot.isEuicc()
-                    && slot.getPortIndexFromIccId(iccId) != TelephonyManager.INVALID_PORT_INDEX) {
-                return slot.getPortIndexFromIccId(iccId);
-            }
-        }
-        return TelephonyManager.INVALID_PORT_INDEX;
-    }
     /**
      * Called by CarrierConfigLoader to update the subscription before sending a broadcast.
      */
@@ -1143,10 +1024,11 @@
     private boolean isCarrierServicePackage(int phoneId, String pkgName) {
         if (pkgName.equals(getDefaultCarrierServicePackageName())) return false;
 
-        String carrierPackageName = TelephonyManager.from(sContext)
-                .getCarrierServicePackageNameForLogicalSlot(phoneId);
-        if (DBG) logd("Carrier service package for subscription = " + carrierPackageName);
-        return pkgName.equals(carrierPackageName);
+        List<String> carrierPackageNames = TelephonyManager.from(sContext)
+                .getCarrierPackageNamesForIntentAndPhone(
+                        new Intent(CarrierService.CARRIER_SERVICE_INTERFACE), phoneId);
+        if (DBG) logd("Carrier Packages For Subscription = " + carrierPackageNames);
+        return carrierPackageNames != null && carrierPackageNames.contains(pkgName);
     }
 
     /**
@@ -1224,33 +1106,6 @@
                 }
             }
         }
-
-        final int preferredUsageSetting =
-                config.getInt(
-                        CarrierConfigManager.KEY_CELLULAR_USAGE_SETTING_INT,
-                        SubscriptionManager.USAGE_SETTING_UNKNOWN);
-
-        @UsageSetting int newUsageSetting = calculateUsageSetting(
-                currentSubInfo.getUsageSetting(),
-                preferredUsageSetting);
-
-        if (newUsageSetting != currentSubInfo.getUsageSetting()) {
-            cv.put(SubscriptionManager.USAGE_SETTING, newUsageSetting);
-            if (DBG) {
-                logd("UsageSetting changed,"
-                        + " oldSetting=" + currentSubInfo.getUsageSetting()
-                        + " preferredSetting=" + preferredUsageSetting
-                        + " newSetting=" + newUsageSetting);
-            }
-        } else {
-            if (DBG) {
-                logd("UsageSetting unchanged,"
-                        + " oldSetting=" + currentSubInfo.getUsageSetting()
-                        + " preferredSetting=" + preferredUsageSetting
-                        + " newSetting=" + newUsageSetting);
-            }
-        }
-
         if (cv.size() > 0 && sContext.getContentResolver().update(SubscriptionManager
                     .getUriForSubscriptionId(currentSubId), cv, null, null) > 0) {
             mSubscriptionController.refreshCachedActiveSubscriptionInfoList();
@@ -1293,15 +1148,10 @@
             SubscriptionManager.putPhoneIdAndSubIdExtra(i, phoneId);
             // TODO(b/130664115) we manually populate this intent with the slotId. In the future we
             // should do a review of whether to make this public
-            UiccSlot slot = UiccController.getInstance().getUiccSlotForPhone(phoneId);
             int slotId = UiccController.getInstance().getSlotIdFromPhoneId(phoneId);
             i.putExtra(PhoneConstants.SLOT_KEY, slotId);
-            if (slot != null) {
-                i.putExtra(PhoneConstants.PORT_KEY, slot.getPortIndexFromPhoneId(phoneId));
-            }
             logd("Broadcasting intent ACTION_SIM_CARD_STATE_CHANGED " + simStateString(state)
-                    + " for phone: " + phoneId + " slot: " + slotId + " port: "
-                    + slot.getPortIndexFromPhoneId(phoneId));
+                    + " for phone: " + phoneId + " slot: " + slotId);
             sContext.sendBroadcast(i, Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
             TelephonyMetrics.getInstance().updateSimState(phoneId, state);
         }
@@ -1325,15 +1175,10 @@
             SubscriptionManager.putPhoneIdAndSubIdExtra(i, phoneId);
             // TODO(b/130664115) we populate this intent with the actual slotId. In the future we
             // should do a review of whether to make this public
-            UiccSlot slot = UiccController.getInstance().getUiccSlotForPhone(phoneId);
             int slotId = UiccController.getInstance().getSlotIdFromPhoneId(phoneId);
             i.putExtra(PhoneConstants.SLOT_KEY, slotId);
-            if (slot != null) {
-                i.putExtra(PhoneConstants.PORT_KEY, slot.getPortIndexFromPhoneId(phoneId));
-            }
             logd("Broadcasting intent ACTION_SIM_APPLICATION_STATE_CHANGED " + simStateString(state)
-                    + " for phone: " + phoneId + " slot: " + slotId + "port: "
-                    + slot.getPortIndexFromPhoneId(phoneId));
+                    + " for phone: " + phoneId + " slot: " + slotId);
             sContext.sendBroadcast(i, Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
             TelephonyMetrics.getInstance().updateSimState(phoneId, state);
         }
diff --git a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
index dcbd2d5..4632a60 100644
--- a/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
+++ b/src/java/com/android/internal/telephony/TelephonyComponentFactory.java
@@ -33,15 +33,9 @@
 import com.android.ims.ImsManager;
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.telephony.cdma.EriManager;
-import com.android.internal.telephony.data.AccessNetworksManager;
-import com.android.internal.telephony.data.DataNetworkController;
-import com.android.internal.telephony.data.DataProfileManager;
-import com.android.internal.telephony.data.DataServiceManager;
-import com.android.internal.telephony.data.DataSettingsManager;
-import com.android.internal.telephony.data.LinkBandwidthEstimator;
-import com.android.internal.telephony.data.PhoneSwitcher;
 import com.android.internal.telephony.dataconnection.DataEnabledSettings;
 import com.android.internal.telephony.dataconnection.DcTracker;
+import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator;
 import com.android.internal.telephony.dataconnection.TransportManager;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
@@ -390,7 +384,7 @@
 
     public ImsExternalCallTracker makeImsExternalCallTracker(ImsPhone imsPhone) {
 
-        return new ImsExternalCallTracker(imsPhone, imsPhone.getContext().getMainExecutor());
+        return new ImsExternalCallTracker(imsPhone);
     }
 
     /**
@@ -408,17 +402,6 @@
         return new TransportManager(phone);
     }
 
-    /**
-     * Make access networks manager
-     *
-     * @param phone The phone instance
-     * @param looper Looper for the handler.
-     * @return The access networks manager
-     */
-    public AccessNetworksManager makeAccessNetworksManager(Phone phone, Looper looper) {
-        return new AccessNetworksManager(phone, looper);
-    }
-
     public CdmaSubscriptionSourceManager
     getCdmaSubscriptionSourceManagerInstance(Context context, CommandsInterface ci, Handler h,
                                              int what, Object obj) {
@@ -462,13 +445,6 @@
         return MultiSimSettingController.init(c, sc);
     }
 
-    /**
-     * Create a new SignalStrengthController instance.
-     */
-    public SignalStrengthController makeSignalStrengthController(GsmCdmaPhone phone) {
-        return new SignalStrengthController(phone);
-    }
-
     public SubscriptionInfoUpdater makeSubscriptionInfoUpdater(Looper looper, Context context,
             SubscriptionController sc) {
         return new SubscriptionInfoUpdater(looper, context, sc);
@@ -480,51 +456,4 @@
     public LinkBandwidthEstimator makeLinkBandwidthEstimator(Phone phone) {
         return new LinkBandwidthEstimator(phone, mTelephonyFacade);
     }
-
-    /**
-     * Create a new data network controller instance. The instance is per-SIM. On multi-sim devices,
-     * there will be multiple {@link DataNetworkController} instances.
-     *
-     * @param phone The phone object
-     * @param looper The looper for event handling
-     * @return The data network controller instance
-     */
-    public DataNetworkController makeDataNetworkController(Phone phone, Looper looper) {
-        return new DataNetworkController(phone, looper);
-    }
-
-    /**
-     * Create data profile manager.
-     *
-     * @param phone The phone instance.
-     * @param dataNetworkController Data network controller instance.
-     * @param dataServiceManager Data service manager instance.
-     * @param looper The looper to be used by the handler. Currently the handler thread is the phone
-     * process's main thread.
-     * @param callback Callback for passing events back to data network controller.
-     * @return The data profile manager instance.
-     */
-    public @NonNull DataProfileManager makeDataProfileManager(@NonNull Phone phone,
-            @NonNull DataNetworkController dataNetworkController,
-            @NonNull DataServiceManager dataServiceManager, @NonNull Looper looper,
-            @NonNull DataProfileManager.DataProfileManagerCallback callback) {
-        return new DataProfileManager(phone, dataNetworkController, dataServiceManager, looper,
-                callback);
-    }
-
-    /**
-     * Create data settings manager.
-     *
-     * @param phone The phone instance.
-     * @param dataNetworkController Data network controller instance.
-     * @param looper The looper to be used by the handler. Currently the handler thread is the phone
-     * process's main thread.
-     * @param callback Callback for passing events back to data network controller.
-     * @return The data settings manager instance.
-     */
-    public @NonNull DataSettingsManager makeDataSettingsManager(@NonNull Phone phone,
-            @NonNull DataNetworkController dataNetworkController, @NonNull Looper looper,
-            @NonNull DataSettingsManager.DataSettingsManagerCallback callback) {
-        return new DataSettingsManager(phone, dataNetworkController, looper, callback);
-    }
 }
diff --git a/src/java/com/android/internal/telephony/TelephonyTester.java b/src/java/com/android/internal/telephony/TelephonyTester.java
index 40bb212..364b18d 100644
--- a/src/java/com/android/internal/telephony/TelephonyTester.java
+++ b/src/java/com/android/internal/telephony/TelephonyTester.java
@@ -46,7 +46,6 @@
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -250,8 +249,7 @@
 
             filter.addAction(ACTION_TEST_CHANGE_NUMBER);
             log("register for intent action=" + ACTION_TEST_CHANGE_NUMBER);
-            phone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone.getHandler(),
-                    Context.RECEIVER_EXPORTED);
+            phone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone.getHandler());
         }
     }
 
@@ -404,12 +402,9 @@
             log("Override data service state with " + ss.getDataRegistrationState());
         }
         if (mServiceStateTestIntent.hasExtra(EXTRA_OPERATOR)) {
-            String[] data = mServiceStateTestIntent.getStringExtra(EXTRA_OPERATOR).split(",");
-            String operatorAlphaLong = data.length > 0 ? data[0] : "";
-            String operatorAlphaShort = data.length > 1 ? data[1] : operatorAlphaLong;
-            String operatorNumeric = data.length > 2 ? data[2] : "";
-            ss.setOperatorName(operatorAlphaLong, operatorAlphaShort, operatorNumeric);
-            log("Override operator with " + Arrays.toString(data));
+            String operator = mServiceStateTestIntent.getStringExtra(EXTRA_OPERATOR);
+            ss.setOperatorName(operator, operator, "");
+            log("Override operator with " + operator);
         }
         if (mServiceStateTestIntent.hasExtra(EXTRA_OPERATOR_RAW)) {
             String operator_raw = mServiceStateTestIntent.getStringExtra(EXTRA_OPERATOR_RAW);
diff --git a/src/java/com/android/internal/telephony/VisualVoicemailSmsFilter.java b/src/java/com/android/internal/telephony/VisualVoicemailSmsFilter.java
index 5bbe8b4..3ea5fc2 100644
--- a/src/java/com/android/internal/telephony/VisualVoicemailSmsFilter.java
+++ b/src/java/com/android/internal/telephony/VisualVoicemailSmsFilter.java
@@ -84,7 +84,7 @@
                         return null;
                     }
                     return new PhoneAccountHandle(PSTN_CONNECTION_SERVICE_COMPONENT,
-                            Integer.toString(PhoneFactory.getPhone(phoneId).getSubId()));
+                            PhoneFactory.getPhone(phoneId).getFullIccSerialNumber());
                 }
             };
 
diff --git a/src/java/com/android/internal/telephony/VoiceIndication.java b/src/java/com/android/internal/telephony/VoiceIndication.java
deleted file mode 100644
index 4ed82a6..0000000
--- a/src/java/com/android/internal/telephony/VoiceIndication.java
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CALL_RING;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_CALL_WAITING;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_INFO_REC;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_CDMA_OTA_PROVISION_STATUS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_EMERGENCY_NUMBER_LIST;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ON_SS;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_ON_USSD;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESEND_INCALL_MUTE;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_RINGBACK_TONE;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_SRVCC_STATE_NOTIFY;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_CALL_SETUP;
-import static com.android.internal.telephony.RILConstants.RIL_UNSOL_STK_CC_ALPHA_NOTIFY;
-
-import android.hardware.radio.voice.IRadioVoiceIndication;
-import android.os.AsyncResult;
-import android.telephony.emergency.EmergencyNumber;
-
-import com.android.internal.telephony.cdma.CdmaCallWaitingNotification;
-import com.android.internal.telephony.cdma.CdmaInformationRecords;
-import com.android.internal.telephony.gsm.SsData;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Interface declaring unsolicited radio indications for voice APIs.
- */
-public class VoiceIndication extends IRadioVoiceIndication.Stub {
-    private final RIL mRil;
-
-    public VoiceIndication(RIL ril) {
-        mRil = ril;
-    }
-
-    /**
-     * Ring indication for an incoming call (eg, RING or CRING event).
-     * The rate of these events is controlled by ro.telephony.call_ring.delay and has a default
-     * value of 3000 (3 seconds) if absent.
-     * @param indicationType Type of radio indication
-     * @param isGsm true for GSM & false for CDMA
-     * @param record CDMA signal information record
-     */
-    public void callRing(int indicationType, boolean isGsm,
-            android.hardware.radio.voice.CdmaSignalInfoRecord record) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        char[] response = null;
-
-        // Ignore record for gsm
-        if (!isGsm) {
-            // TODO: Clean this up with a parcelable class for better self-documentation
-            response = new char[4];
-            response[0] = (char) (record.isPresent ? 1 : 0);
-            response[1] = (char) record.signalType;
-            response[2] = (char) record.alertPitch;
-            response[3] = (char) record.signal;
-            mRil.writeMetricsCallRing(response);
-        }
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CALL_RING, response);
-
-        if (mRil.mRingRegistrant != null) {
-            mRil.mRingRegistrant.notifyRegistrant(new AsyncResult(null, response, null));
-        }
-    }
-
-    /**
-     * Indicates when call state has changed. Redundant or extraneous invocations are tolerated.
-     * @param indicationType Type of radio indication
-     */
-    public void callStateChanged(int indicationType) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED);
-
-        mRil.mCallStateRegistrants.notifyRegistrants();
-    }
-
-    /**
-     * Indicates when CDMA radio receives a call waiting indication.
-     * @param indicationType Type of radio indication
-     * @param callWaitingRecord Cdma CallWaiting information
-     */
-    public void cdmaCallWaiting(int indicationType,
-            android.hardware.radio.voice.CdmaCallWaiting callWaitingRecord) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        // TODO: create a CdmaCallWaitingNotification constructor that takes in these fields to make
-        // sure no fields are missing
-        CdmaCallWaitingNotification notification = new CdmaCallWaitingNotification();
-        notification.number = callWaitingRecord.number;
-        notification.numberPresentation = CdmaCallWaitingNotification.presentationFromCLIP(
-                callWaitingRecord.numberPresentation);
-        notification.name = callWaitingRecord.name;
-        notification.namePresentation = notification.numberPresentation;
-        notification.isPresent = callWaitingRecord.signalInfoRecord.isPresent ? 1 : 0;
-        notification.signalType = callWaitingRecord.signalInfoRecord.signalType;
-        notification.alertPitch = callWaitingRecord.signalInfoRecord.alertPitch;
-        notification.signal = callWaitingRecord.signalInfoRecord.signal;
-        notification.numberType = callWaitingRecord.numberType;
-        notification.numberPlan = callWaitingRecord.numberPlan;
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CDMA_CALL_WAITING, notification);
-
-        mRil.mCallWaitingInfoRegistrants.notifyRegistrants(
-                new AsyncResult(null, notification, null));
-    }
-
-    /**
-     * Indicates when CDMA radio receives one or more info recs.
-     * @param indicationType Type of radio indication
-     * @param records New CDMA information
-     */
-    public void cdmaInfoRec(int indicationType,
-            android.hardware.radio.voice.CdmaInformationRecord[] records) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        for (int i = 0; i < records.length; i++) {
-            android.hardware.radio.voice.CdmaInformationRecord record = records[i];
-            int id = record.name;
-            CdmaInformationRecords cdmaInformationRecords;
-            switch (id) {
-                case CdmaInformationRecords.RIL_CDMA_DISPLAY_INFO_REC:
-                case CdmaInformationRecords.RIL_CDMA_EXTENDED_DISPLAY_INFO_REC:
-                    CdmaInformationRecords.CdmaDisplayInfoRec cdmaDisplayInfoRec =
-                            new CdmaInformationRecords.CdmaDisplayInfoRec(id,
-                                    record.display[0].alphaBuf);
-                    cdmaInformationRecords = new CdmaInformationRecords(cdmaDisplayInfoRec);
-                    break;
-
-                case CdmaInformationRecords.RIL_CDMA_CALLED_PARTY_NUMBER_INFO_REC:
-                case CdmaInformationRecords.RIL_CDMA_CALLING_PARTY_NUMBER_INFO_REC:
-                case CdmaInformationRecords.RIL_CDMA_CONNECTED_NUMBER_INFO_REC:
-                    android.hardware.radio.voice.CdmaNumberInfoRecord numInfoRecord =
-                            record.number[0];
-                    CdmaInformationRecords.CdmaNumberInfoRec cdmaNumberInfoRec =
-                            new CdmaInformationRecords.CdmaNumberInfoRec(id, numInfoRecord.number,
-                                    numInfoRecord.numberType, numInfoRecord.numberPlan,
-                                    numInfoRecord.pi, numInfoRecord.si);
-                    cdmaInformationRecords = new CdmaInformationRecords(cdmaNumberInfoRec);
-                    break;
-
-                case CdmaInformationRecords.RIL_CDMA_SIGNAL_INFO_REC:
-                    android.hardware.radio.voice.CdmaSignalInfoRecord signalInfoRecord =
-                            record.signal[0];
-                    CdmaInformationRecords.CdmaSignalInfoRec cdmaSignalInfoRec =
-                            new CdmaInformationRecords.CdmaSignalInfoRec(
-                                    signalInfoRecord.isPresent ? 1 : 0, signalInfoRecord.signalType,
-                                    signalInfoRecord.alertPitch, signalInfoRecord.signal);
-                    cdmaInformationRecords = new CdmaInformationRecords(cdmaSignalInfoRec);
-                    break;
-
-                case CdmaInformationRecords.RIL_CDMA_REDIRECTING_NUMBER_INFO_REC:
-                    android.hardware.radio.voice.CdmaRedirectingNumberInfoRecord
-                            redirectingNumberInfoRecord = record.redir[0];
-                    CdmaInformationRecords.CdmaRedirectingNumberInfoRec
-                            cdmaRedirectingNumberInfoRec =
-                            new CdmaInformationRecords.CdmaRedirectingNumberInfoRec(
-                                    redirectingNumberInfoRecord.redirectingNumber.number,
-                                    redirectingNumberInfoRecord.redirectingNumber.numberType,
-                                    redirectingNumberInfoRecord.redirectingNumber.numberPlan,
-                                    redirectingNumberInfoRecord.redirectingNumber.pi,
-                                    redirectingNumberInfoRecord.redirectingNumber.si,
-                                    redirectingNumberInfoRecord.redirectingReason);
-                    cdmaInformationRecords = new CdmaInformationRecords(
-                            cdmaRedirectingNumberInfoRec);
-                    break;
-
-                case CdmaInformationRecords.RIL_CDMA_LINE_CONTROL_INFO_REC:
-                    android.hardware.radio.voice.CdmaLineControlInfoRecord lineControlInfoRecord =
-                            record.lineCtrl[0];
-                    CdmaInformationRecords.CdmaLineControlInfoRec cdmaLineControlInfoRec =
-                            new CdmaInformationRecords.CdmaLineControlInfoRec(
-                                    lineControlInfoRecord.lineCtrlPolarityIncluded,
-                                    lineControlInfoRecord.lineCtrlToggle,
-                                    lineControlInfoRecord.lineCtrlReverse,
-                                    lineControlInfoRecord.lineCtrlPowerDenial);
-                    cdmaInformationRecords = new CdmaInformationRecords(cdmaLineControlInfoRec);
-                    break;
-
-                case CdmaInformationRecords.RIL_CDMA_T53_CLIR_INFO_REC:
-                    CdmaInformationRecords.CdmaT53ClirInfoRec cdmaT53ClirInfoRec =
-                            new CdmaInformationRecords.CdmaT53ClirInfoRec(record.clir[0].cause);
-                    cdmaInformationRecords = new CdmaInformationRecords(cdmaT53ClirInfoRec);
-                    break;
-
-                case CdmaInformationRecords.RIL_CDMA_T53_AUDIO_CONTROL_INFO_REC:
-                    android.hardware.radio.voice.CdmaT53AudioControlInfoRecord
-                            audioControlInfoRecord = record.audioCtrl[0];
-                    CdmaInformationRecords.CdmaT53AudioControlInfoRec cdmaT53AudioControlInfoRec =
-                            new CdmaInformationRecords.CdmaT53AudioControlInfoRec(
-                                    audioControlInfoRecord.upLink,
-                                    audioControlInfoRecord.downLink);
-                    cdmaInformationRecords = new CdmaInformationRecords(cdmaT53AudioControlInfoRec);
-                    break;
-
-                default:
-                    throw new RuntimeException("RIL_UNSOL_CDMA_INFO_REC: unsupported record. Got "
-                            + CdmaInformationRecords.idToString(id) + " ");
-            }
-
-            if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CDMA_INFO_REC, cdmaInformationRecords);
-            mRil.notifyRegistrantsCdmaInfoRec(cdmaInformationRecords);
-        }
-    }
-
-    /**
-     * Indicates when CDMA radio receives an update of the progress of an OTASP/OTAPA call.
-     * @param indicationType Type of radio indication
-     * @param status CDMA OTA provision status
-     */
-    public void cdmaOtaProvisionStatus(int indicationType, int status) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        int[] response = new int[] {status};
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_CDMA_OTA_PROVISION_STATUS, response);
-
-        mRil.mOtaProvisionRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
-    }
-
-
-    /**
-     * Indicates current emergency number list.
-     * @param indicationType Type of radio indication
-     * @param emergencyNumberList Current list of emergency numbers known to radio
-     */
-    public void currentEmergencyNumberList(int indicationType,
-            android.hardware.radio.voice.EmergencyNumber[] emergencyNumberList) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        List<EmergencyNumber> response = new ArrayList<>(emergencyNumberList.length);
-        for (android.hardware.radio.voice.EmergencyNumber enHal : emergencyNumberList) {
-            EmergencyNumber emergencyNumber = new EmergencyNumber(enHal.number,
-                    MccTable.countryCodeForMcc(enHal.mcc), enHal.mnc, enHal.categories,
-                    RILUtils.primitiveArrayToArrayList(enHal.urns), enHal.sources,
-                    EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
-            response.add(emergencyNumber);
-        }
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_EMERGENCY_NUMBER_LIST, response);
-
-        // Cache emergency number list from last indication.
-        mRil.cacheEmergencyNumberListIndication(response);
-
-        // Notify emergency number list from radio to registrants
-        mRil.mEmergencyNumberListRegistrants.notifyRegistrants(
-                new AsyncResult(null, response, null));
-    }
-
-    /**
-     * Indicates that the radio system selection module has autonomously entered emergency
-     * callback mode.
-     * @param indicationType Type of radio indication
-     */
-    public void enterEmergencyCallbackMode(int indicationType) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_ENTER_EMERGENCY_CALLBACK_MODE);
-
-        if (mRil.mEmergencyCallbackModeRegistrant != null) {
-            mRil.mEmergencyCallbackModeRegistrant.notifyRegistrant();
-        }
-    }
-
-    /**
-     * Indicates when Emergency Callback Mode ends. Indicates that the radio system selection module
-     * has proactively exited emergency callback mode.
-     * @param indicationType Type of radio indication
-     */
-    public void exitEmergencyCallbackMode(int indicationType) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_EXIT_EMERGENCY_CALLBACK_MODE);
-
-        mRil.mExitEmergencyCallbackModeRegistrants.notifyRegistrants();
-    }
-
-    /**
-     * Indicates that network doesn't have in-band information, need to play out-band tone.
-     * @param indicationType Type of radio indication
-     * @param start true = start play ringback tone, false = stop playing ringback tone
-     */
-    public void indicateRingbackTone(int indicationType, boolean start) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogvRet(RIL_UNSOL_RINGBACK_TONE, start);
-
-        mRil.mRingbackToneRegistrants.notifyRegistrants(new AsyncResult(null, start, null));
-    }
-
-    /**
-     * Indicates when Supplementary service(SS) response is received when DIAL/USSD/SS is changed to
-     * SS by call control.
-     * @param indicationType Type of radio indication
-     * @param ss StkCcUnsolSsResult
-     */
-    public void onSupplementaryServiceIndication(int indicationType,
-            android.hardware.radio.voice.StkCcUnsolSsResult ss) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        int num;
-        SsData ssData = new SsData();
-
-        ssData.serviceType = ssData.ServiceTypeFromRILInt(ss.serviceType);
-        ssData.requestType = ssData.RequestTypeFromRILInt(ss.requestType);
-        ssData.teleserviceType = ssData.TeleserviceTypeFromRILInt(ss.teleserviceType);
-        ssData.serviceClass = ss.serviceClass; // This is service class sent in the SS request.
-        ssData.result = ss.result; // This is the result of the SS request.
-
-        if (ssData.serviceType.isTypeCF() && ssData.requestType.isTypeInterrogation()) {
-            android.hardware.radio.voice.CfData cfData = ss.cfData[0];
-            num = cfData.cfInfo.length;
-            ssData.cfInfo = new CallForwardInfo[num];
-
-            for (int i = 0; i < num; i++) {
-                android.hardware.radio.voice.CallForwardInfo cfInfo = cfData.cfInfo[i];
-                ssData.cfInfo[i] = new CallForwardInfo();
-                ssData.cfInfo[i].status = cfInfo.status;
-                ssData.cfInfo[i].reason = cfInfo.reason;
-                ssData.cfInfo[i].serviceClass = cfInfo.serviceClass;
-                ssData.cfInfo[i].toa = cfInfo.toa;
-                ssData.cfInfo[i].number = cfInfo.number;
-                ssData.cfInfo[i].timeSeconds = cfInfo.timeSeconds;
-                mRil.riljLog("[SS Data] CF Info " + i + " : " +  ssData.cfInfo[i]);
-            }
-        } else {
-            android.hardware.radio.voice.SsInfoData ssInfo = ss.ssInfo[0];
-            num = ssInfo.ssInfo.length;
-            ssData.ssInfo = new int[num];
-            for (int i = 0; i < num; i++) {
-                ssData.ssInfo[i] = ssInfo.ssInfo[i];
-                mRil.riljLog("[SS Data] SS Info " + i + " : " +  ssData.ssInfo[i]);
-            }
-        }
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_ON_SS, ssData);
-
-        if (mRil.mSsRegistrant != null) {
-            mRil.mSsRegistrant.notifyRegistrant(new AsyncResult(null, ssData, null));
-        }
-    }
-
-    /**
-     * Indicates when a new USSD message is received. The USSD session is assumed to persist if the
-     * type code is REQUEST, otherwise the current session (if any) is assumed to have terminated.
-     * @param indicationType Type of radio indication
-     * @param ussdModeType USSD type code
-     * @param msg Message string in UTF-8, if applicable
-     */
-    public void onUssd(int indicationType, int ussdModeType, String msg) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogMore(RIL_UNSOL_ON_USSD, "" + ussdModeType);
-
-        // TODO: Clean this up with a parcelable class for better self-documentation
-        String[] resp = new String[]{"" + ussdModeType, msg};
-        if (mRil.mUSSDRegistrant != null) {
-            mRil.mUSSDRegistrant.notifyRegistrant(new AsyncResult(null, resp, null));
-        }
-    }
-
-    /**
-     * Indicates that framework/application must reset the uplink mute state.
-     * @param indicationType Type of radio indication
-     */
-    public void resendIncallMute(int indicationType) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESEND_INCALL_MUTE);
-
-        mRil.mResendIncallMuteRegistrants.notifyRegistrants();
-    }
-
-    /**
-     * Indicates when Single Radio Voice Call Continuity (SRVCC) progress state has changed.
-     * @param indicationType Type of radio indication
-     * @param state New SRVCC State
-     */
-    public void srvccStateNotify(int indicationType, int state) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        int[] response = new int[] {state};
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_SRVCC_STATE_NOTIFY, response);
-
-        mRil.writeMetricsSrvcc(state);
-        mRil.mSrvccStateRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
-    }
-
-    /**
-     * Indicates when there is an ALPHA from UICC during Call Control.
-     * @param indicationType Type of radio indication
-     * @param alpha ALPHA string from UICC in UTF-8 format
-     */
-    public void stkCallControlAlphaNotify(int indicationType, String alpha) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_STK_CC_ALPHA_NOTIFY, alpha);
-
-        if (mRil.mCatCcAlphaRegistrant != null) {
-            mRil.mCatCcAlphaRegistrant.notifyRegistrant(new AsyncResult(null, alpha, null));
-        }
-    }
-
-    /**
-     * Indicates when SIM wants application to setup a voice call.
-     * @param indicationType Type of radio indication
-     * @param timeout Timeout value in milliseconds for setting up voice call
-     */
-    public void stkCallSetup(int indicationType, long timeout) {
-        mRil.processIndication(RIL.VOICE_SERVICE, indicationType);
-
-        if (RIL.RILJ_LOGD) mRil.unsljLogRet(RIL_UNSOL_STK_CALL_SETUP, timeout);
-
-        if (mRil.mCatCallSetUpRegistrant != null) {
-            mRil.mCatCallSetUpRegistrant.notifyRegistrant(new AsyncResult(null, timeout, null));
-        }
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return IRadioVoiceIndication.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return IRadioVoiceIndication.VERSION;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/VoiceResponse.java b/src/java/com/android/internal/telephony/VoiceResponse.java
deleted file mode 100644
index b1ba9d9..0000000
--- a/src/java/com/android/internal/telephony/VoiceResponse.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import android.hardware.radio.RadioError;
-import android.hardware.radio.RadioResponseInfo;
-import android.hardware.radio.voice.IRadioVoiceResponse;
-
-import java.util.ArrayList;
-import java.util.Collections;
-
-/**
- * Interface declaring response functions to solicited radio requests for SIM APIs.
- */
-public class VoiceResponse extends IRadioVoiceResponse.Stub {
-    private final RIL mRil;
-
-    public VoiceResponse(RIL ril) {
-        mRil = ril;
-    }
-
-    /**
-     * Acknowledge the receipt of radio request sent to the vendor. This must be sent only for
-     * radio request which take long time to respond.
-     * For more details, refer https://source.android.com/devices/tech/connect/ril.html
-     * @param serial Serial no. of the request whose acknowledgement is sent.
-     */
-    public void acknowledgeRequest(int serial) {
-        mRil.processRequestAck(serial);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void acceptCallResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void cancelPendingUssdResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void conferenceResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void dialResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void emergencyDialResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void exitEmergencyCallbackModeResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void explicitCallTransferResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param callForwardInfos points to a vector of CallForwardInfo, one for
-     *        each distinct registered phone number.
-     */
-    public void getCallForwardStatusResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.voice.CallForwardInfo[] callForwardInfos) {
-        RILRequest rr = mRil.processResponse(RIL.VOICE_SERVICE, responseInfo);
-        if (rr != null) {
-            CallForwardInfo[] ret = new CallForwardInfo[callForwardInfos.length];
-            for (int i = 0; i < callForwardInfos.length; i++) {
-                ret[i] = new CallForwardInfo();
-                ret[i].status = callForwardInfos[i].status;
-                ret[i].reason = callForwardInfos[i].reason;
-                ret[i].serviceClass = callForwardInfos[i].serviceClass;
-                ret[i].toa = callForwardInfos[i].toa;
-                ret[i].number = callForwardInfos[i].number;
-                ret[i].timeSeconds = callForwardInfos[i].timeSeconds;
-            }
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param enable If current call waiting state is disabled, enable = false else true
-     * @param serviceClass If enable, then callWaitingResp[1] must follow, with the TS 27.007
-     *        service class bit vector of services for which call waiting is enabled.
-     *        For example, if callWaitingResp[0] is 1 and callWaitingResp[1] is 3, then call waiting
-     *        is enabled for data and voice and disabled for everything else.
-     */
-    public void getCallWaitingResponse(RadioResponseInfo responseInfo, boolean enable,
-            int serviceClass) {
-        RadioResponse.responseInts(
-                RIL.VOICE_SERVICE, mRil, responseInfo, enable ? 1 : 0, serviceClass);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param status indicates CLIP status
-     */
-    public void getClipResponse(RadioResponseInfo responseInfo, int status) {
-        RadioResponse.responseInts(RIL.VOICE_SERVICE, mRil, responseInfo, status);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param n is "n" parameter from TS 27.007 7.7
-     * @param m is "m" parameter from TS 27.007 7.7
-     */
-    public void getClirResponse(RadioResponseInfo responseInfo, int n, int m) {
-        RadioResponse.responseInts(RIL.VOICE_SERVICE, mRil, responseInfo, n, m);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param calls Current call list
-     */
-    public void getCurrentCallsResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.voice.Call[] calls) {
-        RILRequest rr = mRil.processResponse(RIL.VOICE_SERVICE, responseInfo);
-
-        if (rr != null) {
-            int num = calls.length;
-            ArrayList<DriverCall> dcCalls = new ArrayList<>(num);
-            DriverCall dc;
-            for (int i = 0; i < num; i++) {
-                dc = RILUtils.convertToDriverCall(calls[i]);
-                dcCalls.add(dc);
-                if (dc.isVoicePrivacy) {
-                    mRil.mVoicePrivacyOnRegistrants.notifyRegistrants();
-                    mRil.riljLog("InCall VoicePrivacy is enabled");
-                } else {
-                    mRil.mVoicePrivacyOffRegistrants.notifyRegistrants();
-                    mRil.riljLog("InCall VoicePrivacy is disabled");
-                }
-            }
-
-            Collections.sort(dcCalls);
-            if ((num == 0) && mRil.mTestingEmergencyCall.getAndSet(false)) {
-                if (mRil.mEmergencyCallbackModeRegistrant != null) {
-                    mRil.riljLog("responseCurrentCalls: call ended, testing emergency call,"
-                            + " notify ECM Registrants");
-                    mRil.mEmergencyCallbackModeRegistrant.notifyRegistrant();
-                }
-            }
-
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, dcCalls);
-            }
-            mRil.processResponseDone(rr, responseInfo, dcCalls);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param fcInfo Contains LastCallFailCause and vendor cause code. GSM failure reasons
-     *        are mapped to cause codes defined in TS 24.008 Annex H where possible. CDMA failure
-     *        reasons are derived from the possible call failure scenarios described in the
-     *        "CDMA IS-2000 Release A (C.S0005-A v6.0)" standard.
-     */
-    public void getLastCallFailCauseResponse(RadioResponseInfo responseInfo,
-            android.hardware.radio.voice.LastCallFailCauseInfo fcInfo) {
-        RILRequest rr = mRil.processResponse(RIL.VOICE_SERVICE, responseInfo);
-
-        if (rr != null) {
-            LastCallFailCause ret = new LastCallFailCause();
-            ret.causeCode = fcInfo.causeCode;
-            ret.vendorCause = fcInfo.vendorCause;
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, ret);
-            }
-            mRil.processResponseDone(rr, responseInfo, ret);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param enable true for "mute enabled" and false for "mute disabled"
-     */
-    public void getMuteResponse(RadioResponseInfo responseInfo, boolean enable) {
-        RadioResponse.responseInts(RIL.VOICE_SERVICE, mRil, responseInfo, enable ? 1 : 0);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param enable false for Standard Privacy Mode (Public Long Code Mask)
-     *        true for Enhanced Privacy Mode (Private Long Code Mask)
-     */
-    public void getPreferredVoicePrivacyResponse(RadioResponseInfo responseInfo, boolean enable) {
-        RadioResponse.responseInts(RIL.VOICE_SERVICE, mRil, responseInfo, enable ? 1 : 0);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param mode TTY mode
-     */
-    public void getTtyModeResponse(RadioResponseInfo responseInfo, int mode) {
-        RadioResponse.responseInts(RIL.VOICE_SERVICE, mRil, responseInfo, mode);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void handleStkCallSetupRequestFromSimResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void hangupConnectionResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void hangupForegroundResumeBackgroundResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void hangupWaitingOrBackgroundResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     * @param enable true for "vonr enabled" and false for "vonr disabled"
-     */
-    public void isVoNrEnabledResponse(RadioResponseInfo responseInfo, boolean enable) {
-        RILRequest rr = mRil.processResponse(RIL.VOICE_SERVICE, responseInfo);
-
-        if (rr != null) {
-            if (responseInfo.error == RadioError.NONE) {
-                RadioResponse.sendMessageResponse(rr.mResult, enable);
-            }
-            mRil.processResponseDone(rr, responseInfo, enable);
-        }
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void rejectCallResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void sendBurstDtmfResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void sendCdmaFeatureCodeResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void sendDtmfResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void sendUssdResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void separateConnectionResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setCallForwardResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setCallWaitingResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setClirResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setMuteResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setPreferredVoicePrivacyResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setTtyModeResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void setVoNrEnabledResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void startDtmfResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void stopDtmfResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    /**
-     * @param responseInfo Response info struct containing response type, serial no. and error
-     */
-    public void switchWaitingOrHoldingAndActiveResponse(RadioResponseInfo responseInfo) {
-        RadioResponse.responseVoid(RIL.VOICE_SERVICE, mRil, responseInfo);
-    }
-
-    @Override
-    public String getInterfaceHash() {
-        return IRadioVoiceResponse.HASH;
-    }
-
-    @Override
-    public int getInterfaceVersion() {
-        return IRadioVoiceResponse.VERSION;
-    }
-}
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java b/src/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
index aa12f73..79c4d35 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaCallWaitingNotification.java
@@ -44,7 +44,7 @@
     public String toString()
     {
         return super.toString() + "Call Waiting Notification  "
-            + " number: " + Rlog.pii(LOG_TAG, number)
+            + " number: " + number
             + " numberPresentation: " + numberPresentation
             + " name: " + name
             + " namePresentation: " + namePresentation
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java b/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
index eb5f866..fd604a0 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaInboundSmsHandler.java
@@ -141,15 +141,13 @@
                 sTestBroadcastReceiver = new CdmaCbTestBroadcastReceiver();
                 IntentFilter filter = new IntentFilter();
                 filter.addAction(TEST_ACTION);
-                context.registerReceiver(sTestBroadcastReceiver, filter,
-                        Context.RECEIVER_EXPORTED);
+                context.registerReceiver(sTestBroadcastReceiver, filter);
             }
             if (sTestScpBroadcastReceiver == null) {
                 sTestScpBroadcastReceiver = new CdmaScpTestBroadcastReceiver();
                 IntentFilter filter = new IntentFilter();
                 filter.addAction(SCP_TEST_ACTION);
-                context.registerReceiver(sTestScpBroadcastReceiver, filter,
-                        Context.RECEIVER_EXPORTED);
+                context.registerReceiver(sTestScpBroadcastReceiver, filter);
             }
         }
     }
diff --git a/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java b/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
index 5a830a8..1742db7 100644
--- a/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/cdma/CdmaSMSDispatcher.java
@@ -57,13 +57,14 @@
      * @param sms the CDMA SMS message containing the status report
      */
     public void sendStatusReportMessage(SmsMessage sms) {
-        if (VDBG) Rlog.d(TAG, "sending EVENT_NEW_SMS_STATUS_REPORT message");
-        sendMessage(obtainMessage(EVENT_NEW_SMS_STATUS_REPORT, sms));
+        if (VDBG) Rlog.d(TAG, "sending EVENT_HANDLE_STATUS_REPORT message");
+        sendMessage(obtainMessage(EVENT_HANDLE_STATUS_REPORT, sms));
     }
 
     @Override
     protected void handleStatusReport(Object o) {
         if (o instanceof SmsMessage) {
+            if (VDBG) Rlog.d(TAG, "calling handleSmsStatusReport()");
             byte[] pdu = ((SmsMessage) o).getPdu();
             mSmsDispatchersController.handleSmsStatusReport(SmsConstants.FORMAT_3GPP2, pdu);
         } else {
diff --git a/src/java/com/android/internal/telephony/cdma/SmsMessageConverter.java b/src/java/com/android/internal/telephony/cdma/SmsMessageConverter.java
new file mode 100644
index 0000000..84da264
--- /dev/null
+++ b/src/java/com/android/internal/telephony/cdma/SmsMessageConverter.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.cdma;
+
+import android.hardware.radio.V1_0.CdmaSmsMessage;
+
+import com.android.internal.telephony.SmsMessageBase;
+import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
+import com.android.internal.telephony.cdma.sms.CdmaSmsSubaddress;
+import com.android.internal.telephony.cdma.sms.SmsEnvelope;
+
+/**
+ * A Factory class to convert from RIL to Framework SMS
+ *
+ */
+public class SmsMessageConverter {
+    static final String LOG_TAG = "SmsMessageConverter";
+    static private final String LOGGABLE_TAG = "CDMA:SMS";
+    private static final boolean VDBG = false;
+
+    /**
+     *  Create a "raw" CDMA SmsMessage from a Parcel that was forged in ril.cpp.
+     *  Note: Only primitive fields are set.
+     */
+    public static SmsMessage newCdmaSmsMessageFromRil(
+            CdmaSmsMessage cdmaSmsMessage) {
+        // Note: Parcel.readByte actually reads one Int and masks to byte
+        SmsEnvelope env = new SmsEnvelope();
+        CdmaSmsAddress addr = new CdmaSmsAddress();
+        CdmaSmsSubaddress subaddr = new CdmaSmsSubaddress();
+        byte[] data;
+        byte count;
+        int countInt;
+        int addressDigitMode;
+
+        //currently not supported by the modem-lib: env.mMessageType
+        env.teleService = cdmaSmsMessage.teleserviceId;
+
+        if (cdmaSmsMessage.isServicePresent) {
+            env.messageType = SmsEnvelope.MESSAGE_TYPE_BROADCAST;
+        }
+        else {
+            if (SmsEnvelope.TELESERVICE_NOT_SET == env.teleService) {
+                // assume type ACK
+                env.messageType = SmsEnvelope.MESSAGE_TYPE_ACKNOWLEDGE;
+            } else {
+                env.messageType = SmsEnvelope.MESSAGE_TYPE_POINT_TO_POINT;
+            }
+        }
+        env.serviceCategory = cdmaSmsMessage.serviceCategory;
+
+        // address
+        addressDigitMode = cdmaSmsMessage.address.digitMode;
+        addr.digitMode = (byte) (0xFF & addressDigitMode);
+        addr.numberMode = (byte) (0xFF & cdmaSmsMessage.address.numberMode);
+        addr.ton = cdmaSmsMessage.address.numberType;
+        addr.numberPlan = (byte) (0xFF & cdmaSmsMessage.address.numberPlan);
+        count = (byte) cdmaSmsMessage.address.digits.size();
+        addr.numberOfDigits = count;
+        data = new byte[count];
+        for (int index=0; index < count; index++) {
+            data[index] = cdmaSmsMessage.address.digits.get(index);
+
+            // convert the value if it is 4-bit DTMF to 8 bit
+            if (addressDigitMode == CdmaSmsAddress.DIGIT_MODE_4BIT_DTMF) {
+                data[index] = SmsMessage.convertDtmfToAscii(data[index]);
+            }
+        }
+
+        addr.origBytes = data;
+
+        subaddr.type = cdmaSmsMessage.subAddress.subaddressType;
+        subaddr.odd = (byte) (cdmaSmsMessage.subAddress.odd ? 1 : 0);
+        count = (byte) cdmaSmsMessage.subAddress.digits.size();
+
+        if (count < 0) {
+            count = 0;
+        }
+
+        // p_cur->sSubAddress.digits[digitCount] :
+
+        data = new byte[count];
+
+        for (int index = 0; index < count; ++index) {
+            data[index] = cdmaSmsMessage.subAddress.digits.get(index);
+        }
+
+        subaddr.origBytes = data;
+
+        /* currently not supported by the modem-lib:
+            env.bearerReply
+            env.replySeqNo
+            env.errorClass
+            env.causeCode
+        */
+
+        // bearer data
+        countInt = cdmaSmsMessage.bearerData.size();
+        if (countInt < 0) {
+            countInt = 0;
+        }
+
+        data = new byte[countInt];
+        for (int index=0; index < countInt; index++) {
+            data[index] = cdmaSmsMessage.bearerData.get(index);
+        }
+        // BD gets further decoded when accessed in SMSDispatcher
+        env.bearerData = data;
+
+        // link the the filled objects to the SMS
+        env.origAddress = addr;
+        env.origSubaddress = subaddr;
+
+        SmsMessage msg = new SmsMessage(addr, env);
+
+        return msg;
+    }
+
+    public static android.telephony.SmsMessage newSmsMessageFromCdmaSmsMessage(
+            CdmaSmsMessage msg) {
+        return new android.telephony.SmsMessage((SmsMessageBase)newCdmaSmsMessageFromRil(msg));
+    }
+}
diff --git a/src/java/com/android/internal/telephony/cdnr/CarrierConfigEfData.java b/src/java/com/android/internal/telephony/cdnr/CarrierConfigEfData.java
index 6d6d0ea..0ded77e 100644
--- a/src/java/com/android/internal/telephony/cdnr/CarrierConfigEfData.java
+++ b/src/java/com/android/internal/telephony/cdnr/CarrierConfigEfData.java
@@ -33,52 +33,49 @@
 /** Ef data from carrier config. */
 public final class CarrierConfigEfData implements EfData {
     private static final String TAG = "CarrierConfigEfData";
-
-    private final String mSpn;
-    private final int mSpnDisplayCondition;
-    private final String[] mSpdi;
-    private final String[] mEhplmn;
-    private final String[] mPnn;
-    private final String[] mOpl;
+    private final PersistableBundle mConfig;
 
     public CarrierConfigEfData(@NonNull PersistableBundle config) {
-        // Save only the relevant keys of the config.
-        mSpn = config.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
-        mSpnDisplayCondition = config.getInt(
-                CarrierConfigManager.KEY_SPN_DISPLAY_CONDITION_OVERRIDE_INT,
-                IccRecords.INVALID_CARRIER_NAME_DISPLAY_CONDITION_BITMASK);
-        mSpdi = config.getStringArray(CarrierConfigManager.KEY_SPDI_OVERRIDE_STRING_ARRAY);
-        mEhplmn = config.getStringArray(CarrierConfigManager.KEY_EHPLMN_OVERRIDE_STRING_ARRAY);
-        mPnn = config.getStringArray(CarrierConfigManager.KEY_PNN_OVERRIDE_STRING_ARRAY);
-        mOpl = config.getStringArray(CarrierConfigManager.KEY_OPL_OVERRIDE_STRING_ARRAY);
+        mConfig = config;
     }
 
     @Override
     public String getServiceProviderName() {
-        return TextUtils.isEmpty(mSpn) ? null : mSpn;
+        String spn = mConfig.getString(CarrierConfigManager.KEY_CARRIER_NAME_STRING);
+        if (TextUtils.isEmpty(spn)) return null;
+        return spn;
     }
 
     @Override
     public int getServiceProviderNameDisplayCondition(boolean isRoaming) {
-        return mSpnDisplayCondition;
+        int condition = mConfig.getInt(
+                CarrierConfigManager.KEY_SPN_DISPLAY_CONDITION_OVERRIDE_INT,
+                IccRecords.INVALID_CARRIER_NAME_DISPLAY_CONDITION_BITMASK);
+        return condition;
     }
 
     @Override
     public List<String> getServiceProviderDisplayInformation() {
-        return mSpdi != null ? Arrays.asList(mSpdi) : null;
+        String[] spdi = mConfig.getStringArray(
+                CarrierConfigManager.KEY_SPDI_OVERRIDE_STRING_ARRAY);
+        return spdi != null ? Arrays.asList(spdi) : null;
     }
 
     @Override
     public List<String> getEhplmnList() {
-        return mEhplmn != null ? Arrays.asList(mEhplmn) : null;
+        String[] ehplmn = mConfig.getStringArray(
+                CarrierConfigManager.KEY_EHPLMN_OVERRIDE_STRING_ARRAY);
+        return ehplmn != null ? Arrays.asList(ehplmn) : null;
     }
 
     @Override
     public List<PlmnNetworkName> getPlmnNetworkNameList() {
+        String[] pnn = mConfig.getStringArray(
+                CarrierConfigManager.KEY_PNN_OVERRIDE_STRING_ARRAY);
         List<PlmnNetworkName> pnnList = null;
-        if (mPnn != null) {
-            pnnList = new ArrayList<>(mPnn.length);
-            for (String pnnStr : mPnn) {
+        if (pnn != null) {
+            pnnList = new ArrayList<>(pnn.length);
+            for (String pnnStr : pnn) {
                 try {
                     String[] names = pnnStr.split("\\s*,\\s*");
                     String alphal = names[0];
@@ -94,10 +91,13 @@
 
     @Override
     public List<OperatorPlmnInfo> getOperatorPlmnList() {
+        // OPL
+        String[] opl = mConfig.getStringArray(
+                CarrierConfigManager.KEY_OPL_OVERRIDE_STRING_ARRAY);
         List<OperatorPlmnInfo> oplList = null;
-        if (mOpl != null) {
-            oplList = new ArrayList<>(mOpl.length);
-            for (String oplStr : mOpl) {
+        if (opl != null) {
+            oplList = new ArrayList<>(opl.length);
+            for (String oplStr : opl) {
                 try {
                     String[] info = oplStr.split("\\s*,\\s*");
                     oplList.add(new OperatorPlmnInfo(
diff --git a/src/java/com/android/internal/telephony/data/AccessNetworksManager.java b/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
deleted file mode 100644
index 2a12ecc..0000000
--- a/src/java/com/android/internal/telephony/data/AccessNetworksManager.java
+++ /dev/null
@@ -1,851 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * 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.data;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.StringDef;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.content.pm.PackageManager;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.PersistableBundle;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.RemoteException;
-import android.os.SystemProperties;
-import android.os.UserHandle;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
-import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.Annotation.ApnType;
-import android.telephony.Annotation.NetCapability;
-import android.telephony.AnomalyReporter;
-import android.telephony.CarrierConfigManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.IQualifiedNetworksService;
-import android.telephony.data.IQualifiedNetworksServiceCallback;
-import android.telephony.data.QualifiedNetworksService;
-import android.telephony.data.ThrottleStatus;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.IndentingPrintWriter;
-import android.util.LocalLog;
-import android.util.SparseArray;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.RIL;
-import com.android.internal.telephony.dataconnection.DataThrottler;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.Executor;
-import java.util.stream.Collectors;
-
-/**
- * Access network manager manages the qualified/available networks for mobile data connection.
- * It binds to the vendor's qualified networks service and actively monitors the qualified
- * networks changes.
- */
-public class AccessNetworksManager extends Handler {
-    private static final boolean DBG = false;
-    public static final String SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE =
-            "ro.telephony.iwlan_operation_mode";
-
-    @Retention(RetentionPolicy.SOURCE)
-    @StringDef(prefix = {"IWLAN_OPERATION_MODE_"},
-            value = {
-                    IWLAN_OPERATION_MODE_DEFAULT,
-                    IWLAN_OPERATION_MODE_LEGACY,
-                    IWLAN_OPERATION_MODE_AP_ASSISTED})
-    public @interface IwlanOperationMode {}
-
-    /**
-     * IWLAN default mode. On device that has IRadio 1.4 or above, it means
-     * {@link #IWLAN_OPERATION_MODE_AP_ASSISTED}. On device that has IRadio 1.3 or below, it means
-     * {@link #IWLAN_OPERATION_MODE_LEGACY}.
-     */
-    public static final String IWLAN_OPERATION_MODE_DEFAULT = "default";
-
-    /**
-     * IWLAN legacy mode. IWLAN is completely handled by the modem, and when the device is on
-     * IWLAN, modem reports IWLAN as a RAT.
-     */
-    public static final String IWLAN_OPERATION_MODE_LEGACY = "legacy";
-
-    /**
-     * IWLAN application processor assisted mode. IWLAN is handled by the bound IWLAN data service
-     * and network service separately.
-     */
-    public static final String IWLAN_OPERATION_MODE_AP_ASSISTED = "AP-assisted";
-
-    private final String mLogTag;
-    private final LocalLog mLocalLog = new LocalLog(64);
-    private final UUID mAnomalyUUID = UUID.fromString("c2d1a639-00e2-4561-9619-6acf37d90590");
-    private String mLastBoundPackageName;
-
-    public static final int[] SUPPORTED_APN_TYPES = {
-            ApnSetting.TYPE_DEFAULT,
-            ApnSetting.TYPE_MMS,
-            ApnSetting.TYPE_FOTA,
-            ApnSetting.TYPE_IMS,
-            ApnSetting.TYPE_CBS,
-            ApnSetting.TYPE_SUPL,
-            ApnSetting.TYPE_EMERGENCY,
-            ApnSetting.TYPE_XCAP
-    };
-
-    private final Phone mPhone;
-
-    private final CarrierConfigManager mCarrierConfigManager;
-
-    private IQualifiedNetworksService mIQualifiedNetworksService;
-
-    private AccessNetworksManagerDeathRecipient mDeathRecipient;
-
-    private String mTargetBindingPackageName;
-
-    private QualifiedNetworksServiceConnection mServiceConnection;
-
-    // Available networks. Key is the APN type.
-    private final SparseArray<int[]> mAvailableNetworks = new SparseArray<>();
-
-    private final @TransportType int[] mAvailableTransports;
-
-    private final RegistrantList mQualifiedNetworksChangedRegistrants = new RegistrantList();
-
-    private final Set<DataThrottler> mDataThrottlers = new HashSet<>();
-
-    private final BroadcastReceiver mConfigChangedReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)
-                    && mPhone.getPhoneId() == intent.getIntExtra(
-                    CarrierConfigManager.EXTRA_SLOT_INDEX, 0)) {
-                // We should wait for carrier config changed event because the target binding
-                // package name can come from the carrier config. Note that we still get this event
-                // even when SIM is absent.
-                if (DBG) log("Carrier config changed. Try to bind qualified network service.");
-                bindQualifiedNetworksService();
-            }
-        }
-    };
-
-    /**
-     * The current transport of the APN type. The key is the APN type, and the value is the
-     * transport.
-     */
-    private final Map<Integer, Integer> mCurrentTransports = new ConcurrentHashMap<>();
-
-    /**
-     * The preferred transport of the APN type. The key is the APN type, and the value is the
-     * transport. The preferred transports are updated as soon as QNS changes the preference, while
-     * the current transports are updated after handover complete.
-     */
-    // TODO: Deprecate mPreferredTransports. Should expose mAvailableNetworks to
-    //  DataNetworkController after we support multi preferred access networks (i.e.
-    //  DataNetworkController might select 2nd preferred access network in some scenarios.)
-    private final Map<Integer, Integer> mPreferredTransports = new ConcurrentHashMap<>();
-
-    /**
-     * Callbacks for passing information to interested clients.
-     */
-    private final @NonNull Set<AccessNetworksManagerCallback> mAccessNetworksManagerCallbacks =
-            new ArraySet<>();
-
-    /**
-     * Registers the data throttler in order to receive APN status changes.
-     *
-     * @param dataThrottler the data throttler to register
-     */
-    public void registerDataThrottler(DataThrottler dataThrottler) {
-        this.post(() -> {
-            QualifiedNetworksServiceConnection serviceConnection = mServiceConnection;
-            this.mDataThrottlers.add(dataThrottler);
-            if (serviceConnection != null) {
-                serviceConnection.registerDataThrottler(dataThrottler);
-            }
-        });
-    }
-
-    /**
-     * Represents qualified network types list on a specific APN type.
-     */
-    public static class QualifiedNetworks {
-        public final @ApnType int apnType;
-        // The qualified networks in preferred order. Each network is a AccessNetworkType.
-        public final @NonNull @RadioAccessNetworkType int[] qualifiedNetworks;
-        public QualifiedNetworks(@ApnType int apnType, @NonNull int[] qualifiedNetworks) {
-            this.apnType = apnType;
-            this.qualifiedNetworks = Arrays.stream(qualifiedNetworks)
-                    .boxed()
-                    .filter(DataUtils::isValidAccessNetwork)
-                    .mapToInt(Integer::intValue)
-                    .toArray();
-        }
-
-        @Override
-        public String toString() {
-            return "[QualifiedNetworks: apnType="
-                    + ApnSetting.getApnTypeString(apnType)
-                    + ", networks="
-                    + Arrays.stream(qualifiedNetworks)
-                    .mapToObj(AccessNetworkType::toString)
-                    .collect(Collectors.joining(","))
-                    + "]";
-        }
-    }
-
-    private class AccessNetworksManagerDeathRecipient implements IBinder.DeathRecipient {
-        @Override
-        public void binderDied() {
-            // TODO: try to rebind the service.
-            String message = "Qualified network service " + mLastBoundPackageName + " died.";
-            loge(message);
-            AnomalyReporter.reportAnomaly(mAnomalyUUID, message, mPhone.getCarrierId());
-        }
-    }
-
-    private final class QualifiedNetworksServiceConnection implements ServiceConnection {
-
-        /**
-         * The APN throttle status callback is attached to the service connection so that they have
-         * the same life cycle.
-         */
-        @NonNull
-        private final ThrottleStatusChangedCallback mThrottleStatusCallback;
-
-        QualifiedNetworksServiceConnection() {
-            mThrottleStatusCallback = new ThrottleStatusChangedCallback();
-        }
-
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            if (DBG) log("onServiceConnected " + name);
-            mIQualifiedNetworksService = IQualifiedNetworksService.Stub.asInterface(service);
-            mDeathRecipient = new AccessNetworksManagerDeathRecipient();
-            mLastBoundPackageName = getQualifiedNetworksServicePackageName();
-
-            try {
-                service.linkToDeath(mDeathRecipient, 0 /* flags */);
-                mIQualifiedNetworksService.createNetworkAvailabilityProvider(mPhone.getPhoneId(),
-                        new QualifiedNetworksServiceCallback());
-
-                registerDataThrottlersFirstTime();
-
-            } catch (RemoteException e) {
-                loge("Remote exception. " + e);
-            }
-        }
-
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            if (DBG) log("onServiceDisconnected " + name);
-            unregisterForThrottleCallbacks();
-            mTargetBindingPackageName = null;
-        }
-
-        /**
-         * Runs on all of the data throttlers when the service is connected
-         */
-        private void registerDataThrottlersFirstTime() {
-            post(() -> {
-                for (DataThrottler dataThrottler : mDataThrottlers) {
-                    dataThrottler.registerForThrottleStatusChanges(mThrottleStatusCallback);
-                }
-            });
-        }
-
-        private void registerDataThrottler(DataThrottler dataThrottler) {
-            post(() -> {
-                dataThrottler.registerForThrottleStatusChanges(mThrottleStatusCallback);
-            });
-        }
-
-        private void unregisterForThrottleCallbacks() {
-            post(() -> {
-                for (DataThrottler dataThrottler : mDataThrottlers) {
-                    dataThrottler.unregisterForThrottleStatusChanges(mThrottleStatusCallback);
-                }
-            });
-        }
-    }
-
-    private class ThrottleStatusChangedCallback implements DataThrottler.Callback {
-        @Override
-        public void onThrottleStatusChanged(List<ThrottleStatus> throttleStatuses) {
-            post(() -> {
-                try {
-                    List<ThrottleStatus> throttleStatusesBySlot =
-                            throttleStatuses
-                                    .stream()
-                                    .filter(x -> x.getSlotIndex() == mPhone.getPhoneId())
-                                    .collect(Collectors.toList());
-                    if (mIQualifiedNetworksService != null) {
-                        mIQualifiedNetworksService.reportThrottleStatusChanged(mPhone.getPhoneId(),
-                                throttleStatusesBySlot);
-                    }
-                } catch (Exception ex) {
-                    loge("onThrottleStatusChanged", ex);
-                }
-            });
-        }
-    }
-
-    private final class QualifiedNetworksServiceCallback extends
-            IQualifiedNetworksServiceCallback.Stub {
-        @Override
-        public void onQualifiedNetworkTypesChanged(int apnTypes,
-                @NonNull int[] qualifiedNetworkTypes) {
-            if (qualifiedNetworkTypes == null) {
-                loge("onQualifiedNetworkTypesChanged: Ignored null input.");
-                return;
-            }
-
-            log("onQualifiedNetworkTypesChanged: apnTypes = ["
-                    + ApnSetting.getApnTypesStringFromBitmask(apnTypes)
-                    + "], networks = [" + Arrays.stream(qualifiedNetworkTypes)
-                    .mapToObj(AccessNetworkType::toString).collect(Collectors.joining(","))
-                    + "]");
-
-            if (Arrays.stream(qualifiedNetworkTypes).anyMatch(accessNetwork
-                    -> !DataUtils.isValidAccessNetwork(accessNetwork))) {
-                loge("Invalid access networks " + Arrays.toString(qualifiedNetworkTypes));
-                return;
-            }
-
-            List<QualifiedNetworks> qualifiedNetworksList = new ArrayList<>();
-            for (int apnType : SUPPORTED_APN_TYPES) {
-                if ((apnTypes & apnType) == apnType) {
-                    if (mAvailableNetworks.get(apnType) != null) {
-                        if (Arrays.equals(mAvailableNetworks.get(apnType),
-                                qualifiedNetworkTypes)) {
-                            log("Available networks for "
-                                    + ApnSetting.getApnTypesStringFromBitmask(apnType)
-                                    + " not changed.");
-                            continue;
-                        }
-                    }
-
-                    // Empty array indicates QNS did not suggest any qualified networks. In this
-                    // case all network requests will be routed to cellular.
-                    if (qualifiedNetworkTypes.length == 0) {
-                        mAvailableNetworks.remove(apnType);
-                        if (getPreferredTransport(apnType)
-                                == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
-                            mPreferredTransports.put(apnType,
-                                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-                            mAccessNetworksManagerCallbacks.forEach(callback ->
-                                    callback.invokeFromExecutor(() ->
-                                            callback.onPreferredTransportChanged(DataUtils
-                                                    .apnTypeToNetworkCapability(apnType))));
-                        }
-                    } else {
-                        mAvailableNetworks.put(apnType, qualifiedNetworkTypes);
-                        qualifiedNetworksList.add(new QualifiedNetworks(apnType,
-                                qualifiedNetworkTypes));
-
-                    }
-                }
-            }
-
-            if (!qualifiedNetworksList.isEmpty()) {
-                setPreferredTransports(qualifiedNetworksList);
-                mQualifiedNetworksChangedRegistrants.notifyResult(qualifiedNetworksList);
-            }
-        }
-    }
-
-    /**
-     * Access networks manager callback. This should be only used by {@link DataNetworkController}.
-     */
-    public abstract static class AccessNetworksManagerCallback extends DataCallback {
-        /**
-         * Constructor
-         *
-         * @param executor The executor of the callback.
-         */
-        public AccessNetworksManagerCallback(@NonNull @CallbackExecutor Executor executor) {
-            super(executor);
-        }
-
-        /**
-         * Called when preferred transport changed.
-         *
-         * @param networkCapability The network capability.
-         */
-        public abstract void onPreferredTransportChanged(@NetCapability int networkCapability);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param phone The phone object.
-     * @param looper Looper for the handler.
-     */
-    public AccessNetworksManager(@NonNull Phone phone, @NonNull Looper looper) {
-        super(looper);
-        mPhone = phone;
-        mCarrierConfigManager = (CarrierConfigManager) phone.getContext().getSystemService(
-                Context.CARRIER_CONFIG_SERVICE);
-        mLogTag = "ANM-" + mPhone.getPhoneId();
-
-        if (isInLegacyMode()) {
-            log("operates in legacy mode.");
-            // For legacy mode, WWAN is the only transport to handle all data connections, even
-            // the IWLAN ones.
-            mAvailableTransports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN};
-        } else {
-            log("operates in AP-assisted mode.");
-            mAvailableTransports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                    AccessNetworkConstants.TRANSPORT_TYPE_WLAN};
-            IntentFilter intentFilter = new IntentFilter();
-            intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-            try {
-                Context contextAsUser = phone.getContext().createPackageContextAsUser(
-                        phone.getContext().getPackageName(), 0, UserHandle.ALL);
-                contextAsUser.registerReceiver(mConfigChangedReceiver, intentFilter,
-                        null /* broadcastPermission */, null);
-            } catch (PackageManager.NameNotFoundException e) {
-                loge("Package name not found: ", e);
-            }
-            bindQualifiedNetworksService();
-        }
-
-        if (phone.isUsingNewDataStack()) {
-            // Using post to delay the registering because data retry manager instance is created
-            // later than access networks manager.
-            post(() -> mPhone.getDataNetworkController().getDataRetryManager().registerCallback(
-                    new DataRetryManager.DataRetryManagerCallback(this::post) {
-                        @Override
-                        public void onThrottleStatusChanged(List<ThrottleStatus> throttleStatuses) {
-                            try {
-                                logl("onThrottleStatusChanged: " + throttleStatuses);
-                                if (mIQualifiedNetworksService != null) {
-                                    mIQualifiedNetworksService.reportThrottleStatusChanged(
-                                            mPhone.getPhoneId(), throttleStatuses);
-                                }
-                            } catch (Exception ex) {
-                                loge("onThrottleStatusChanged: ", ex);
-                            }
-                        }
-                    }));
-        }
-    }
-
-    /**
-     * Find the qualified network service from configuration and binds to it. It reads the
-     * configuration from carrier config if it exists. If not, read it from resources.
-     */
-    private void bindQualifiedNetworksService() {
-        post(() -> {
-            Intent intent = null;
-            String packageName = getQualifiedNetworksServicePackageName();
-            String className = getQualifiedNetworksServiceClassName();
-
-            if (DBG) log("Qualified network service package = " + packageName);
-            if (TextUtils.isEmpty(packageName)) {
-                loge("Can't find the binding package");
-                return;
-            }
-
-            if (TextUtils.isEmpty(className)) {
-                intent = new Intent(QualifiedNetworksService.QUALIFIED_NETWORKS_SERVICE_INTERFACE);
-                intent.setPackage(packageName);
-            } else {
-                ComponentName cm = new ComponentName(packageName, className);
-                intent = new Intent(QualifiedNetworksService.QUALIFIED_NETWORKS_SERVICE_INTERFACE)
-                        .setComponent(cm);
-            }
-
-            if (TextUtils.equals(packageName, mTargetBindingPackageName)) {
-                if (DBG) log("Service " + packageName + " already bound or being bound.");
-                return;
-            }
-
-            if (mIQualifiedNetworksService != null
-                    && mIQualifiedNetworksService.asBinder().isBinderAlive()) {
-                // Remove the network availability updater and then unbind the service.
-                try {
-                    mIQualifiedNetworksService.removeNetworkAvailabilityProvider(
-                            mPhone.getPhoneId());
-                } catch (RemoteException e) {
-                    loge("Cannot remove network availability updater. " + e);
-                }
-
-                mPhone.getContext().unbindService(mServiceConnection);
-            }
-
-            try {
-                mServiceConnection = new QualifiedNetworksServiceConnection();
-                log("bind to " + packageName);
-                if (!mPhone.getContext().bindService(intent, mServiceConnection,
-                        Context.BIND_AUTO_CREATE)) {
-                    loge("Cannot bind to the qualified networks service.");
-                    return;
-                }
-                mTargetBindingPackageName = packageName;
-            } catch (Exception e) {
-                loge("Cannot bind to the qualified networks service. Exception: " + e);
-            }
-        });
-    }
-
-    /**
-     * Get the qualified network service package.
-     *
-     * @return package name of the qualified networks service package. Return empty string when in
-     * legacy mode (i.e. Dedicated IWLAN data/network service is not supported).
-     */
-    private String getQualifiedNetworksServicePackageName() {
-        // Read package name from the resource
-        String packageName = mPhone.getContext().getResources().getString(
-                com.android.internal.R.string.config_qualified_networks_service_package);
-
-        PersistableBundle b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId());
-
-        if (b != null) {
-            // If carrier config overrides it, use the one from carrier config
-            String carrierConfigPackageName =  b.getString(CarrierConfigManager
-                    .KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_PACKAGE_OVERRIDE_STRING);
-            if (!TextUtils.isEmpty(carrierConfigPackageName)) {
-                if (DBG) log("Found carrier config override " + carrierConfigPackageName);
-                packageName = carrierConfigPackageName;
-            }
-        }
-
-        return packageName;
-    }
-
-    /**
-     * Get the qualified network service class name.
-     *
-     * @return class name of the qualified networks service package.
-     */
-    private String getQualifiedNetworksServiceClassName() {
-        // Read package name from the resource
-        String className = mPhone.getContext().getResources().getString(
-                com.android.internal.R.string.config_qualified_networks_service_class);
-
-        PersistableBundle b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId());
-
-        if (b != null) {
-            // If carrier config overrides it, use the one from carrier config
-            String carrierConfigClassName =  b.getString(CarrierConfigManager
-                    .KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_CLASS_OVERRIDE_STRING);
-            if (!TextUtils.isEmpty(carrierConfigClassName)) {
-                if (DBG) log("Found carrier config override " + carrierConfigClassName);
-                className = carrierConfigClassName;
-            }
-        }
-
-        return className;
-    }
-
-    private @NonNull List<QualifiedNetworks> getQualifiedNetworksList() {
-        List<QualifiedNetworks> qualifiedNetworksList = new ArrayList<>();
-        for (int i = 0; i < mAvailableNetworks.size(); i++) {
-            qualifiedNetworksList.add(new QualifiedNetworks(mAvailableNetworks.keyAt(i),
-                    mAvailableNetworks.valueAt(i)));
-        }
-
-        return qualifiedNetworksList;
-    }
-
-    /**
-     * Register for qualified networks changed event.
-     *
-     * @param h The target to post the event message to.
-     * @param what The event.
-     */
-    public void registerForQualifiedNetworksChanged(Handler h, int what) {
-        if (h != null) {
-            Registrant r = new Registrant(h, what, null);
-            mQualifiedNetworksChangedRegistrants.add(r);
-
-            // Notify for the first time if there is already something in the available network
-            // list.
-            if (mAvailableNetworks.size() != 0) {
-                r.notifyResult(getQualifiedNetworksList());
-            }
-        }
-    }
-
-    /**
-     * @return {@code true} if the device operates in legacy mode, otherwise {@code false}.
-     */
-    public boolean isInLegacyMode() {
-        // Get IWLAN operation mode from the system property. If the system property is configured
-        // to default or not configured, the mode is tied to IRadio version. For 1.4 or above, it's
-        // AP-assisted mode, for 1.3 or below, it's legacy mode.
-        String mode = SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE);
-
-        if (mode.equals(IWLAN_OPERATION_MODE_AP_ASSISTED)) {
-            return false;
-        } else if (mode.equals(IWLAN_OPERATION_MODE_LEGACY)) {
-            return true;
-        }
-
-        return mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_1_4);
-    }
-
-    /**
-     * @return The available transports. Note that on legacy devices, the only available transport
-     * would be WWAN only. If the device is configured as AP-assisted mode, the available transport
-     * will always be WWAN and WLAN (even if the device is not camped on IWLAN).
-     * See {@link #isInLegacyMode()} for mode details.
-     */
-    public synchronized @NonNull int[] getAvailableTransports() {
-        return mAvailableTransports;
-    }
-
-    /**
-     * Get the transport based on the network capability.
-     *
-     * @param netCap The network capability.
-     * @return The transport type.
-     */
-    public @TransportType int getCurrentTransportByNetworkCapability(@NetCapability int netCap) {
-        return getCurrentTransport(DataUtils.networkCapabilityToApnType(netCap));
-    }
-
-    /**
-     * Get the transport based on the APN type.
-     *
-     * @param apnType APN type
-     * @return The transport type
-     */
-    // TODO: Remove this after TransportManager is removed.
-    public @TransportType int getCurrentTransport(@ApnType int apnType) {
-        // In legacy mode, always route to cellular.
-        if (isInLegacyMode()) {
-            return AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
-        }
-
-        // If we can't find the corresponding transport, always route to cellular.
-        return mCurrentTransports.get(apnType) == null
-                ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN : mCurrentTransports.get(apnType);
-    }
-
-    /**
-     * Set the current transport of a network capability.
-     *
-     * @param netCap The network capability.
-     * @param transport The transport.
-     */
-    public void setCurrentTransportByNetworkCapability(@NetCapability int netCap,
-            @TransportType int transport) {
-        setCurrentTransport(DataUtils.networkCapabilityToApnType(netCap), transport);
-    }
-
-    /**
-     * Set the current transport of apn type.
-     *
-     * @param apnType The APN type
-     * @param transport The transport.
-     */
-    // TODO: Remove this after TransportManager is removed.
-    public void setCurrentTransport(@ApnType int apnType, @TransportType int transport) {
-        Integer previousTransport = mCurrentTransports.put(apnType, transport);
-        if (previousTransport == null || previousTransport != transport) {
-            logl("setCurrentTransport: apnType=" + ApnSetting.getApnTypeString(apnType)
-                    + ", transport=" + AccessNetworkConstants.transportTypeToString(transport));
-        }
-    }
-
-    private static @TransportType int getTransportFromAccessNetwork(int accessNetwork) {
-        return accessNetwork == AccessNetworkType.IWLAN
-                ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
-                : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
-    }
-
-    private void setPreferredTransports(@NonNull List<QualifiedNetworks> networksList) {
-        for (QualifiedNetworks networks : networksList) {
-            if (networks.qualifiedNetworks.length > 0) {
-                int transport = getTransportFromAccessNetwork(networks.qualifiedNetworks[0]);
-                if (getPreferredTransport(networks.apnType) != transport) {
-                    mPreferredTransports.put(networks.apnType, transport);
-                    mAccessNetworksManagerCallbacks.forEach(callback ->
-                            callback.invokeFromExecutor(() ->
-                                    callback.onPreferredTransportChanged(DataUtils
-                                            .apnTypeToNetworkCapability(networks.apnType))));
-                    logl("setPreferredTransports: apnType="
-                            + ApnSetting.getApnTypeString(networks.apnType) + ", transport="
-                            + AccessNetworkConstants.transportTypeToString(transport));
-                }
-            }
-        }
-    }
-
-    /**
-     * Get the  preferred transport.
-     *
-     * @param apnType APN type
-     * @return The preferred transport.
-     */
-    public @TransportType int getPreferredTransport(@ApnType int apnType) {
-        // In legacy mode, always preferred on cellular.
-        if (isInLegacyMode()) {
-            return AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
-        }
-
-        return mPreferredTransports.get(apnType) == null
-                ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN : mPreferredTransports.get(apnType);
-    }
-
-    /**
-     * Get the  preferred transport by network capability.
-     *
-     * @param networkCapability The network capability. (Note that only APN-type capabilities are
-     * supported.
-     * @return The preferred transport.
-     */
-    public @TransportType int getPreferredTransportByNetworkCapability(
-            @NetCapability int networkCapability) {
-        int apnType = DataUtils.networkCapabilityToApnType(networkCapability);
-        // For non-APN type capabilities, always route to WWAN.
-        if (apnType == ApnSetting.TYPE_NONE) {
-            return AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
-        }
-        return getPreferredTransport(apnType);
-    }
-
-    /**
-     * Check if there is any APN type's current transport is on IWLAN.
-     *
-     * @return {@code true} if there is any APN is on IWLAN, otherwise {@code false}.
-     */
-    public boolean isAnyApnOnIwlan() {
-        for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) {
-            if (mPhone.isUsingNewDataStack()) {
-                if (getPreferredTransport(apnType) == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
-                    return true;
-                }
-            } else {
-                if (getCurrentTransport(apnType) == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Unregister for qualified networks changed event.
-     *
-     * @param h The handler
-     */
-    public void unregisterForQualifiedNetworksChanged(Handler h) {
-        if (h != null) {
-            mQualifiedNetworksChangedRegistrants.remove(h);
-        }
-    }
-
-    /**
-     * Register the callback for receiving information from {@link AccessNetworksManager}.
-     *
-     * @param callback The callback.
-     */
-    public void registerCallback(@NonNull AccessNetworksManagerCallback callback) {
-        mAccessNetworksManagerCallbacks.add(callback);
-    }
-
-    /**
-     * Unregister the callback which was previously registered through
-     * {@link #registerCallback(AccessNetworksManagerCallback)}.
-     *
-     * @param callback The callback to unregister.
-     */
-    public void unregisterCallback(@NonNull AccessNetworksManagerCallback callback) {
-        mAccessNetworksManagerCallbacks.remove(callback);
-    }
-
-    private void log(String s) {
-        Rlog.d(mLogTag, s);
-    }
-
-    private void loge(String s) {
-        Rlog.e(mLogTag, s);
-    }
-
-    private void loge(String s, Exception ex) {
-        Rlog.e(mLogTag, s, ex);
-    }
-
-    private void logl(String s) {
-        log(s);
-        mLocalLog.log(s);
-    }
-
-    /**
-     * Dump the state of access networks manager
-     *
-     * @param fd File descriptor
-     * @param printWriter Print writer
-     * @param args Arguments
-     */
-    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
-        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
-        pw.println(AccessNetworksManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":");
-        pw.increaseIndent();
-        pw.println("current transports=");
-        pw.increaseIndent();
-        for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) {
-            pw.println(ApnSetting.getApnTypeString(apnType)
-                    + ": " + AccessNetworkConstants.transportTypeToString(
-                    getCurrentTransport(apnType)));
-        }
-        pw.decreaseIndent();
-        pw.println("preferred transports=");
-        pw.increaseIndent();
-        for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) {
-            pw.println(ApnSetting.getApnTypeString(apnType)
-                    + ": " + AccessNetworkConstants.transportTypeToString(
-                    getPreferredTransport(apnType)));
-        }
-
-        pw.decreaseIndent();
-        pw.println("isInLegacy=" + isInLegacyMode());
-        pw.println("IWLAN operation mode="
-                + SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE));
-        pw.println("Local logs=");
-        pw.increaseIndent();
-        mLocalLog.dump(fd, pw, args);
-        pw.decreaseIndent();
-        pw.decreaseIndent();
-        pw.flush();
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/DataCallback.java b/src/java/com/android/internal/telephony/data/DataCallback.java
deleted file mode 100644
index 1fafe8c..0000000
--- a/src/java/com/android/internal/telephony/data/DataCallback.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.concurrent.Executor;
-
-/**
- * This is the generic callback used for passing information between telephony data modules.
- */
-public class DataCallback {
-    /** The executor of the callback. */
-    private final @NonNull Executor mExecutor;
-
-    /**
-     * Constructor
-     *
-     * @param executor The executor of the callback.
-     */
-    public DataCallback(@NonNull @CallbackExecutor Executor executor) {
-        mExecutor = executor;
-    }
-
-    /**
-     * @return The executor of the callback.
-     */
-    @VisibleForTesting
-    public @NonNull Executor getExecutor() {
-        return mExecutor;
-    }
-
-    /**
-     * Invoke the callback from executor.
-     *
-     * @param runnable The callback method to invoke.
-     */
-    public void invokeFromExecutor(@NonNull Runnable runnable) {
-        mExecutor.execute(runnable);
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/DataConfigManager.java b/src/java/com/android/internal/telephony/data/DataConfigManager.java
deleted file mode 100644
index 82a4ccd..0000000
--- a/src/java/com/android/internal/telephony/data/DataConfigManager.java
+++ /dev/null
@@ -1,1245 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.NonNull;
-import android.annotation.StringDef;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.res.Resources;
-import android.net.LinkProperties;
-import android.net.NetworkCapabilities;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PersistableBundle;
-import android.os.RegistrantList;
-import android.provider.DeviceConfig;
-import android.telephony.Annotation.ApnType;
-import android.telephony.Annotation.NetCapability;
-import android.telephony.Annotation.NetworkType;
-import android.telephony.CarrierConfigManager;
-import android.telephony.ServiceState;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyDisplayInfo;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-import android.text.TextUtils;
-import android.util.IndentingPrintWriter;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.data.DataNetworkController.HandoverRule;
-import com.android.internal.telephony.data.DataRetryManager.DataHandoverRetryRule;
-import com.android.internal.telephony.data.DataRetryManager.DataSetupRetryRule;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.stream.Collectors;
-
-/**
- * DataConfigManager is the source of all data related configuration from carrier config and
- * resource overlay. DataConfigManager is created to reduce the excessive access to the
- * {@link CarrierConfigManager}. All the data config will be loaded once and stored here.
- */
-public class DataConfigManager extends Handler {
-    /** The default timeout in ms for data network stuck in a transit state. */
-    private static final int DEFAULT_NETWORK_TRANSIT_STATE_TIMEOUT_MS = 300000;
-
-    /** Event for carrier config changed. */
-    private static final int EVENT_CARRIER_CONFIG_CHANGED = 1;
-
-    /** Event for device config changed. */
-    private static final int EVENT_DEVICE_CONFIG_CHANGED = 2;
-
-    /** Indicates the bandwidth estimation source is from the modem. */
-    private static final String BANDWIDTH_SOURCE_MODEM_STRING_VALUE = "modem";
-
-    /** Indicates the bandwidth estimation source is from the static carrier config. */
-    private static final String BANDWIDTH_SOURCE_CARRIER_CONFIG_STRING_VALUE = "carrier_config";
-
-    /** Indicates the bandwidth estimation source is from {@link LinkBandwidthEstimator}. */
-    private static final String BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_STRING_VALUE =
-            "bandwidth_estimator";
-
-    /** Default downlink and uplink bandwidth value in kbps. */
-    private static final int DEFAULT_BANDWIDTH = 14;
-
-    /** Network type GPRS. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_GPRS = "GPRS";
-
-    /** Network type EDGE. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_EDGE = "EDGE";
-
-    /** Network type UMTS. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_UMTS = "UMTS";
-
-    /** Network type CDMA. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_CDMA = "CDMA";
-
-    /** Network type 1xRTT. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_1xRTT = "1xRTT";
-
-    /** Network type EvDo Rev 0. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_EVDO_0 = "EvDo_0";
-
-    /** Network type EvDo Rev A. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_EVDO_A = "EvDo_A";
-
-    /** Network type HSDPA. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_HSDPA = "HSDPA";
-
-    /** Network type HSUPA. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_HSUPA = "HSUPA";
-
-    /** Network type HSPA. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_HSPA = "HSPA";
-
-    /** Network type EvDo Rev B. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_EVDO_B = "EvDo_B";
-
-    /** Network type eHRPD. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_EHRPD = "eHRPD";
-
-    /** Network type iDEN. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_IDEN = "iDEN";
-
-    /** Network type LTE. Should not be used outside of DataConfigManager. */
-    // TODO: Public only for use by DcTracker. This should be private once DcTracker is removed.
-    public static final String DATA_CONFIG_NETWORK_TYPE_LTE = "LTE";
-
-    /** Network type HSPA+. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_HSPAP = "HSPA+";
-
-    /** Network type GSM. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_GSM = "GSM";
-
-    /** Network type IWLAN. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_IWLAN = "IWLAN";
-
-    /** Network type TD_SCDMA. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_TD_SCDMA = "TD_SCDMA";
-
-    /** Network type LTE_CA. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_LTE_CA = "LTE_CA";
-
-    /** Network type NR_NSA. Should not be used outside of DataConfigManager. */
-    // TODO: Public only for use by DcTracker. This should be private once DcTracker is removed.
-    public static final String DATA_CONFIG_NETWORK_TYPE_NR_NSA = "NR_NSA";
-
-    /** Network type NR_NSA_MMWAVE. Should not be used outside of DataConfigManager. */
-    // TODO: Public only for use by DcTracker. This should be private once DcTracker is removed.
-    public static final String DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE = "NR_NSA_MMWAVE";
-
-    /** Network type NR_SA. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_NR_SA = "NR_SA";
-
-    /** Network type NR_SA_MMWAVE. Should not be used outside of DataConfigManager. */
-    private static final String DATA_CONFIG_NETWORK_TYPE_NR_SA_MMWAVE = "NR_SA_MMWAVE";
-
-    @StringDef(prefix = {"DATA_CONFIG_NETWORK_TYPE_"}, value = {
-            DATA_CONFIG_NETWORK_TYPE_GPRS,
-            DATA_CONFIG_NETWORK_TYPE_EDGE,
-            DATA_CONFIG_NETWORK_TYPE_UMTS,
-            DATA_CONFIG_NETWORK_TYPE_CDMA,
-            DATA_CONFIG_NETWORK_TYPE_1xRTT,
-            DATA_CONFIG_NETWORK_TYPE_EVDO_0,
-            DATA_CONFIG_NETWORK_TYPE_EVDO_A,
-            DATA_CONFIG_NETWORK_TYPE_HSDPA,
-            DATA_CONFIG_NETWORK_TYPE_HSUPA,
-            DATA_CONFIG_NETWORK_TYPE_HSPA,
-            DATA_CONFIG_NETWORK_TYPE_EVDO_B,
-            DATA_CONFIG_NETWORK_TYPE_EHRPD,
-            DATA_CONFIG_NETWORK_TYPE_IDEN,
-            DATA_CONFIG_NETWORK_TYPE_LTE,
-            DATA_CONFIG_NETWORK_TYPE_HSPAP,
-            DATA_CONFIG_NETWORK_TYPE_GSM,
-            DATA_CONFIG_NETWORK_TYPE_IWLAN,
-            DATA_CONFIG_NETWORK_TYPE_TD_SCDMA,
-            DATA_CONFIG_NETWORK_TYPE_LTE_CA,
-            DATA_CONFIG_NETWORK_TYPE_NR_NSA,
-            DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE,
-            DATA_CONFIG_NETWORK_TYPE_NR_SA,
-            DATA_CONFIG_NETWORK_TYPE_NR_SA_MMWAVE,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    private @interface DataConfigNetworkType {}
-
-    /** DeviceConfig key of anomaly report threshold for back to back ims release-request. */
-    private static final String KEY_ANOMALY_IMS_RELEASE_REQUEST = "anomaly_ims_release_request";
-    /** DeviceConfig key of anomaly report threshold for frequent setup data failure. */
-    private static final String KEY_ANOMALY_SETUP_DATA_CALL_FAILURE =
-            "anomaly_setup_data_call_failure";
-    /** DeviceConfig key of anomaly report threshold for frequent network-unwanted call. */
-    private static final String KEY_ANOMALY_NETWORK_UNWANTED = "anomaly_network_unwanted";
-    /** DeviceConfig key of anomaly report threshold for DataNetwork stuck in connecting state. */
-    private static final String KEY_ANOMALY_NETWORK_CONNECTING_TIMEOUT =
-            "anomaly_network_connecting_timeout";
-    /** DeviceConfig key of anomaly report threshold for DataNetwork stuck in disconnecting state.*/
-    private static final String KEY_ANOMALY_NETWORK_DISCONNECTING_TIMEOUT =
-            "anomaly_network_disconnecting_timeout";
-    /** DeviceConfig key of anomaly report threshold for DataNetwork stuck in handover state. */
-    private static final String KEY_ANOMALY_NETWORK_HANDOVER_TIMEOUT =
-            "anomaly_network_handover_timeout";
-
-    /** Anomaly report thresholds for frequent setup data call failure. */
-    private EventFrequency mSetupDataCallAnomalyReportThreshold;
-
-    /** Anomaly report thresholds for back to back release-request of IMS. */
-    private EventFrequency mImsReleaseRequestAnomalyReportThreshold;
-
-    /**
-     * Anomaly report thresholds for frequent network unwanted call
-     * at {@link TelephonyNetworkAgent#onNetworkUnwanted}
-     */
-    private EventFrequency mNetworkUnwantedAnomalyReportThreshold;
-
-    /**
-     * Timeout in ms before creating an anomaly report for a DataNetwork stuck in
-     * {@link DataNetwork.ConnectingState}.
-     */
-    private int mNetworkConnectingTimeout;
-
-    /**
-     * Timeout in ms before creating an anomaly report for a DataNetwork stuck in
-     * {@link DataNetwork.DisconnectingState}.
-     */
-    private int mNetworkDisconnectingTimeout;
-
-    /**
-     * Timeout in ms before creating an anomaly report for a DataNetwork stuck in
-     * {@link DataNetwork.HandoverState}.
-     */
-    private int mNetworkHandoverTimeout;
-
-    private @NonNull final Phone mPhone;
-    private @NonNull final String mLogTag;
-
-    /** The registrants list for config update event. */
-    private @NonNull final RegistrantList mConfigUpdateRegistrants = new RegistrantList();
-
-    private @NonNull final CarrierConfigManager mCarrierConfigManager;
-    private @NonNull PersistableBundle mCarrierConfig = null;
-    private @NonNull Resources mResources = null;
-
-    /** The network capability priority map */
-    private @NonNull final Map<Integer, Integer> mNetworkCapabilityPriorityMap =
-            new ConcurrentHashMap<>();
-    /** The data setup retry rules */
-    private @NonNull final List<DataSetupRetryRule> mDataSetupRetryRules = new ArrayList<>();
-    /** The data handover retry rules */
-    private @NonNull final List<DataHandoverRetryRule> mDataHandoverRetryRules = new ArrayList<>();
-    /** The metered APN types for home network */
-    private @NonNull final @ApnType Set<Integer> mMeteredApnTypes = new HashSet<>();
-    /** The metered APN types for roaming network */
-    private @NonNull final @ApnType Set<Integer> mRoamingMeteredApnTypes = new HashSet<>();
-    /** The network types that only support single data networks */
-    private @NonNull final @NetworkType List<Integer> mSingleDataNetworkTypeList =
-            new ArrayList<>();
-    /** The network types that support temporarily not metered */
-    private @NonNull final @DataConfigNetworkType Set<String> mUnmeteredNetworkTypes =
-            new HashSet<>();
-    /** The network types that support temporarily not metered when roaming */
-    private @NonNull final @DataConfigNetworkType Set<String> mRoamingUnmeteredNetworkTypes =
-            new HashSet<>();
-    /** A map of network types to the downlink and uplink bandwidth values for that network type */
-    private @NonNull final @DataConfigNetworkType Map<String, DataNetwork.NetworkBandwidth>
-            mBandwidthMap = new ConcurrentHashMap<>();
-    /** A map of network types to the TCP buffer sizes for that network type */
-    private @NonNull final @DataConfigNetworkType Map<String, String> mTcpBufferSizeMap =
-            new ConcurrentHashMap<>();
-    /** Rules for handover between IWLAN and cellular network. */
-    private @NonNull final List<HandoverRule> mHandoverRuleList = new ArrayList<>();
-
-    /**
-     * Constructor
-     *
-     * @param phone The phone instance.
-     * @param looper The looper to be used by the handler. Currently the handler thread is the
-     * phone process's main thread.
-     */
-    public DataConfigManager(@NonNull Phone phone, @NonNull Looper looper) {
-        super(looper);
-        mPhone = phone;
-        mLogTag = "DCM-" + mPhone.getPhoneId();
-        log("DataConfigManager created.");
-
-        mCarrierConfigManager = mPhone.getContext().getSystemService(CarrierConfigManager.class);
-
-        // Register for carrier configs update
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        mPhone.getContext().registerReceiver(new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
-                    if (mPhone.getPhoneId() == intent.getIntExtra(
-                            CarrierConfigManager.EXTRA_SLOT_INDEX,
-                            SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
-                        sendEmptyMessage(EVENT_CARRIER_CONFIG_CHANGED);
-                    }
-                }
-            }
-        }, filter, null, mPhone);
-
-        // Register for device config update
-        DeviceConfig.addOnPropertiesChangedListener(
-                DeviceConfig.NAMESPACE_TELEPHONY, this::post,
-                properties -> {
-                    if (TextUtils.equals(DeviceConfig.NAMESPACE_TELEPHONY,
-                            properties.getNamespace())) {
-                        sendEmptyMessage(EVENT_DEVICE_CONFIG_CHANGED);
-                    }
-                });
-
-        // Must be called to set mCarrierConfig and mResources to non-null values
-        updateCarrierConfig();
-        updateDeviceConfig();
-        mConfigUpdateRegistrants.notifyRegistrants();
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-            case EVENT_CARRIER_CONFIG_CHANGED:
-                log("EVENT_CARRIER_CONFIG_CHANGED");
-                updateCarrierConfig();
-                mConfigUpdateRegistrants.notifyRegistrants();
-                break;
-            case EVENT_DEVICE_CONFIG_CHANGED:
-                log("EVENT_DEVICE_CONFIG_CHANGED");
-                updateDeviceConfig();
-                mConfigUpdateRegistrants.notifyRegistrants();
-                break;
-            default:
-                loge("Unexpected message " + msg.what);
-        }
-    }
-
-    /** Update local properties from {@link DeviceConfig} */
-    private void updateDeviceConfig() {
-        DeviceConfig.Properties properties = //read all telephony properties
-                DeviceConfig.getProperties(DeviceConfig.NAMESPACE_TELEPHONY);
-
-        mImsReleaseRequestAnomalyReportThreshold = parseSlidingWindowCounterThreshold(
-                properties.getString(KEY_ANOMALY_IMS_RELEASE_REQUEST, null),
-                0,
-                12);
-        mNetworkUnwantedAnomalyReportThreshold = parseSlidingWindowCounterThreshold(
-                properties.getString(KEY_ANOMALY_NETWORK_UNWANTED, null),
-                0,
-                12);
-        mSetupDataCallAnomalyReportThreshold = parseSlidingWindowCounterThreshold(
-                properties.getString(KEY_ANOMALY_SETUP_DATA_CALL_FAILURE, null),
-                0,
-                2);
-        mNetworkConnectingTimeout = properties.getInt(
-                KEY_ANOMALY_NETWORK_CONNECTING_TIMEOUT, DEFAULT_NETWORK_TRANSIT_STATE_TIMEOUT_MS);
-        mNetworkDisconnectingTimeout = properties.getInt(
-                KEY_ANOMALY_NETWORK_DISCONNECTING_TIMEOUT,
-                DEFAULT_NETWORK_TRANSIT_STATE_TIMEOUT_MS);
-        mNetworkHandoverTimeout = properties.getInt(
-                KEY_ANOMALY_NETWORK_HANDOVER_TIMEOUT, DEFAULT_NETWORK_TRANSIT_STATE_TIMEOUT_MS);
-    }
-
-    /**
-     * @return {@code true} if the configuration is carrier specific. {@code false} if the
-     * configuration is the default (i.e. SIM not inserted).
-     */
-    public boolean isConfigCarrierSpecific() {
-        return mCarrierConfig.getBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL);
-    }
-
-    /**
-     * Update the configuration from carrier configs and resources.
-     */
-    private void updateCarrierConfig() {
-        if (mCarrierConfigManager != null) {
-            mCarrierConfig = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId());
-        }
-        if (mCarrierConfig == null) {
-            mCarrierConfig = CarrierConfigManager.getDefaultConfig();
-        }
-        mResources = SubscriptionManager.getResourcesForSubId(mPhone.getContext(),
-                mPhone.getSubId());
-
-        updateNetworkCapabilityPriority();
-        updateDataRetryRules();
-        updateMeteredApnTypes();
-        updateSingleDataNetworkTypeList();
-        updateUnmeteredNetworkTypes();
-        updateBandwidths();
-        updateTcpBuffers();
-        updateHandoverRules();
-
-        log("Data config updated. Config is " + (isConfigCarrierSpecific() ? "" : "not ")
-                + "carrier specific.");
-    }
-
-    /**
-     * Update the network capability priority from carrier config.
-     */
-    private void updateNetworkCapabilityPriority() {
-        synchronized (this) {
-            mNetworkCapabilityPriorityMap.clear();
-            String[] capabilityPriorityStrings = mCarrierConfig.getStringArray(
-                    CarrierConfigManager.KEY_TELEPHONY_NETWORK_CAPABILITY_PRIORITIES_STRING_ARRAY);
-            if (capabilityPriorityStrings != null) {
-                for (String capabilityPriorityString : capabilityPriorityStrings) {
-                    capabilityPriorityString = capabilityPriorityString.trim().toUpperCase();
-                    String[] tokens = capabilityPriorityString.split(":");
-                    if (tokens.length != 2) {
-                        loge("Invalid config \"" + capabilityPriorityString + "\"");
-                        continue;
-                    }
-
-                    int netCap = DataUtils.getNetworkCapabilityFromString(tokens[0]);
-                    if (netCap < 0) {
-                        loge("Invalid config \"" + capabilityPriorityString + "\"");
-                        continue;
-                    }
-
-                    int priority = Integer.parseInt(tokens[1]);
-                    mNetworkCapabilityPriorityMap.put(netCap, priority);
-                }
-            }
-        }
-    }
-
-    /**
-     * Get the priority of a network capability.
-     *
-     * @param capability The network capability
-     * @return The priority range from 0 ~ 100. 100 is the highest priority.
-     */
-    public int getNetworkCapabilityPriority(@NetCapability int capability) {
-        if (mNetworkCapabilityPriorityMap.containsKey(capability)) {
-            return mNetworkCapabilityPriorityMap.get(capability);
-        }
-        return 0;
-    }
-
-    /**
-     * Update the data retry rules from the carrier config.
-     */
-    private void updateDataRetryRules() {
-        synchronized (this) {
-            mDataSetupRetryRules.clear();
-            String[] dataRetryRulesStrings = mCarrierConfig.getStringArray(
-                    CarrierConfigManager.KEY_TELEPHONY_DATA_SETUP_RETRY_RULES_STRING_ARRAY);
-            if (dataRetryRulesStrings != null) {
-                for (String ruleString : dataRetryRulesStrings) {
-                    try {
-                        mDataSetupRetryRules.add(new DataSetupRetryRule(ruleString));
-                    } catch (IllegalArgumentException e) {
-                        loge("updateDataRetryRules: " + e.getMessage());
-                    }
-                }
-            }
-
-            mDataHandoverRetryRules.clear();
-            dataRetryRulesStrings = mCarrierConfig.getStringArray(
-                    CarrierConfigManager.KEY_TELEPHONY_DATA_HANDOVER_RETRY_RULES_STRING_ARRAY);
-            if (dataRetryRulesStrings != null) {
-                for (String ruleString : dataRetryRulesStrings) {
-                    try {
-                        mDataHandoverRetryRules.add(new DataHandoverRetryRule(ruleString));
-                    } catch (IllegalArgumentException e) {
-                        loge("updateDataRetryRules: " + e.getMessage());
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * @return The data setup retry rules from carrier config.
-     */
-    public @NonNull List<DataSetupRetryRule> getDataSetupRetryRules() {
-        return Collections.unmodifiableList(mDataSetupRetryRules);
-    }
-
-    /**
-     * @return The data handover retry rules from carrier config.
-     */
-    public @NonNull List<DataHandoverRetryRule> getDataHandoverRetryRules() {
-        return Collections.unmodifiableList(mDataHandoverRetryRules);
-    }
-
-    /**
-     * @return Whether data roaming is enabled by default in carrier config.
-     */
-    public boolean isDataRoamingEnabledByDefault() {
-        return mCarrierConfig.getBoolean(
-                CarrierConfigManager.KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL);
-    }
-
-    /**
-     * Update the home and roaming metered APN types from the carrier config.
-     */
-    private void updateMeteredApnTypes() {
-        synchronized (this) {
-            mMeteredApnTypes.clear();
-            String[] meteredApnTypes = mCarrierConfig.getStringArray(
-                    CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS);
-            if (meteredApnTypes != null) {
-                Arrays.stream(meteredApnTypes)
-                        .map(ApnSetting::getApnTypeInt)
-                        .forEach(mMeteredApnTypes::add);
-            }
-            mRoamingMeteredApnTypes.clear();
-            String[] roamingMeteredApns = mCarrierConfig.getStringArray(
-                    CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS);
-            if (roamingMeteredApns != null) {
-                Arrays.stream(roamingMeteredApns)
-                        .map(ApnSetting::getApnTypeInt)
-                        .forEach(mRoamingMeteredApnTypes::add);
-            }
-        }
-    }
-
-    /**
-     * Get the metered network capabilities.
-     *
-     * @param isRoaming {@code true} for roaming scenario.
-     *
-     * @return The metered network capabilities when connected to a home network.
-     */
-    public @NonNull @NetCapability Set<Integer> getMeteredNetworkCapabilities(boolean isRoaming) {
-        Set<Integer> meteredApnTypes = isRoaming ? mRoamingMeteredApnTypes : mMeteredApnTypes;
-        return meteredApnTypes.stream()
-                .map(DataUtils::apnTypeToNetworkCapability)
-                .filter(cap -> cap >= 0)
-                .collect(Collectors.toUnmodifiableSet());
-    }
-
-    /**
-     * @return {@code true} if tethering profile should not be used when the device is roaming.
-     */
-    public boolean isTetheringProfileDisabledForRoaming() {
-        return mCarrierConfig.getBoolean(
-                CarrierConfigManager.KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL);
-    }
-
-    /**
-     * Check if the network capability metered.
-     *
-     * @param networkCapability The network capability.
-     * @param isRoaming {@code true} for roaming scenario.
-     * @return {@code true} if the network capability is metered.
-     */
-    public boolean isMeteredCapability(@NetCapability int networkCapability, boolean isRoaming) {
-        return getMeteredNetworkCapabilities(isRoaming).contains(networkCapability);
-    }
-
-    /**
-     * Check if the network capabilities are metered. If one of the capabilities is metered, then
-     * the capabilities are metered.
-     *
-     * @param networkCapabilities The network capabilities.
-     * @param isRoaming {@code true} for roaming scenario.
-     * @return {@code true} if the capabilities are metered.
-     */
-    public boolean isAnyMeteredCapability(@NonNull @NetCapability int[] networkCapabilities,
-            boolean isRoaming) {
-        return Arrays.stream(networkCapabilities).boxed()
-                .anyMatch(cap -> isMeteredCapability(cap, isRoaming));
-    }
-
-    /**
-     * @return Whether to use data activity for RRC detection
-     */
-    public boolean shouldUseDataActivityForRrcDetection() {
-        return mCarrierConfig.getBoolean(
-                CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL);
-    }
-
-    /**
-     * Update the network types for only single data networks from the carrier config.
-     */
-    private void updateSingleDataNetworkTypeList() {
-        synchronized (this) {
-            mSingleDataNetworkTypeList.clear();
-            int[] singleDataNetworkTypeList = mCarrierConfig.getIntArray(
-                    CarrierConfigManager.KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY);
-            if (singleDataNetworkTypeList != null) {
-                Arrays.stream(singleDataNetworkTypeList)
-                        .forEach(mSingleDataNetworkTypeList::add);
-            }
-        }
-    }
-
-    /**
-     * @return The list of {@link NetworkType} that only supports single data networks
-     */
-    public @NonNull @NetworkType List<Integer> getNetworkTypesOnlySupportSingleDataNetwork() {
-        return Collections.unmodifiableList(mSingleDataNetworkTypeList);
-    }
-
-    /**
-     * @return Whether {@link NetworkCapabilities#NET_CAPABILITY_TEMPORARILY_NOT_METERED}
-     * is supported by the carrier.
-     */
-    public boolean isTempNotMeteredSupportedByCarrier() {
-        return mCarrierConfig.getBoolean(
-                CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL);
-    }
-
-    /**
-     * Update the network types that are temporarily not metered from the carrier config.
-     */
-    private void updateUnmeteredNetworkTypes() {
-        synchronized (this) {
-            mUnmeteredNetworkTypes.clear();
-            String[] unmeteredNetworkTypes = mCarrierConfig.getStringArray(
-                    CarrierConfigManager.KEY_UNMETERED_NETWORK_TYPES_STRING_ARRAY);
-            if (unmeteredNetworkTypes != null) {
-                mUnmeteredNetworkTypes.addAll(Arrays.asList(unmeteredNetworkTypes));
-            }
-            mRoamingUnmeteredNetworkTypes.clear();
-            String[] roamingUnmeteredNetworkTypes = mCarrierConfig.getStringArray(
-                    CarrierConfigManager.KEY_ROAMING_UNMETERED_NETWORK_TYPES_STRING_ARRAY);
-            if (roamingUnmeteredNetworkTypes != null) {
-                mRoamingUnmeteredNetworkTypes.addAll(Arrays.asList(roamingUnmeteredNetworkTypes));
-            }
-        }
-    }
-
-    /**
-     * Get whether the network type is unmetered from the carrier configs.
-     *
-     * @param displayInfo The {@link TelephonyDisplayInfo} to check meteredness for.
-     * @param serviceState The {@link ServiceState}, used to determine roaming state.
-     * @return Whether the carrier considers the given display info unmetered.
-     */
-    public boolean isNetworkTypeUnmetered(@NonNull TelephonyDisplayInfo displayInfo,
-            @NonNull ServiceState serviceState) {
-        String dataConfigNetworkType = getDataConfigNetworkType(displayInfo);
-        return serviceState.getDataRoaming()
-                ? mRoamingUnmeteredNetworkTypes.contains(dataConfigNetworkType)
-                : mUnmeteredNetworkTypes.contains(dataConfigNetworkType);
-    }
-
-    /**
-     * Update the downlink and uplink bandwidth values from the carrier config.
-     */
-    private void updateBandwidths() {
-        synchronized (this) {
-            mBandwidthMap.clear();
-            String[] bandwidths = mCarrierConfig.getStringArray(
-                    CarrierConfigManager.KEY_BANDWIDTH_STRING_ARRAY);
-            boolean useLte = mCarrierConfig.getBoolean(CarrierConfigManager
-                    .KEY_BANDWIDTH_NR_NSA_USE_LTE_VALUE_FOR_UPLINK_BOOL);
-            if (bandwidths != null) {
-                for (String bandwidth : bandwidths) {
-                    // split1[0] = network type as string
-                    // split1[1] = downlink,uplink
-                    String[] split1 = bandwidth.split(":");
-                    if (split1.length != 2) {
-                        loge("Invalid bandwidth: " + bandwidth);
-                        continue;
-                    }
-                    // split2[0] = downlink bandwidth in kbps
-                    // split2[1] = uplink bandwidth in kbps
-                    String[] split2 = split1[1].split(",");
-                    if (split2.length != 2) {
-                        loge("Invalid bandwidth values: " + Arrays.toString(split2));
-                        continue;
-                    }
-                    int downlink, uplink;
-                    try {
-                        downlink = Integer.parseInt(split2[0]);
-                        uplink = Integer.parseInt(split2[1]);
-                    } catch (NumberFormatException e) {
-                        loge("Exception parsing bandwidth values for network type " + split1[0]
-                                + ": " + e);
-                        continue;
-                    }
-                    if (useLte && split1[0].startsWith("NR")) {
-                        // We can get it directly from mBandwidthMap because LTE is defined before
-                        // the NR values in CarrierConfigManager#KEY_BANDWIDTH_STRING_ARRAY.
-                        uplink = mBandwidthMap.get(DATA_CONFIG_NETWORK_TYPE_LTE)
-                                .uplinkBandwidthKbps;
-                    }
-                    mBandwidthMap.put(split1[0],
-                            new DataNetwork.NetworkBandwidth(downlink, uplink));
-                }
-            }
-        }
-    }
-
-    /**
-     * Get the bandwidth estimate from the carrier config.
-     *
-     * @param displayInfo The {@link TelephonyDisplayInfo} to get the bandwidth for.
-     * @return The pre-configured bandwidth estimate from carrier config.
-     */
-    public @NonNull DataNetwork.NetworkBandwidth getBandwidthForNetworkType(
-            @NonNull TelephonyDisplayInfo displayInfo) {
-        DataNetwork.NetworkBandwidth bandwidth = mBandwidthMap.get(
-                getDataConfigNetworkType(displayInfo));
-        if (bandwidth != null) {
-            return bandwidth;
-        }
-        return new DataNetwork.NetworkBandwidth(DEFAULT_BANDWIDTH, DEFAULT_BANDWIDTH);
-    }
-
-    /**
-     * @return Whether data throttling should be reset when the TAC changes from the carrier config.
-     */
-    public boolean shouldResetDataThrottlingWhenTacChanges() {
-        return mCarrierConfig.getBoolean(
-                CarrierConfigManager.KEY_UNTHROTTLE_DATA_RETRY_WHEN_TAC_CHANGES_BOOL);
-    }
-
-    /**
-     * @return The data service package override string from the carrier config.
-     */
-    public String getDataServicePackageName() {
-        return mCarrierConfig.getString(
-                CarrierConfigManager.KEY_CARRIER_DATA_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING);
-    }
-
-    /**
-     * @return The default MTU value in bytes from the carrier config.
-     */
-    public int getDefaultMtu() {
-        return mCarrierConfig.getInt(CarrierConfigManager.KEY_DEFAULT_MTU_INT);
-    }
-
-    /**
-     * Update the TCP buffer sizes from the resource overlays.
-     */
-    private void updateTcpBuffers() {
-        synchronized (this) {
-            mTcpBufferSizeMap.clear();
-            String[] configs = mResources.getStringArray(
-                    com.android.internal.R.array.config_network_type_tcp_buffers);
-            if (configs != null) {
-                for (String config : configs) {
-                    // split[0] = network type as string
-                    // split[1] = rmem_min,rmem_def,rmem_max,wmem_min,wmem_def,wmem_max
-                    String[] split = config.split(":");
-                    if (split.length != 2) {
-                        loge("Invalid TCP buffer sizes entry: " + config);
-                        continue;
-                    }
-                    if (split[1].split(",").length != 6) {
-                        loge("Invalid TCP buffer sizes for " + split[0] + ": " + split[1]);
-                        continue;
-                    }
-                    mTcpBufferSizeMap.put(split[0], split[1]);
-                }
-            }
-        }
-    }
-
-    /**
-     * Anomaly report thresholds for frequent setup data call failure.
-     * @return EventFrequency to trigger the anomaly report
-     */
-    public @NonNull EventFrequency getAnomalySetupDataCallThreshold() {
-        return mSetupDataCallAnomalyReportThreshold;
-    }
-
-    /**
-     * Anomaly report thresholds for frequent network unwanted call
-     * at {@link TelephonyNetworkAgent#onNetworkUnwanted}
-     * @return EventFrequency to trigger the anomaly report
-     */
-    public @NonNull EventFrequency getAnomalyNetworkUnwantedThreshold() {
-        return mNetworkUnwantedAnomalyReportThreshold;
-    }
-
-    /**
-     * Anomaly report thresholds for back to back release-request of IMS.
-     * @return EventFrequency to trigger the anomaly report
-     */
-    public @NonNull EventFrequency getAnomalyImsReleaseRequestThreshold() {
-        return mImsReleaseRequestAnomalyReportThreshold;
-    }
-
-    /**
-     * @return Timeout in ms before creating an anomaly report for a DataNetwork stuck in
-     * {@link DataNetwork.ConnectingState}.
-     */
-    public int getAnomalyNetworkConnectingTimeoutMs() {
-        return mNetworkConnectingTimeout;
-    }
-
-    /**
-     * @return Timeout in ms before creating an anomaly report for a DataNetwork stuck in
-     * {@link DataNetwork.DisconnectingState}.
-     */
-    public int getAnomalyNetworkDisconnectingTimeoutMs() {
-        return mNetworkDisconnectingTimeout;
-    }
-
-    /**
-     * @return Timeout in ms before creating an anomaly report for a DataNetwork stuck in
-     * {@link DataNetwork.HandoverState}.
-     */
-    public int getNetworkHandoverTimeoutMs() {
-        return mNetworkHandoverTimeout;
-    }
-
-    /**
-     * Get the TCP config string, used by {@link LinkProperties#setTcpBufferSizes(String)}.
-     * The config string will have the following form, with values in bytes:
-     * "read_min,read_default,read_max,write_min,write_default,write_max"
-     *
-     * @param displayInfo The {@link TelephonyDisplayInfo} to get the TCP config string for.
-     * @return The TCP configuration string for the given display info or the default value from
-     *         {@code config_tcp_buffers} if unavailable.
-     */
-    public @NonNull String getTcpConfigString(@NonNull TelephonyDisplayInfo displayInfo) {
-        String config = mTcpBufferSizeMap.get(getDataConfigNetworkType(displayInfo));
-        if (TextUtils.isEmpty(config)) {
-            config = getDefaultTcpConfigString();
-        }
-        return config;
-    }
-
-    /**
-     * @return The fixed TCP buffer size configured based on the device's memory and performance.
-     */
-    public @NonNull String getDefaultTcpConfigString() {
-        return mResources.getString(com.android.internal.R.string.config_tcp_buffers);
-    }
-
-    /**
-     * @return The delay in millisecond for IMS graceful tear down. If IMS/RCS de-registration
-     * does not complete within the window, the data network will be torn down after timeout.
-     */
-    public long getImsDeregistrationDelay() {
-        return mResources.getInteger(
-                com.android.internal.R.integer.config_delay_for_ims_dereg_millis);
-    }
-
-    /**
-     * @return {@code true} if PDN should persist when IWLAN data service restarted/crashed.
-     * {@code false} will cause all data networks on IWLAN torn down if IWLAN data service crashes.
-     */
-    public boolean shouldPersistIwlanDataNetworksWhenDataServiceRestarted() {
-        return mResources.getBoolean(com.android.internal.R.bool
-                .config_wlan_data_service_conn_persistence_on_restart);
-    }
-
-    /**
-     * @return {@code true} if adopt predefined IWLAN handover policy. If {@code false}, handover is
-     * allowed by default.
-     */
-    public boolean isIwlanHandoverPolicyEnabled() {
-        return mResources.getBoolean(com.android.internal.R.bool
-                .config_enable_iwlan_handover_policy);
-    }
-
-    /**
-     * @return {@code true} if tearing down IMS data network should be delayed until the voice call
-     * ends.
-     */
-    public boolean isImsDelayTearDownEnabled() {
-        return mCarrierConfig.getBoolean(
-                CarrierConfigManager.KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL);
-    }
-
-    /**
-     * @return The bandwidth estimation source.
-     */
-    public @DataNetwork.BandwidthEstimationSource int getBandwidthEstimateSource() {
-        String source = mResources.getString(
-                com.android.internal.R.string.config_bandwidthEstimateSource);
-        switch (source) {
-            case BANDWIDTH_SOURCE_MODEM_STRING_VALUE:
-                return DataNetwork.BANDWIDTH_SOURCE_MODEM;
-            case BANDWIDTH_SOURCE_CARRIER_CONFIG_STRING_VALUE:
-                return DataNetwork.BANDWIDTH_SOURCE_CARRIER_CONFIG;
-            case BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_STRING_VALUE:
-                return DataNetwork.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR;
-            default:
-                loge("Invalid bandwidth estimation source config: " + source);
-                return DataNetwork.BANDWIDTH_SOURCE_UNKNOWN;
-        }
-    }
-
-    /**
-     * Get the {@link DataConfigNetworkType} based on the given {@link TelephonyDisplayInfo}.
-     *
-     * @param displayInfo The {@link TelephonyDisplayInfo} used to determine the type.
-     * @return The equivalent {@link DataConfigNetworkType}.
-     */
-    public static @NonNull @DataConfigNetworkType String getDataConfigNetworkType(
-            @NonNull TelephonyDisplayInfo displayInfo) {
-        // TODO: Make method private once DataConnection is removed
-        int networkType = displayInfo.getNetworkType();
-        switch (displayInfo.getOverrideNetworkType()) {
-            case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED:
-                if (networkType == TelephonyManager.NETWORK_TYPE_NR) {
-                    return DATA_CONFIG_NETWORK_TYPE_NR_SA_MMWAVE;
-                } else {
-                    return DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE;
-                }
-            case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA:
-                return DATA_CONFIG_NETWORK_TYPE_NR_NSA;
-            case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO:
-            case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA:
-                return DATA_CONFIG_NETWORK_TYPE_LTE_CA;
-            case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE:
-            default:
-                return networkTypeToDataConfigNetworkType(networkType);
-        }
-    }
-
-    /** Update handover rules from carrier config. */
-    private void updateHandoverRules() {
-        synchronized (this) {
-            mHandoverRuleList.clear();
-            String[] handoverRulesStrings = mCarrierConfig.getStringArray(
-                    CarrierConfigManager.KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY);
-            if (handoverRulesStrings != null) {
-                for (String ruleString : handoverRulesStrings) {
-                    try {
-                        mHandoverRuleList.add(new HandoverRule(ruleString));
-                    } catch (IllegalArgumentException e) {
-                        loge("updateHandoverRules: " + e.getMessage());
-                    }
-                }
-            }
-        }
-    }
-
-    /**
-     * Describe an event occurs eventNumOccurrence within a time span timeWindow
-     */
-    public static class EventFrequency {
-        /** The time window in ms within which event occurs. */
-        public final long timeWindow;
-
-        /** The number of time the event occurs. */
-        public final int eventNumOccurrence;
-
-        /**
-         * Constructor
-         *
-         * @param timeWindow The time window in ms within which event occurs.
-         * @param eventNumOccurrence The number of time the event occurs.
-         */
-        public EventFrequency(long timeWindow, int eventNumOccurrence) {
-            this.timeWindow = timeWindow;
-            this.eventNumOccurrence = eventNumOccurrence;
-        }
-
-        @Override
-        public String toString() {
-            return String.format("EventFrequency=[timeWindow=%d, eventNumOccurrence=%d]",
-                    timeWindow, eventNumOccurrence);
-        }
-    }
-
-    /**
-     * Parse a pair of event throttle thresholds of the form "time window in ms,occurrences"
-     * into {@link EventFrequency}
-     * @param s String to be parsed in the form of "time window in ms,occurrences"
-     * @param defaultTimeWindow The time window to return if parsing failed.
-     * @param defaultOccurrences The occurrence to return if parsing failed.
-     * @return timeWindow and occurrence wrapped in EventFrequency
-     */
-    @VisibleForTesting
-    public EventFrequency parseSlidingWindowCounterThreshold(String s,
-            long defaultTimeWindow, int defaultOccurrences) {
-        EventFrequency defaultValue = new EventFrequency(defaultTimeWindow, defaultOccurrences);
-        if (TextUtils.isEmpty(s)) return defaultValue;
-
-        final String[] pair = s.split(",");
-        if (pair.length != 2) {
-            loge("Invalid format: " + s
-                    + "Format should be in \"time window in ms,occurrences\". "
-                    + "Using default instead.");
-            return defaultValue;
-        }
-        long windowSpan;
-        int occurrence;
-        try {
-            windowSpan = Long.parseLong(pair[0].trim());
-        } catch (NumberFormatException e) {
-            loge("Exception parsing SlidingWindow window span " + pair[0] + ": " + e);
-            return defaultValue;
-        }
-        try {
-            occurrence = Integer.parseInt(pair[1].trim());
-        } catch (NumberFormatException e) {
-            loge("Exception parsing SlidingWindow occurrence as integer " + pair[1] + ": " + e);
-            return defaultValue;
-        }
-        return new EventFrequency(windowSpan, occurrence);
-    }
-
-    /**
-     * @return Get rules for handover between IWLAN and cellular networks.
-     *
-     * @see CarrierConfigManager#KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY
-     */
-    public @NonNull List<HandoverRule> getHandoverRules() {
-        return Collections.unmodifiableList(mHandoverRuleList);
-    }
-
-    /**
-     * @return Get the delay in milliseconds for re-evaluating unsatisfied network requests.
-     */
-    public long getRetrySetupAfterDisconnectMillis() {
-        return mCarrierConfig.getLong(CarrierConfigManager
-                .KEY_CARRIER_DATA_CALL_APN_RETRY_AFTER_DISCONNECT_LONG);
-    }
-
-    /**
-     * Get the data config network type for the given network type
-     *
-     * @param networkType The network type
-     * @return The equivalent data config network type
-     */
-    private static @NonNull @DataConfigNetworkType String networkTypeToDataConfigNetworkType(
-            @NetworkType int networkType) {
-        switch (networkType) {
-            case TelephonyManager.NETWORK_TYPE_GPRS:
-                return DATA_CONFIG_NETWORK_TYPE_GPRS;
-            case TelephonyManager.NETWORK_TYPE_EDGE:
-                return DATA_CONFIG_NETWORK_TYPE_EDGE;
-            case TelephonyManager.NETWORK_TYPE_UMTS:
-                return DATA_CONFIG_NETWORK_TYPE_UMTS;
-            case TelephonyManager.NETWORK_TYPE_HSDPA:
-                return DATA_CONFIG_NETWORK_TYPE_HSDPA;
-            case TelephonyManager.NETWORK_TYPE_HSUPA:
-                return DATA_CONFIG_NETWORK_TYPE_HSUPA;
-            case TelephonyManager.NETWORK_TYPE_HSPA:
-                return DATA_CONFIG_NETWORK_TYPE_HSPA;
-            case TelephonyManager.NETWORK_TYPE_CDMA:
-                return DATA_CONFIG_NETWORK_TYPE_CDMA;
-            case TelephonyManager.NETWORK_TYPE_EVDO_0:
-                return DATA_CONFIG_NETWORK_TYPE_EVDO_0;
-            case TelephonyManager.NETWORK_TYPE_EVDO_A:
-                return DATA_CONFIG_NETWORK_TYPE_EVDO_A;
-            case TelephonyManager.NETWORK_TYPE_EVDO_B:
-                return DATA_CONFIG_NETWORK_TYPE_EVDO_B;
-            case TelephonyManager.NETWORK_TYPE_1xRTT:
-                return DATA_CONFIG_NETWORK_TYPE_1xRTT;
-            case TelephonyManager.NETWORK_TYPE_LTE:
-                return DATA_CONFIG_NETWORK_TYPE_LTE;
-            case TelephonyManager.NETWORK_TYPE_EHRPD:
-                return DATA_CONFIG_NETWORK_TYPE_EHRPD;
-            case TelephonyManager.NETWORK_TYPE_IDEN:
-                return DATA_CONFIG_NETWORK_TYPE_IDEN;
-            case TelephonyManager.NETWORK_TYPE_HSPAP:
-                return DATA_CONFIG_NETWORK_TYPE_HSPAP;
-            case TelephonyManager.NETWORK_TYPE_GSM:
-                return DATA_CONFIG_NETWORK_TYPE_GSM;
-            case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
-                return DATA_CONFIG_NETWORK_TYPE_TD_SCDMA;
-            case TelephonyManager.NETWORK_TYPE_IWLAN:
-                return DATA_CONFIG_NETWORK_TYPE_IWLAN;
-            case TelephonyManager.NETWORK_TYPE_LTE_CA:
-                return DATA_CONFIG_NETWORK_TYPE_LTE_CA;
-            case TelephonyManager.NETWORK_TYPE_NR:
-                return DATA_CONFIG_NETWORK_TYPE_NR_SA;
-            default:
-                return "";
-        }
-    }
-
-    /**
-     * @return Get recovery action delay in milliseconds between recovery actions.
-     *
-     * @see CarrierConfigManager#KEY_DATA_STALL_RECOVERY_TIMERS_LONG_ARRAY
-     */
-    public @NonNull long[] getDataStallRecoveryDelayMillis() {
-        return mCarrierConfig.getLongArray(
-            CarrierConfigManager.KEY_DATA_STALL_RECOVERY_TIMERS_LONG_ARRAY);
-    }
-
-    /**
-     * @return Get the data stall recovery should skip boolean array.
-     *
-     * @see CarrierConfigManager#KEY_DATA_STALL_RECOVERY_SHOULD_SKIP_BOOL_ARRAY
-     */
-    public @NonNull boolean[] getDataStallRecoveryShouldSkipArray() {
-        return mCarrierConfig.getBooleanArray(
-            CarrierConfigManager.KEY_DATA_STALL_RECOVERY_SHOULD_SKIP_BOOL_ARRAY);
-    }
-
-    /**
-     * @return The default preferred APN. An empty string if not configured. This is used for the
-     * first time boot up where preferred APN is not set.
-     */
-    public @NonNull String getDefaultPreferredApn() {
-        return TextUtils.emptyIfNull(mCarrierConfig.getString(
-                CarrierConfigManager.KEY_DEFAULT_PREFERRED_APN_NAME_STRING));
-    }
-
-    /**
-     * @return The PCO id used for determine if data networks are using NR advanced networks. 0
-     * indicates this feature is disabled.
-     */
-    public int getNrAdvancedCapablePcoId() {
-        return mCarrierConfig.getInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT);
-    }
-
-    /**
-     * @return The allowed APN types for initial attach. The order in the list determines the
-     * priority of it being considered as IA APN. Note this should be only used for some exception
-     * cases that we need to use "user-added" APN for initial attach. The regular way to configure
-     * IA APN is by adding "IA" type to the APN in APN config.
-     */
-    public @NonNull @ApnType List<Integer> getAllowedInitialAttachApnTypes() {
-        String[] apnTypesArray = mCarrierConfig.getStringArray(
-                CarrierConfigManager.KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY);
-        if (apnTypesArray != null) {
-            return Arrays.stream(apnTypesArray)
-                    .map(ApnSetting::getApnTypesBitmaskFromString)
-                    .collect(Collectors.toList());
-        }
-
-        return Collections.emptyList();
-    }
-
-    /**
-     * @return {@code true} if enhanced IWLAN handover check is enabled. If enabled, telephony
-     * frameworks will not perform handover if the target transport is out of service, or VoPS not
-     * supported. The network will be torn down on the source transport, and will be
-     * re-established on the target transport when condition is allowed for bringing up a new
-     * network.
-     */
-    public boolean isEnhancedIwlanHandoverCheckEnabled() {
-        return mResources.getBoolean(
-                com.android.internal.R.bool.config_enhanced_iwlan_handover_check);
-    }
-
-    /**
-     * Registration point for subscription info ready.
-     *
-     * @param h handler to notify.
-     * @param what what code of message when delivered.
-     */
-    public void registerForConfigUpdate(Handler h, int what) {
-        mConfigUpdateRegistrants.addUnique(h, what, null);
-    }
-
-    /**
-     *
-     * @param h The original handler passed in {@link #registerForConfigUpdate(Handler, int)}.
-     */
-    public void unregisterForConfigUpdate(Handler h) {
-        mConfigUpdateRegistrants.remove(h);
-    }
-
-    /**
-     * Log debug messages.
-     * @param s debug messages
-     */
-    private void log(@NonNull String s) {
-        Rlog.d(mLogTag, s);
-    }
-
-    /**
-     * Log error messages.
-     * @param s error messages
-     */
-    private void loge(@NonNull String s) {
-        Rlog.e(mLogTag, s);
-    }
-
-    /**
-     * Dump the state of DataConfigManager
-     *
-     * @param fd File descriptor
-     * @param printWriter Print writer
-     * @param args Arguments
-     */
-    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
-        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
-        pw.println(DataConfigManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":");
-        pw.increaseIndent();
-        pw.println("isConfigCarrierSpecific=" + isConfigCarrierSpecific());
-        pw.println("Network capability priority:");
-        pw.increaseIndent();
-        mNetworkCapabilityPriorityMap.forEach((key, value) -> pw.print(
-                DataUtils.networkCapabilityToString(key) + ":" + value + " "));
-        pw.decreaseIndent();
-        pw.println();
-        pw.println("Data setup retry rules:");
-        pw.increaseIndent();
-        mDataSetupRetryRules.forEach(pw::println);
-        pw.decreaseIndent();
-        pw.println("isIwlanHandoverPolicyEnabled=" + isIwlanHandoverPolicyEnabled());
-        pw.println("Data handover retry rules:");
-        pw.increaseIndent();
-        mDataHandoverRetryRules.forEach(pw::println);
-        pw.decreaseIndent();
-        pw.println("mSetupDataCallAnomalyReport=" + mSetupDataCallAnomalyReportThreshold);
-        pw.println("mNetworkUnwantedAnomalyReport=" + mNetworkUnwantedAnomalyReportThreshold);
-        pw.println("mImsReleaseRequestAnomalyReport=" + mImsReleaseRequestAnomalyReportThreshold);
-        pw.println("mNetworkConnectingTimeout=" + mNetworkConnectingTimeout);
-        pw.println("mNetworkDisconnectingTimeout=" + mNetworkDisconnectingTimeout);
-        pw.println("mNetworkHandoverTimeout=" + mNetworkHandoverTimeout);
-        pw.println("Metered APN types=" + mMeteredApnTypes.stream()
-                .map(ApnSetting::getApnTypeString).collect(Collectors.joining(",")));
-        pw.println("Roaming metered APN types=" + mRoamingMeteredApnTypes.stream()
-                .map(ApnSetting::getApnTypeString).collect(Collectors.joining(",")));
-        pw.println("Single data network types=" + mSingleDataNetworkTypeList.stream()
-                .map(TelephonyManager::getNetworkTypeName).collect(Collectors.joining(",")));
-        pw.println("Unmetered network types=" + String.join(",", mUnmeteredNetworkTypes));
-        pw.println("Roaming unmetered network types="
-                + String.join(",", mRoamingUnmeteredNetworkTypes));
-        pw.println("Bandwidths:");
-        pw.increaseIndent();
-        mBandwidthMap.forEach((key, value) -> pw.println(key + ":" + value));
-        pw.decreaseIndent();
-        pw.println("shouldUseDataActivityForRrcDetection="
-                + shouldUseDataActivityForRrcDetection());
-        pw.println("isTempNotMeteredSupportedByCarrier=" + isTempNotMeteredSupportedByCarrier());
-        pw.println("shouldResetDataThrottlingWhenTacChanges="
-                + shouldResetDataThrottlingWhenTacChanges());
-        pw.println("Data service package name=" + getDataServicePackageName());
-        pw.println("Default MTU=" + getDefaultMtu());
-        pw.println("TCP buffer sizes by RAT:");
-        pw.increaseIndent();
-        mTcpBufferSizeMap.forEach((key, value) -> pw.println(key + ":" + value));
-        pw.decreaseIndent();
-        pw.println("Default TCP buffer sizes=" + getDefaultTcpConfigString());
-        pw.println("getImsDeregistrationDelay=" + getImsDeregistrationDelay());
-        pw.println("shouldPersistIwlanDataNetworksWhenDataServiceRestarted="
-                + shouldPersistIwlanDataNetworksWhenDataServiceRestarted());
-        pw.println("Bandwidth estimation source=" + mResources.getString(
-                com.android.internal.R.string.config_bandwidthEstimateSource));
-        pw.println("isDelayTearDownImsEnabled=" + isImsDelayTearDownEnabled());
-        pw.println("isEnhancedIwlanHandoverCheckEnabled=" + isEnhancedIwlanHandoverCheckEnabled());
-        pw.println("isTetheringProfileDisabledForRoaming="
-                + isTetheringProfileDisabledForRoaming());
-        pw.decreaseIndent();
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/DataEvaluation.java b/src/java/com/android/internal/telephony/data/DataEvaluation.java
deleted file mode 100644
index c061e16..0000000
--- a/src/java/com/android/internal/telephony/data/DataEvaluation.java
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.CurrentTimeMillisLong;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.telephony.TelephonyManager;
-import android.telephony.data.DataProfile;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- * The class to describe a data evaluation for whether allowing or disallowing certain operations
- * like setup a data network, sustaining existing data networks, or handover between IWLAN and
- * cellular.
- */
-public class DataEvaluation {
-    /** The reason for this evaluation */
-    private final @NonNull DataEvaluationReason mDataEvaluationReason;
-
-    /** Data disallowed reasons. There could be multiple reasons for not allowing data. */
-    private final @NonNull Set<DataDisallowedReason> mDataDisallowedReasons = new HashSet<>();
-
-    /** Data allowed reason. It is intended to only have one allowed reason. */
-    private @NonNull DataAllowedReason mDataAllowedReason = DataAllowedReason.NONE;
-
-    private @Nullable DataProfile mCandidateDataProfile = null;
-
-    /** The timestamp of evaluation time */
-    private @CurrentTimeMillisLong long mEvaluatedTime = 0;
-
-    /**
-     * Constructor
-     *
-     * @param reason The reason for this evaluation.
-     */
-    public DataEvaluation(DataEvaluationReason reason) {
-        mDataEvaluationReason = reason;
-    }
-
-    /**
-     * Add a data disallowed reason. Note that adding a disallowed reason will clean up the
-     * allowed reason because they are mutual exclusive.
-     *
-     * @param reason Disallowed reason.
-     */
-    public void addDataDisallowedReason(DataDisallowedReason reason) {
-        mDataAllowedReason = DataAllowedReason.NONE;
-        mDataDisallowedReasons.add(reason);
-        mEvaluatedTime = System.currentTimeMillis();
-    }
-
-    /**
-     * Remove a data disallowed reason if one exists.
-     *
-     * @param reason Disallowed reason.
-     */
-    public void removeDataDisallowedReason(DataDisallowedReason reason) {
-        mDataDisallowedReasons.remove(reason);
-        mEvaluatedTime = System.currentTimeMillis();
-    }
-
-    /**
-     * Add a data allowed reason. Note that adding an allowed reason will clean up the disallowed
-     * reasons because they are mutual exclusive.
-     *
-     * @param reason Allowed reason.
-     */
-    public void addDataAllowedReason(DataAllowedReason reason) {
-        mDataDisallowedReasons.clear();
-
-        // Only higher priority allowed reason can overwrite the old one. See
-        // DataAllowedReason for the oder.
-        if (reason.ordinal() > mDataAllowedReason.ordinal()) {
-            mDataAllowedReason = reason;
-        }
-        mEvaluatedTime = System.currentTimeMillis();
-    }
-
-    /**
-     * @return List of data disallowed reasons.
-     */
-    public @NonNull List<DataDisallowedReason> getDataDisallowedReasons() {
-        return new ArrayList<>(mDataDisallowedReasons);
-    }
-
-    /**
-     * @return The data allowed reason.
-     */
-    public @NonNull DataAllowedReason getDataAllowedReason() {
-        return mDataAllowedReason;
-    }
-
-    /**
-     * Set the candidate data profile for setup data network.
-     *
-     * @param dataProfile The candidate data profile.
-     */
-    public void setCandidateDataProfile(@NonNull DataProfile dataProfile) {
-        mCandidateDataProfile = dataProfile;
-    }
-
-    /**
-     * @return The candidate data profile for setup data network.
-     */
-    public @Nullable DataProfile getCandidateDataProfile() {
-        return mCandidateDataProfile;
-    }
-
-    /**
-     * @return {@code true} if the evaluation contains disallowed reasons.
-     */
-    public boolean containsDisallowedReasons() {
-        return mDataDisallowedReasons.size() != 0;
-    }
-
-    /**
-     * Check if it contains a certain disallowed reason.
-     *
-     * @param reason The disallowed reason to check.
-     * @return {@code true} if the provided reason matches one of the disallowed reasons.
-     */
-    public boolean contains(DataDisallowedReason reason) {
-        return mDataDisallowedReasons.contains(reason);
-    }
-
-    /**
-     * Check if only one disallowed reason prevent data connection.
-     *
-     * @param reason The given reason to check
-     * @return {@code true} if the given reason is the only one that prevents data connection
-     */
-    public boolean containsOnly(DataDisallowedReason reason) {
-        return mDataDisallowedReasons.size() == 1 && contains(reason);
-    }
-
-    /**
-     * Check if the any of the disallowed reasons match one of the provided reason.
-     *
-     * @param reasons The given reasons to check.
-     * @return {@code true} if any of the given reasons matches one of the disallowed reasons.
-     */
-    public boolean containsAny(DataDisallowedReason... reasons) {
-        for (DataDisallowedReason reason : reasons) {
-            if (mDataDisallowedReasons.contains(reason)) return true;
-        }
-        return false;
-    }
-
-    /**
-     * Check if the allowed reason is the specified reason.
-     *
-     * @param reason The allowed reason.
-     * @return {@code true} if the specified reason matches the allowed reason.
-     */
-    public boolean contains(DataAllowedReason reason) {
-        return reason == mDataAllowedReason;
-    }
-
-    /**
-     * @return {@code true} if the disallowed reasons contains hard reasons.
-     */
-    public boolean containsHardDisallowedReasons() {
-        for (DataDisallowedReason reason : mDataDisallowedReasons) {
-            if (reason.isHardReason()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * The reason for evaluating unsatisfied network requests, existing data networks, and handover.
-     */
-    @VisibleForTesting
-    public enum DataEvaluationReason {
-        /** New request from the apps. */
-        NEW_REQUEST,
-        /** Data config changed. */
-        DATA_CONFIG_CHANGED,
-        /** SIM is loaded. */
-        SIM_LOADED,
-        /** SIM is removed. */
-        SIM_REMOVAL,
-        /** Data profiles changed. */
-        DATA_PROFILES_CHANGED,
-        /** When service state changes.(For now only considering data RAT and data registration). */
-        DATA_SERVICE_STATE_CHANGED,
-        /** When data is enabled or disabled (by user, carrier, thermal, etc...) */
-        DATA_ENABLED_CHANGED,
-        /** When data enabled overrides are changed (MMS always allowed, data on non-DDS sub). */
-        DATA_ENABLED_OVERRIDE_CHANGED,
-        /** When data roaming is enabled or disabled. */
-        ROAMING_ENABLED_CHANGED,
-        /** When voice call ended (for concurrent voice/data not supported RAT). */
-        VOICE_CALL_ENDED,
-        /** When network restricts or no longer restricts mobile data. */
-        DATA_RESTRICTED_CHANGED,
-        /** Network capabilities changed. The unsatisfied requests might have chances to attach. */
-        DATA_NETWORK_CAPABILITIES_CHANGED,
-        /** When emergency call started or ended. */
-        EMERGENCY_CALL_CHANGED,
-        /** When data disconnected, re-evaluate later to see if data could be brought up again. */
-        RETRY_AFTER_DISCONNECTED,
-        /** Data setup retry. */
-        DATA_RETRY,
-        /** For handover evaluation, or for network tearing down after handover succeeds/fails. */
-        DATA_HANDOVER,
-        /** Preferred transport changed. */
-        PREFERRED_TRANSPORT_CHANGED,
-        /** Slice config changed. */
-        SLICE_CONFIG_CHANGED,
-        /**
-         * Single data network arbitration. On certain RATs, only one data network is allowed at the
-         * same time.
-         */
-        SINGLE_DATA_NETWORK_ARBITRATION,
-        /** Query from {@link TelephonyManager#isDataConnectivityPossible()}. */
-        EXTERNAL_QUERY,
-        /** Tracking area code changed. */
-        TAC_CHANGED,
-    }
-
-    /** Disallowed reasons. There could be multiple reasons if it is not allowed. */
-    public enum DataDisallowedReason {
-        // Soft failure reasons. A soft reason means that in certain conditions, data is still
-        // allowed. Normally those reasons are due to users settings.
-        /** Data is disabled by the user or policy. */
-        DATA_DISABLED(false),
-        /** Data roaming is disabled by the user. */
-        ROAMING_DISABLED(false),
-        /** Default data not selected. */
-        DEFAULT_DATA_UNSELECTED(false),
-
-        // Belows are all hard failure reasons. A hard reason means no matter what the data should
-        // not be allowed.
-        /** Data registration state is not in service. */
-        NOT_IN_SERVICE(true),
-        /** Data config is not ready. */
-        DATA_CONFIG_NOT_READY(true),
-        /** SIM is not ready. */
-        SIM_NOT_READY(true),
-        /** Concurrent voice and data is not allowed. */
-        CONCURRENT_VOICE_DATA_NOT_ALLOWED(true),
-        /** Carrier notified data should be restricted. */
-        DATA_RESTRICTED_BY_NETWORK(true),
-        /** Radio power is off (i.e. airplane mode on) */
-        RADIO_POWER_OFF(true),
-        /** Data setup now allowed due to pending tear down all networks. */
-        PENDING_TEAR_DOWN_ALL(true),
-        /** Airplane mode is forcibly turned on by the carrier. */
-        RADIO_DISABLED_BY_CARRIER(true),
-        /** Underlying data service is not bound. */
-        DATA_SERVICE_NOT_READY(true),
-        /** Unable to find a suitable data profile. */
-        NO_SUITABLE_DATA_PROFILE(true),
-        /** Current data network type not allowed. */
-        DATA_NETWORK_TYPE_NOT_ALLOWED(true),
-        /** Device is currently in CDMA ECBM. */
-        CDMA_EMERGENCY_CALLBACK_MODE(true),
-        /** There is already a retry setup/handover scheduled. */
-        RETRY_SCHEDULED(true),
-        /** Network has explicitly request to throttle setup attempt. */
-        DATA_THROTTLED(true),
-        /** Data profile becomes invalid. (could be removed by the user, or SIM refresh, etc..) */
-        DATA_PROFILE_INVALID(true),
-        /** Data profile not preferred (i.e. users switch preferred profile in APN editor.) */
-        DATA_PROFILE_NOT_PREFERRED(true),
-        /** Handover is not allowed by policy. */
-        NOT_ALLOWED_BY_POLICY(true),
-        /** Data network is not in the right state. */
-        ILLEGAL_STATE(true),
-        /** VoPS is not supported by the network. */
-        VOPS_NOT_SUPPORTED(true),
-        /** Only one data network is allowed at one time. */
-        ONLY_ALLOWED_SINGLE_NETWORK(true),
-        /** Data enabled settings are not ready. */
-        DATA_SETTINGS_NOT_READY(true);
-
-        private final boolean mIsHardReason;
-
-        /**
-         * @return {@code true} if the disallowed reason is a hard reason.
-         */
-        public boolean isHardReason() {
-            return mIsHardReason;
-        }
-
-        /**
-         * Constructor
-         *
-         * @param isHardReason {@code true} if the disallowed reason is a hard reason. A hard reason
-         * means no matter what the data should not be allowed. A soft reason means that in certain
-         * conditions, data is still allowed.
-         */
-        DataDisallowedReason(boolean isHardReason) {
-            mIsHardReason = isHardReason;
-        }
-    }
-
-    /**
-     * Data allowed reasons. There will be only one reason if data is allowed.
-     */
-    public enum DataAllowedReason {
-        // Note that unlike disallowed reasons, we only have one allowed reason every time
-        // when we check data is allowed or not. The order of these allowed reasons is very
-        // important. The lower ones take precedence over the upper ones.
-        /**
-         * None. This is the initial value.
-         */
-        NONE,
-        /**
-         * The normal reason. This is the most common case.
-         */
-        NORMAL,
-        /**
-         * The network brought up by this network request is unmetered. Should allowed no matter
-         * the user enables or disables data.
-         */
-        UNMETERED_USAGE,
-        /**
-         * The network request supports MMS and MMS is always allowed.
-         */
-        MMS_REQUEST,
-        /**
-         * The network request is restricted (i.e. Only privilege apps can access the network.)
-         */
-        RESTRICTED_REQUEST,
-        /**
-         * SUPL is allowed while emergency call is ongoing.
-         */
-        EMERGENCY_SUPL,
-        /**
-         * Data is allowed because the network request is for emergency. This should be always at
-         * the bottom (i.e. highest priority)
-         */
-        EMERGENCY_REQUEST,
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder evaluationStr = new StringBuilder();
-        evaluationStr.append("Data evaluation: evaluation reason:" + mDataEvaluationReason + ", ");
-        if (mDataDisallowedReasons.size() > 0) {
-            evaluationStr.append("Data disallowed reasons:");
-            for (DataDisallowedReason reason : mDataDisallowedReasons) {
-                evaluationStr.append(" ").append(reason);
-            }
-        } else {
-            evaluationStr.append("Data allowed reason:");
-            evaluationStr.append(" ").append(mDataAllowedReason);
-        }
-        evaluationStr.append(", candidate profile=" + mCandidateDataProfile);
-        evaluationStr.append(", time=" + DataUtils.systemTimeToString(mEvaluatedTime));
-        return evaluationStr.toString();
-    }
-
-}
diff --git a/src/java/com/android/internal/telephony/data/DataNetwork.java b/src/java/com/android/internal/telephony/data/DataNetwork.java
deleted file mode 100644
index f85bc13..0000000
--- a/src/java/com/android/internal/telephony/data/DataNetwork.java
+++ /dev/null
@@ -1,3435 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NetworkAgent;
-import android.net.NetworkAgentConfig;
-import android.net.NetworkCapabilities;
-import android.net.NetworkFactory;
-import android.net.NetworkProvider;
-import android.net.NetworkScore;
-import android.net.ProxyInfo;
-import android.net.RouteInfo;
-import android.net.TelephonyNetworkSpecifier;
-import android.net.Uri;
-import android.net.vcn.VcnManager;
-import android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener;
-import android.net.vcn.VcnNetworkPolicyResult;
-import android.os.AsyncResult;
-import android.os.Looper;
-import android.os.Message;
-import android.os.Process;
-import android.os.SystemClock;
-import android.provider.Telephony;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.Annotation.DataFailureCause;
-import android.telephony.Annotation.DataState;
-import android.telephony.Annotation.NetCapability;
-import android.telephony.Annotation.NetworkType;
-import android.telephony.Annotation.ValidationStatus;
-import android.telephony.AnomalyReporter;
-import android.telephony.DataFailCause;
-import android.telephony.DataSpecificRegistrationInfo;
-import android.telephony.LinkCapacityEstimate;
-import android.telephony.NetworkRegistrationInfo;
-import android.telephony.PcoData;
-import android.telephony.PreciseDataConnectionState;
-import android.telephony.ServiceState;
-import android.telephony.SubscriptionManager;
-import android.telephony.SubscriptionPlan;
-import android.telephony.TelephonyDisplayInfo;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataCallResponse.HandoverFailureMode;
-import android.telephony.data.DataCallResponse.LinkStatus;
-import android.telephony.data.DataProfile;
-import android.telephony.data.DataService;
-import android.telephony.data.DataServiceCallback;
-import android.telephony.data.NetworkSliceInfo;
-import android.telephony.data.QosBearerSession;
-import android.telephony.data.TrafficDescriptor;
-import android.telephony.data.TrafficDescriptor.OsAppId;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.IndentingPrintWriter;
-import android.util.LocalLog;
-import android.util.SparseArray;
-import android.util.SparseIntArray;
-
-import com.android.internal.telephony.CarrierSignalAgent;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.RIL;
-import com.android.internal.telephony.data.DataEvaluation.DataAllowedReason;
-import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
-import com.android.internal.telephony.data.DataRetryManager.DataHandoverRetryEntry;
-import com.android.internal.telephony.data.DataRetryManager.DataRetryEntry;
-import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
-import com.android.internal.telephony.data.TelephonyNetworkAgent.TelephonyNetworkAgentCallback;
-import com.android.internal.telephony.metrics.DataCallSessionStats;
-import com.android.internal.telephony.metrics.TelephonyMetrics;
-import com.android.internal.util.ArrayUtils;
-import com.android.internal.util.IState;
-import com.android.internal.util.State;
-import com.android.internal.util.StateMachine;
-import com.android.net.module.util.LinkPropertiesUtils;
-import com.android.net.module.util.NetUtils;
-import com.android.net.module.util.NetworkCapabilitiesUtils;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.math.BigInteger;
-import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
-
-/**
- * DataNetwork class represents a single PDN (Packet Data Network).
- *
- * The life cycle of a data network starts from {@link ConnectingState}. If setup data request
- * succeeds, then it enters {@link ConnectedState}, otherwise it enters
- * {@link DisconnectedState}.
- *
- * When data network is in {@link ConnectingState}, it can enter {@link HandoverState} if handover
- * between IWLAN and cellular occurs. After handover completes or fails, it return back to
- * {@link ConnectedState}. When the data network is about to be disconnected, it first enters
- * {@link DisconnectingState} when performing graceful tear down or when sending the data
- * deactivation request. At the end, it enters {@link DisconnectedState} when {@link DataService}
- * notifies data disconnected. Note that an unsolicited disconnected event from {@link DataService}
- * or any vendor HAL failure response can immediately move data network from {@link ConnectedState}
- * to {@link DisconnectedState}. {@link DisconnectedState} is the final state of a data network.
- *
- * State machine diagram:
- *
- *
- *                                  ┌─────────┐
- *                                  │Handover │
- *                                  └─▲────┬──┘
- *                                    │    │
- *             ┌───────────┐        ┌─┴────▼──┐        ┌──────────────┐
- *             │Connecting ├────────►Connected├────────►Disconnecting │
- *             └─────┬─────┘        └────┬────┘        └───────┬──────┘
- *                   │                   │                     │
- *                   │             ┌─────▼──────┐              │
- *                   └─────────────►Disconnected◄──────────────┘
- *                                 └────────────┘
- *
- */
-public class DataNetwork extends StateMachine {
-    private static final boolean VDBG = false;
-    /** Event for data config updated. */
-    private static final int EVENT_DATA_CONFIG_UPDATED = 1;
-
-    /** Event for attaching a network request. */
-    private static final int EVENT_ATTACH_NETWORK_REQUEST = 2;
-
-    /** Event for detaching a network request. */
-    private static final int EVENT_DETACH_NETWORK_REQUEST = 3;
-
-    /** Event for allocating PDU session id response. */
-    private static final int EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE = 5;
-
-    /** Event for setup data network response. */
-    private static final int EVENT_SETUP_DATA_NETWORK_RESPONSE = 6;
-
-    /** Event for tearing down data network. */
-    private static final int EVENT_TEAR_DOWN_NETWORK = 7;
-
-    /** Event triggered by {@link DataServiceCallback#onDataCallListChanged(List)}. */
-    private static final int EVENT_DATA_STATE_CHANGED = 8;
-
-    /** Data network service state changed event. */
-    private static final int EVENT_SERVICE_STATE_CHANGED = 9;
-
-    /** Event for detaching all network requests. */
-    private static final int EVENT_DETACH_ALL_NETWORK_REQUESTS = 10;
-
-    /** Event for bandwidth estimation from the modem changed. */
-    private static final int EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED = 11;
-
-    /** Event for display info changed. This is for getting 5G NSA or mmwave information. */
-    private static final int EVENT_DISPLAY_INFO_CHANGED = 13;
-
-    /** Event for initiating an handover between cellular and IWLAN. */
-    private static final int EVENT_START_HANDOVER = 14;
-
-    /** Event for setup data call (for handover) response from the data service. */
-    private static final int EVENT_HANDOVER_RESPONSE = 15;
-
-    /** Event for subscription plan changed or unmetered/congested override set. */
-    private static final int EVENT_SUBSCRIPTION_PLAN_OVERRIDE = 16;
-
-    /** Event for PCO data received from network. */
-    private static final int EVENT_PCO_DATA_RECEIVED = 17;
-
-    /** Event for carrier privileged UIDs changed. */
-    private static final int EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED = 18;
-
-    /** Event for deactivate data network response. */
-    private static final int EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE = 19;
-
-    /**
-     * Event for data network stuck in transient (i.e. connecting/disconnecting/handover) state for
-     * too long time. Timeout value specified in
-     * {@link DataConfigManager#getAnomalyNetworkConnectingTimeoutMs()},
-     * {@link DataConfigManager#getAnomalyNetworkDisconnectingTimeoutMs()},
-     * {@link DataConfigManager#getNetworkHandoverTimeoutMs()}.
-     */
-    private static final int EVENT_STUCK_IN_TRANSIENT_STATE = 20;
-
-    /**
-     * Event for waiting for tearing down condition met. This will cause data network entering
-     * disconnecting state.
-     */
-    private static final int EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET = 21;
-
-    /** Event for call started. */
-    private static final int EVENT_VOICE_CALL_STARTED = 22;
-
-    /** Event for call ended. */
-    private static final int EVENT_VOICE_CALL_ENDED = 23;
-
-    /** Event for CSS indicator changed. */
-    private static final int EVENT_CSS_INDICATOR_CHANGED = 24;
-
-    /** Invalid context id. */
-    private static final int INVALID_CID = -1;
-
-    /**
-     * The data network providing default internet will have a higher score of 50. Other network
-     * will have a slightly lower score of 45. The intention is other connections will not cause
-     * connectivity service to tear down default internet connection. For example, to validate
-     * internet connection on non-default data SIM, we'll set up a temporary internet network on
-     * that data SIM. In this case, score of 45 is assigned so connectivity service will not replace
-     * the default internet network with it.
-     */
-    private static final int DEFAULT_INTERNET_NETWORK_SCORE = 50;
-    private static final int OTHER_NETWORK_SCORE = 45;
-
-    @IntDef(prefix = {"DEACTIVATION_REASON_"},
-            value = {
-                    TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED,
-                    TEAR_DOWN_REASON_SIM_REMOVAL,
-                    TEAR_DOWN_REASON_AIRPLANE_MODE_ON,
-                    TEAR_DOWN_REASON_DATA_DISABLED,
-                    TEAR_DOWN_REASON_NO_LIVE_REQUEST,
-                    TEAR_DOWN_REASON_RAT_NOT_ALLOWED,
-                    TEAR_DOWN_REASON_ROAMING_DISABLED,
-                    TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED,
-                    TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY,
-                    TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER,
-                    TEAR_DOWN_REASON_DATA_STALL,
-                    TEAR_DOWN_REASON_HANDOVER_FAILED,
-                    TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED,
-                    TEAR_DOWN_REASON_VCN_REQUESTED,
-                    TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED,
-                    TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED,
-                    TEAR_DOWN_REASON_NOT_IN_SERVICE,
-                    TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY,
-                    TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL,
-                    TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE,
-                    TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE,
-                    TEAR_DOWN_REASON_RETRY_SCHEDULED,
-                    TEAR_DOWN_REASON_DATA_THROTTLED,
-                    TEAR_DOWN_REASON_DATA_PROFILE_INVALID,
-                    TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED,
-                    TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY,
-                    TEAR_DOWN_REASON_ILLEGAL_STATE,
-                    TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK,
-                    TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED,
-            })
-    public @interface TearDownReason {}
-
-    /** Data network tear down requested by connectivity service. */
-    public static final int TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED = 1;
-
-    /** Data network tear down due to SIM removal. */
-    public static final int TEAR_DOWN_REASON_SIM_REMOVAL = 2;
-
-    /** Data network tear down due to airplane mode turned on. */
-    public static final int TEAR_DOWN_REASON_AIRPLANE_MODE_ON = 3;
-
-    /** Data network tear down due to data disabled (by user, policy, carrier, etc...). */
-    public static final int TEAR_DOWN_REASON_DATA_DISABLED = 4;
-
-    /** Data network tear down due to no live network request. */
-    public static final int TEAR_DOWN_REASON_NO_LIVE_REQUEST = 5;
-
-    /** Data network tear down due to current RAT is not allowed by the data profile. */
-    public static final int TEAR_DOWN_REASON_RAT_NOT_ALLOWED = 6;
-
-    /** Data network tear down due to data roaming not enabled. */
-    public static final int TEAR_DOWN_REASON_ROAMING_DISABLED = 7;
-
-    /** Data network tear down due to concurrent voice/data not allowed. */
-    public static final int TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED = 8;
-
-
-
-    /** Data network tear down due to data service unbound. */
-    public static final int TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY = 10;
-
-    /** Data network tear down due to radio turned off by the carrier. */
-    public static final int TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER = 11;
-
-    /** Data network tear down due to data stall. */
-    public static final int TEAR_DOWN_REASON_DATA_STALL = 12;
-
-    /** Data network tear down due to handover failed. */
-    public static final int TEAR_DOWN_REASON_HANDOVER_FAILED = 13;
-
-    /** Data network tear down due to handover not allowed. */
-    public static final int TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED = 14;
-
-    /** Data network tear down due to VCN service requested. */
-    public static final int TEAR_DOWN_REASON_VCN_REQUESTED = 15;
-
-    /** Data network tear down due to VOPS no longer supported. */
-    public static final int TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED = 16;
-
-    /** Data network tear down due to default data unselected. */
-    public static final int TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED = 17;
-
-    /** Data network tear down due to device not in service. */
-    public static final int TEAR_DOWN_REASON_NOT_IN_SERVICE = 18;
-
-    /** Data network tear down due to data config not ready. */
-    public static final int TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY = 19;
-
-    /** Data network tear down due to tear down all pending. */
-    public static final int TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL = 20;
-
-    /** Data network tear down due to no suitable data profile. */
-    public static final int TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE = 21;
-
-    /** Data network tear down due to CDMA ECBM. */
-    public static final int TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE = 22;
-
-    /** Data network tear down due to retry scheduled. */
-    public static final int TEAR_DOWN_REASON_RETRY_SCHEDULED = 23;
-
-    /** Data network tear down due to data throttled. */
-    public static final int TEAR_DOWN_REASON_DATA_THROTTLED = 24;
-
-    /** Data network tear down due to data profile invalid. */
-    public static final int TEAR_DOWN_REASON_DATA_PROFILE_INVALID = 25;
-
-    /** Data network tear down due to data profile not preferred. */
-    public static final int TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED = 26;
-
-    /** Data network tear down due to not allowed by policy. */
-    public static final int TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY = 27;
-
-    /** Data network tear down due to illegal state. */
-    public static final int TEAR_DOWN_REASON_ILLEGAL_STATE = 28;
-
-    /** Data network tear down due to only allowed single network. */
-    public static final int TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK = 29;
-
-    /** Data network tear down due to preferred data switched to another phone. */
-    public static final int TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED = 30;
-
-    @IntDef(prefix = {"BANDWIDTH_SOURCE_"},
-            value = {
-                    BANDWIDTH_SOURCE_UNKNOWN,
-                    BANDWIDTH_SOURCE_MODEM,
-                    BANDWIDTH_SOURCE_CARRIER_CONFIG,
-                    BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR,
-            })
-    public @interface BandwidthEstimationSource {}
-
-    /** Indicates the bandwidth estimation source is unknown. This must be a configuration error. */
-    public static final int BANDWIDTH_SOURCE_UNKNOWN = 0;
-
-    /** Indicates the bandwidth estimation source is from the modem. */
-    public static final int BANDWIDTH_SOURCE_MODEM = 1;
-
-    /** Indicates the bandwidth estimation source is from the static carrier config. */
-    public static final int BANDWIDTH_SOURCE_CARRIER_CONFIG = 2;
-
-    /** Indicates the bandwidth estimation source is from {@link LinkBandwidthEstimator}. */
-    public static final int BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR = 3;
-
-    /**
-     * The capabilities that are allowed to changed dynamically during the life cycle of network.
-     * This is copied from {@code NetworkCapabilities#MUTABLE_CAPABILITIES}. There is no plan to
-     * make this a connectivity manager API since in the future, immutable network capabilities
-     * would be allowed to changed dynamically. (i.e. not immutable anymore.)
-     */
-    private static final List<Integer> MUTABLE_CAPABILITIES = List.of(
-            NetworkCapabilities.NET_CAPABILITY_TRUSTED,
-            NetworkCapabilities.NET_CAPABILITY_VALIDATED,
-            NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL,
-            NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING,
-            NetworkCapabilities.NET_CAPABILITY_FOREGROUND,
-            NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED,
-            NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED,
-            NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY,
-            NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED,
-            NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED,
-            NetworkCapabilities.NET_CAPABILITY_HEAD_UNIT,
-            // Connectivity service will support NOT_METERED as a mutable and requestable
-            // capability.
-            NetworkCapabilities.NET_CAPABILITY_NOT_METERED,
-            // Even though MMTEL is an immutable capability, we still make it an mutable capability
-            // here before we have a better solution to deal with network transition from VoPS
-            // to non-VoPS network.
-            NetworkCapabilities.NET_CAPABILITY_MMTEL
-    );
-
-    /** The parent state. Any messages not handled by the child state fallback to this. */
-    private final DefaultState mDefaultState = new DefaultState();
-
-    /**
-     * The connecting state. This is the initial state of a data network.
-     *
-     * @see DataNetwork for the state machine diagram.
-     */
-    private final ConnectingState mConnectingState = new ConnectingState();
-
-    /**
-     * The connected state. This is the state when data network becomes usable.
-     *
-     * @see DataNetwork for the state machine diagram.
-     */
-    private final ConnectedState mConnectedState = new ConnectedState();
-
-    /**
-     * The handover state. This is the state when data network handover between IWLAN and cellular.
-     *
-     * @see DataNetwork for the state machine diagram.
-     */
-    private final HandoverState mHandoverState = new HandoverState();
-
-    /**
-     * The disconnecting state. This is the state when data network is about to be disconnected.
-     * The network is still usable in this state, but the clients should be prepared to lose the
-     * network in any moment. This state is particular useful for IMS graceful tear down, where
-     * the network enters disconnecting state while waiting for IMS de-registration signal.
-     *
-     * @see DataNetwork for the state machine diagram.
-     */
-    private final DisconnectingState mDisconnectingState = new DisconnectingState();
-
-    /**
-     * The disconnected state. This is the final state of a data network.
-     *
-     * @see DataNetwork for the state machine diagram.
-     */
-    private final DisconnectedState mDisconnectedState = new DisconnectedState();
-
-    /** The phone instance. */
-    private final @NonNull Phone mPhone;
-
-    /**
-     * The subscription id. This is assigned when the network is created, and not supposed to
-     * change afterwards.
-     */
-    private final int mSubId;
-
-    /** The network score of this network. */
-    private int mNetworkScore;
-
-    /**
-     * Indicates that
-     * {@link DataService.DataServiceProvider#deactivateDataCall(int, int, DataServiceCallback)}
-     * has been called. This flag can be only changed from {@code false} to {@code true}.
-     */
-    private boolean mInvokedDataDeactivation = false;
-
-    /**
-     * Indicates that if the data network has ever entered {@link ConnectedState}.
-     */
-    private boolean mEverConnected = false;
-
-    /** RIL interface. */
-    private final @NonNull CommandsInterface mRil;
-
-    /** Local log. */
-    private final LocalLog mLocalLog = new LocalLog(128);
-
-    /** The callback to receives data network state update. */
-    private final @NonNull DataNetworkCallback mDataNetworkCallback;
-
-    /** The log tag. */
-    private String mLogTag;
-
-    /** Metrics of per data network connection. */
-    private final DataCallSessionStats mDataCallSessionStats;
-
-    /**
-     * The unique context id assigned by the data service in {@link DataCallResponse#getId()}. One
-     * for {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN} and one for
-     * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN}. The reason for storing both is that
-     * during handover, both cid will be used.
-     */
-    private final SparseIntArray mCid = new SparseIntArray(2);
-
-    /**
-     * The initial network agent id. The network agent can be re-created due to immutable capability
-     * changed. This is to preserve the initial network agent id so the id in the logging tag won't
-     * change for the entire life cycle of data network.
-     */
-    private int mInitialNetworkAgentId;
-
-    /** PDU session id. */
-    private int mPduSessionId = DataCallResponse.PDU_SESSION_ID_NOT_SET;
-
-    /**
-     * Data service managers for accessing {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN} and
-     * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN} data services.
-     */
-    private final @NonNull SparseArray<DataServiceManager> mDataServiceManagers;
-
-    /** Access networks manager. */
-    private final @NonNull AccessNetworksManager mAccessNetworksManager;
-
-    /** Data network controller. */
-    private final @NonNull DataNetworkController mDataNetworkController;
-
-    /** Data config manager. */
-    private final @NonNull DataConfigManager mDataConfigManager;
-
-    /** VCN manager. */
-    private final @Nullable VcnManager mVcnManager;
-
-    /** VCN policy changed listener. */
-    private @Nullable VcnNetworkPolicyChangeListener mVcnPolicyChangeListener;
-
-    /** The network agent associated with this data network. */
-    private @NonNull TelephonyNetworkAgent mNetworkAgent;
-
-    /** QOS callback tracker. This is only created after network connected on WWAN. */
-    private @Nullable QosCallbackTracker mQosCallbackTracker;
-
-    /** NAT keepalive tracker. */
-    private @Nullable KeepaliveTracker mKeepaliveTracker;
-
-    /** The data profile used to establish this data network. */
-    private @NonNull DataProfile mDataProfile;
-
-    /**
-     * The data profile used for data handover. Some carriers might use different data profile
-     * between IWLAN and cellular. Only set before handover started.
-     */
-    private @Nullable DataProfile mHandoverDataProfile;
-
-    /** The network capabilities of this data network. */
-    private @NonNull NetworkCapabilities mNetworkCapabilities;
-
-    /** The matched traffic descriptor returned from setup data call request. */
-    private final @NonNull List<TrafficDescriptor> mTrafficDescriptors = new ArrayList<>();
-
-    /** The link properties of this data network. */
-    private @NonNull LinkProperties mLinkProperties;
-
-    /** The network slice info. */
-    private @Nullable NetworkSliceInfo mNetworkSliceInfo;
-
-    /** The link status (i.e. RRC state). */
-    private @LinkStatus int mLinkStatus = DataCallResponse.LINK_STATUS_UNKNOWN;
-
-    /** The network bandwidth. */
-    private @NonNull NetworkBandwidth mNetworkBandwidth = new NetworkBandwidth(14, 14);
-
-    /** The TCP buffer sizes config. */
-    private @NonNull String mTcpBufferSizes;
-
-    /** The telephony display info. */
-    private @NonNull TelephonyDisplayInfo mTelephonyDisplayInfo;
-
-    /** Whether {@link NetworkCapabilities#NET_CAPABILITY_TEMPORARILY_NOT_METERED} is supported. */
-    private boolean mTempNotMeteredSupported = false;
-
-    /** Whether the current data network is temporarily not metered. */
-    private boolean mTempNotMetered = false;
-
-    /** Whether the current data network is congested. */
-    private boolean mCongested = false;
-
-    /** The network requests associated with this data network */
-    private final @NonNull NetworkRequestList mAttachedNetworkRequestList =
-            new NetworkRequestList();
-
-    /**
-     * The latest data call response received from either
-     * {@link DataServiceCallback#onSetupDataCallComplete(int, DataCallResponse)} or
-     * {@link DataServiceCallback#onDataCallListChanged(List)}. The very first update must be
-     * from {@link DataServiceCallback#onSetupDataCallComplete(int, DataCallResponse)}.
-     */
-    private @Nullable DataCallResponse mDataCallResponse = null;
-
-    /**
-     * The fail cause from either setup data failure or unsolicited disconnect reported by data
-     * service.
-     */
-    private @DataFailureCause int mFailCause = DataFailCause.NONE;
-
-    /**
-     * The retry delay in milliseconds from setup data failure.
-     */
-    private long mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED;
-
-    /**
-     * Indicates if data network is suspended. Note this is slightly different from the
-     * {@link TelephonyManager#DATA_SUSPENDED}, which is only possible when data network is in
-     * connected state. This flag reflects to the
-     * {@link NetworkCapabilities#NET_CAPABILITY_NOT_SUSPENDED} which can happen when data network
-     * is in connected or disconnecting state.
-     */
-    private boolean mSuspended = false;
-
-    /**
-     * The current transport of the data network. For handover, the current transport will be set
-     * after handover completes.
-     */
-    private @TransportType int mTransport;
-
-    /** The reason that why setting up this data network is allowed. */
-    private @NonNull DataAllowedReason mDataAllowedReason;
-
-    /**
-     * PCO (Protocol Configuration Options) data received from the network. Key is the PCO id, value
-     * is the PCO content.
-     */
-    private final @NonNull Map<Integer, PcoData> mPcoData = new ArrayMap<>();
-
-    /** The QOS bearer sessions. */
-    private final @NonNull List<QosBearerSession> mQosBearerSessions = new ArrayList<>();
-
-    /**
-     * The UIDs of packages that have carrier privilege.
-     */
-    private @NonNull int[] mAdministratorUids = new int[0];
-
-    /**
-     * Carrier service package uid. This UID will not change through the life cycle of data network.
-     */
-    private int mCarrierServicePackageUid = Process.INVALID_UID;
-
-    /**
-     * Link bandwidth estimator callback for receiving latest link bandwidth information.
-     */
-    private @Nullable LinkBandwidthEstimatorCallback mLinkBandwidthEstimatorCallback;
-
-    /**
-     * The network bandwidth.
-     */
-    public static class NetworkBandwidth {
-        /** The downlink bandwidth in Kbps. */
-        public final int downlinkBandwidthKbps;
-
-        /** The uplink Bandwidth in Kbps. */
-        public final int uplinkBandwidthKbps;
-
-        /**
-         * Constructor.
-         *
-         * @param downlinkBandwidthKbps The downlink bandwidth in Kbps.
-         * @param uplinkBandwidthKbps The uplink Bandwidth in Kbps.
-         */
-        public NetworkBandwidth(int downlinkBandwidthKbps, int uplinkBandwidthKbps) {
-            this.downlinkBandwidthKbps = downlinkBandwidthKbps;
-            this.uplinkBandwidthKbps = uplinkBandwidthKbps;
-        }
-
-        @Override
-        public String toString() {
-            return String.format("NetworkBandwidth=[downlink=%d, uplink=%d]",
-                    downlinkBandwidthKbps, uplinkBandwidthKbps);
-        }
-    }
-
-    /**
-     * Data network callback. Should only be used by {@link DataNetworkController}.
-     */
-    public abstract static class DataNetworkCallback extends DataCallback {
-        /**
-         * Constructor
-         *
-         * @param executor The executor of the callback.
-         */
-        public DataNetworkCallback(@NonNull @CallbackExecutor Executor executor) {
-            super(executor);
-        }
-
-        /**
-         * Called when data setup failed.
-         *
-         * @param dataNetwork The data network.
-         * @param requestList The network requests attached to this data network.
-         * @param cause The fail cause of setup data network.
-         * @param retryDurationMillis The network suggested data retry duration in milliseconds as
-         * specified in 3GPP TS 24.302 section 8.2.9.1. The {@link DataProfile} associated to this
-         * data network will be throttled for the specified duration unless
-         * {@link DataServiceCallback#onApnUnthrottled} is called. {@link Long#MAX_VALUE} indicates
-         * data retry should not occur. {@link DataCallResponse#RETRY_DURATION_UNDEFINED} indicates
-         * network did not suggest any retry duration.
-         */
-        public abstract void onSetupDataFailed(@NonNull DataNetwork dataNetwork,
-                @NonNull NetworkRequestList requestList, @DataFailureCause int cause,
-                long retryDurationMillis);
-
-        /**
-         * Called when data network enters {@link ConnectedState}.
-         *
-         * @param dataNetwork The data network.
-         */
-        public abstract void onConnected(@NonNull DataNetwork dataNetwork);
-
-        /**
-         * Called when data network validation status changed.
-         *
-         * @param dataNetwork The data network.
-         * @param status one of {@link NetworkAgent#VALIDATION_STATUS_VALID} or
-         * {@link NetworkAgent#VALIDATION_STATUS_NOT_VALID}.
-         * @param redirectUri 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 abstract void onValidationStatusChanged(@NonNull DataNetwork dataNetwork,
-                @ValidationStatus int status, @Nullable Uri redirectUri);
-
-        /**
-         * Called when data network suspended state changed.
-         *
-         * @param dataNetwork The data network.
-         * @param suspended {@code true} if data is suspended.
-         */
-        public abstract void onSuspendedStateChanged(@NonNull DataNetwork dataNetwork,
-                boolean suspended);
-
-        /**
-         * Called when network requests were failed to attach to the data network.
-         *
-         * @param dataNetwork The data network.
-         * @param requestList The requests failed to attach.
-         */
-        public abstract void onAttachFailed(@NonNull DataNetwork dataNetwork,
-                @NonNull NetworkRequestList requestList);
-
-        /**
-         * Called when data network enters {@link DisconnectedState}. Note this is only called
-         * when the data network was previously connected. For setup data network failed,
-         * {@link #onSetupDataFailed(DataNetwork, NetworkRequestList, int, long)} is called.
-         *
-         * @param dataNetwork The data network.
-         * @param cause The disconnect cause.
-         */
-        public abstract void onDisconnected(@NonNull DataNetwork dataNetwork,
-                @DataFailureCause int cause);
-
-        /**
-         * Called when handover between IWLAN and cellular network succeeded.
-         *
-         * @param dataNetwork The data network.
-         */
-        public abstract void onHandoverSucceeded(@NonNull DataNetwork dataNetwork);
-
-        /**
-         * Called when data network handover between IWLAN and cellular network failed.
-         *
-         * @param dataNetwork The data network.
-         * @param cause The fail cause.
-         * @param retryDurationMillis Network suggested retry time in milliseconds.
-         * {@link Long#MAX_VALUE} indicates data retry should not occur.
-         * {@link DataCallResponse#RETRY_DURATION_UNDEFINED} indicates network did not suggest any
-         * retry duration.
-         * @param handoverFailureMode The handover failure mode that determine the behavior of
-         * how frameworks should handle the handover failure.
-         */
-        public abstract void onHandoverFailed(@NonNull DataNetwork dataNetwork,
-                @DataFailureCause int cause, long retryDurationMillis,
-                @HandoverFailureMode int handoverFailureMode);
-
-        /**
-         * Called when data network link status (i.e. RRC state) changed.
-         *
-         * @param dataNetwork The data network.
-         * @param linkStatus The link status (i.e. RRC state).
-         */
-        public abstract void onLinkStatusChanged(@NonNull DataNetwork dataNetwork,
-                @LinkStatus int linkStatus);
-
-        /**
-         * Called when PCO data changed.
-         *
-         * @param dataNetwork The data network.
-         */
-        public abstract void onPcoDataChanged(@NonNull DataNetwork dataNetwork);
-
-        /**
-         * Called when network capabilities changed.
-         *
-         * @param dataNetwork The data network.
-         */
-        public abstract void onNetworkCapabilitiesChanged(@NonNull DataNetwork dataNetwork);
-
-        /**
-         * Called when attempt to tear down a data network
-         *
-         * @param dataNetwork The data network.
-         */
-        public abstract void onTrackNetworkUnwanted(@NonNull DataNetwork dataNetwork);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param phone The phone instance.
-     * @param looper The looper to be used by the state machine. Currently the handler thread is the
-     * phone process's main thread.
-     * @param dataServiceManagers Data service managers.
-     * @param dataProfile The data profile for establishing the data network.
-     * @param networkRequestList The initial network requests attached to this data network.
-     * @param transport The initial transport of the data network.
-     * @param dataAllowedReason The reason that why setting up this data network is allowed.
-     * @param callback The callback to receives data network state update.
-     */
-    public DataNetwork(@NonNull Phone phone, @NonNull Looper looper,
-            @NonNull SparseArray<DataServiceManager> dataServiceManagers,
-            @NonNull DataProfile dataProfile,
-            @NonNull NetworkRequestList networkRequestList,
-            @TransportType int transport,
-            @NonNull DataAllowedReason dataAllowedReason,
-            @NonNull DataNetworkCallback callback) {
-        super("DataNetwork", looper);
-        // State machine should be initialized at the top of constructor. log() can be only used
-        // after state machine initialized (because getCurrentState() crashes if state machine has
-        // not started.)
-        initializeStateMachine();
-
-        mPhone = phone;
-        mSubId = phone.getSubId();
-        mRil = mPhone.mCi;
-        mLinkProperties = new LinkProperties();
-        mDataServiceManagers = dataServiceManagers;
-        mAccessNetworksManager = phone.getAccessNetworksManager();
-        mVcnManager = mPhone.getContext().getSystemService(VcnManager.class);
-        mDataNetworkController = phone.getDataNetworkController();
-        mDataNetworkController.registerDataNetworkControllerCallback(
-                new DataNetworkController.DataNetworkControllerCallback(getHandler()::post) {
-                    @Override
-                    public void onSubscriptionPlanOverride() {
-                        sendMessage(EVENT_SUBSCRIPTION_PLAN_OVERRIDE);
-                    }});
-        mDataConfigManager = mDataNetworkController.getDataConfigManager();
-        mDataCallSessionStats = new DataCallSessionStats(mPhone);
-        mDataNetworkCallback = callback;
-        mDataProfile = dataProfile;
-        if (dataProfile.getTrafficDescriptor() != null) {
-            // The initial traffic descriptor is from the data profile. After that traffic
-            // descriptors will be updated by modem through setup data call response and data call
-            // list changed event.
-            mTrafficDescriptors.add(dataProfile.getTrafficDescriptor());
-        }
-        mTransport = transport;
-        mDataAllowedReason = dataAllowedReason;
-        dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
-        mAttachedNetworkRequestList.addAll(networkRequestList);
-        mCid.put(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, INVALID_CID);
-        mCid.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, INVALID_CID);
-        mTcpBufferSizes = mDataConfigManager.getDefaultTcpConfigString();
-        mTelephonyDisplayInfo = mPhone.getDisplayInfoController().getTelephonyDisplayInfo();
-
-        for (TelephonyNetworkRequest networkRequest : networkRequestList) {
-            networkRequest.setAttachedNetwork(DataNetwork.this);
-            networkRequest.setState(TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
-        }
-
-        // Update the capabilities in the constructor is to make sure the data network has initial
-        // capability immediately after created. Doing this connecting state creates the window that
-        // DataNetworkController might check if existing data network's capability can satisfy the
-        // next network request within this window.
-        updateNetworkCapabilities();
-    }
-
-    /**
-     * Initialize and start the state machine.
-     */
-    private void initializeStateMachine() {
-        addState(mDefaultState);
-        addState(mConnectingState, mDefaultState);
-        addState(mConnectedState, mDefaultState);
-        addState(mHandoverState, mDefaultState);
-        addState(mDisconnectingState, mDefaultState);
-        addState(mDisconnectedState, mDefaultState);
-        setInitialState(mConnectingState);
-        start();
-    }
-
-    /**
-     * @return {@code true} if 464xlat should be skipped.
-     */
-    private boolean shouldSkip464Xlat() {
-        if (mDataProfile.getApnSetting() != null) {
-            switch (mDataProfile.getApnSetting().getSkip464Xlat()) {
-                case Telephony.Carriers.SKIP_464XLAT_ENABLE:
-                    return true;
-                case Telephony.Carriers.SKIP_464XLAT_DISABLE:
-                    return false;
-                case Telephony.Carriers.SKIP_464XLAT_DEFAULT:
-                default:
-                    break;
-            }
-        }
-
-        // As default, return true if ims and no internet
-        final NetworkCapabilities nc = getNetworkCapabilities();
-        return nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                && !nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-    }
-
-    /**
-     * Create the telephony network agent.
-     *
-     * @return The telephony network agent.
-     */
-    private @NonNull TelephonyNetworkAgent createNetworkAgent() {
-        final NetworkAgentConfig.Builder configBuilder = new NetworkAgentConfig.Builder();
-        configBuilder.setLegacyType(ConnectivityManager.TYPE_MOBILE);
-        configBuilder.setLegacyTypeName("MOBILE");
-        int networkType = getDataNetworkType();
-        configBuilder.setLegacySubType(networkType);
-        configBuilder.setLegacySubTypeName(TelephonyManager.getNetworkTypeName(networkType));
-        if (mDataProfile.getApnSetting() != null) {
-            configBuilder.setLegacyExtraInfo(mDataProfile.getApnSetting().getApnName());
-        }
-
-        final CarrierSignalAgent carrierSignalAgent = mPhone.getCarrierSignalAgent();
-        if (carrierSignalAgent.hasRegisteredReceivers(TelephonyManager
-                .ACTION_CARRIER_SIGNAL_REDIRECTED)) {
-            // carrierSignal Receivers will place the carrier-specific provisioning notification
-            configBuilder.setProvisioningNotificationEnabled(false);
-        }
-
-        // Fill the IMSI
-        final String subscriberId = mPhone.getSubscriberId();
-        if (!TextUtils.isEmpty(subscriberId)) {
-            configBuilder.setSubscriberId(subscriberId);
-        }
-
-        // set skip464xlat if it is not default otherwise
-        if (shouldSkip464Xlat()) {
-            configBuilder.setNat64DetectionEnabled(false);
-        }
-
-        final NetworkFactory factory = PhoneFactory.getNetworkFactory(
-                mPhone.getPhoneId());
-        final NetworkProvider provider = (null == factory) ? null : factory.getProvider();
-
-        mNetworkScore = getNetworkScore();
-        return new TelephonyNetworkAgent(mPhone, getHandler().getLooper(), this,
-                new NetworkScore.Builder().setLegacyInt(mNetworkScore).build(),
-                configBuilder.build(), provider,
-                new TelephonyNetworkAgentCallback(getHandler()::post) {
-                    @Override
-                    public void onValidationStatus(@ValidationStatus int status,
-                            @Nullable Uri redirectUri) {
-                        mDataNetworkCallback.invokeFromExecutor(
-                                () -> mDataNetworkCallback.onValidationStatusChanged(
-                                        DataNetwork.this, status, redirectUri));
-                    }
-                });
-    }
-
-    /**
-     * The default state. Any events that were not handled by the child states fallback to this
-     * state.
-     *
-     * @see DataNetwork for the state machine diagram.
-     */
-    private final class DefaultState extends State {
-        @Override
-        public void enter() {
-            logv("Registering all events.");
-            mDataConfigManager.registerForConfigUpdate(getHandler(), EVENT_DATA_CONFIG_UPDATED);
-            mPhone.getDisplayInfoController().registerForTelephonyDisplayInfoChanged(
-                    getHandler(), EVENT_DISPLAY_INFO_CHANGED, null);
-            mPhone.getServiceStateTracker().registerForServiceStateChanged(getHandler(),
-                    EVENT_SERVICE_STATE_CHANGED);
-            for (int transport : mAccessNetworksManager.getAvailableTransports()) {
-                mDataServiceManagers.get(transport)
-                        .registerForDataCallListChanged(getHandler(), EVENT_DATA_STATE_CHANGED);
-            }
-            mPhone.getCarrierPrivilegesTracker().registerCarrierPrivilegesListener(getHandler(),
-                    EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED, null);
-
-            mPhone.getServiceStateTracker().registerForCssIndicatorChanged(
-                    getHandler(), EVENT_CSS_INDICATOR_CHANGED, null);
-            mPhone.getCallTracker().registerForVoiceCallStarted(
-                    getHandler(), EVENT_VOICE_CALL_STARTED, null);
-            mPhone.getCallTracker().registerForVoiceCallEnded(
-                    getHandler(), EVENT_VOICE_CALL_ENDED, null);
-            // Check null for devices not supporting FEATURE_TELEPHONY_IMS.
-            if (mPhone.getImsPhone() != null) {
-                mPhone.getImsPhone().getCallTracker().registerForVoiceCallStarted(
-                        getHandler(), EVENT_VOICE_CALL_STARTED, null);
-                mPhone.getImsPhone().getCallTracker().registerForVoiceCallEnded(
-                        getHandler(), EVENT_VOICE_CALL_ENDED, null);
-            }
-
-            // Only add symmetric code here, for example, registering and unregistering.
-            // DefaultState.enter() is the starting point in the life cycle of the DataNetwork,
-            // and DefaultState.exit() is the end. For non-symmetric initializing works, put them
-            // in ConnectingState.enter().
-        }
-
-        @Override
-        public void exit() {
-            logv("Unregistering all events.");
-            // Check null for devices not supporting FEATURE_TELEPHONY_IMS.
-            if (mPhone.getImsPhone() != null) {
-                mPhone.getImsPhone().getCallTracker().unregisterForVoiceCallStarted(getHandler());
-                mPhone.getImsPhone().getCallTracker().unregisterForVoiceCallEnded(getHandler());
-            }
-            mPhone.getCallTracker().unregisterForVoiceCallStarted(getHandler());
-            mPhone.getCallTracker().unregisterForVoiceCallEnded(getHandler());
-
-            mPhone.getServiceStateTracker().unregisterForCssIndicatorChanged(getHandler());
-            mPhone.getCarrierPrivilegesTracker().unregisterCarrierPrivilegesListener(getHandler());
-            for (int transport : mAccessNetworksManager.getAvailableTransports()) {
-                mDataServiceManagers.get(transport)
-                        .unregisterForDataCallListChanged(getHandler());
-            }
-            mPhone.getServiceStateTracker().unregisterForServiceStateChanged(getHandler());
-            mPhone.getDisplayInfoController().unregisterForTelephonyDisplayInfoChanged(
-                    getHandler());
-            mDataConfigManager.unregisterForConfigUpdate(getHandler());
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            switch (msg.what) {
-                case EVENT_DATA_CONFIG_UPDATED:
-                    onDataConfigUpdated();
-                    break;
-                case EVENT_SERVICE_STATE_CHANGED: {
-                    mDataCallSessionStats.onDrsOrRatChanged(getDataNetworkType());
-                    updateSuspendState();
-                    updateNetworkCapabilities();
-                    break;
-                }
-                case EVENT_ATTACH_NETWORK_REQUEST: {
-                    onAttachNetworkRequests((NetworkRequestList) msg.obj);
-                    updateNetworkScore();
-                    break;
-                }
-                case EVENT_DETACH_NETWORK_REQUEST: {
-                    onDetachNetworkRequest((TelephonyNetworkRequest) msg.obj);
-                    updateNetworkScore();
-                    break;
-                }
-                case EVENT_DETACH_ALL_NETWORK_REQUESTS: {
-                    for (TelephonyNetworkRequest networkRequest : mAttachedNetworkRequestList) {
-                        networkRequest.setState(TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED);
-                        networkRequest.setAttachedNetwork(null);
-                    }
-                    log("All network requests detached.");
-                    mAttachedNetworkRequestList.clear();
-                    break;
-                }
-                case EVENT_DATA_STATE_CHANGED: {
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    int transport = (int) ar.userObj;
-                    onDataStateChanged(transport, (List<DataCallResponse>) ar.result);
-                    break;
-                }
-                case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED: {
-                    AsyncResult asyncResult = (AsyncResult) msg.obj;
-                    int[] administratorUids = (int[]) asyncResult.result;
-                    mAdministratorUids = Arrays.copyOf(administratorUids, administratorUids.length);
-                    updateNetworkCapabilities();
-                    break;
-                }
-                case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED:
-                case EVENT_TEAR_DOWN_NETWORK:
-                case EVENT_PCO_DATA_RECEIVED:
-                case EVENT_STUCK_IN_TRANSIENT_STATE:
-                case EVENT_DISPLAY_INFO_CHANGED:
-                case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
-                case EVENT_CSS_INDICATOR_CHANGED:
-                case EVENT_VOICE_CALL_STARTED:
-                case EVENT_VOICE_CALL_ENDED:
-                    // Ignore the events when not in the correct state.
-                    log("Ignored " + eventToString(msg.what));
-                    break;
-                case EVENT_START_HANDOVER:
-                    log("Ignore the handover to " + AccessNetworkConstants
-                            .transportTypeToString(msg.arg1) + " request.");
-                    break;
-                default:
-                    loge("Unhandled event " + eventToString(msg.what));
-                    break;
-            }
-            return HANDLED;
-        }
-    }
-
-    /**
-     * The connecting state. This is the initial state of a data network.
-     *
-     * @see DataNetwork for the state machine diagram.
-     */
-    private final class ConnectingState extends State {
-        @Override
-        public void enter() {
-            sendMessageDelayed(EVENT_STUCK_IN_TRANSIENT_STATE,
-                    mDataConfigManager.getAnomalyNetworkConnectingTimeoutMs());
-            mNetworkAgent = createNetworkAgent();
-            mInitialNetworkAgentId = mNetworkAgent.getId();
-            mLogTag = "DN-" + mInitialNetworkAgentId + "-"
-                    + ((mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) ? "C" : "I");
-
-            // Get carrier config package uid. Note that this uid will not change through the life
-            // cycle of this data network. So there is no need to listen to the change event.
-            mCarrierServicePackageUid = mPhone.getCarrierPrivilegesTracker()
-                    .getCarrierServicePackageUid();
-
-            notifyPreciseDataConnectionState();
-            if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
-                // Defer setupData until we get the PDU session ID response
-                allocatePduSessionId();
-                return;
-            }
-
-            setupData();
-        }
-
-        @Override
-        public void exit() {
-            removeMessages(EVENT_STUCK_IN_TRANSIENT_STATE);
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            logv("event=" + eventToString(msg.what));
-            switch (msg.what) {
-                case EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE:
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    if (ar.exception == null) {
-                        mPduSessionId = (int) ar.result;
-                        log("Set PDU session id to " + mPduSessionId);
-                    } else {
-                        loge("Failed to allocate PDU session id. e=" + ar.exception);
-                    }
-                    setupData();
-                    break;
-                case EVENT_SETUP_DATA_NETWORK_RESPONSE:
-                    int resultCode = msg.arg1;
-                    DataCallResponse dataCallResponse =
-                            msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE);
-                    onSetupResponse(resultCode, dataCallResponse);
-                    break;
-                case EVENT_START_HANDOVER:
-                case EVENT_TEAR_DOWN_NETWORK:
-                case EVENT_PCO_DATA_RECEIVED:
-                case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
-                    // Defer the request until connected or disconnected.
-                    log("Defer message " + eventToString(msg.what));
-                    deferMessage(msg);
-                    break;
-                case EVENT_STUCK_IN_TRANSIENT_STATE:
-                    reportAnomaly("Data network stuck in connecting state for "
-                            + TimeUnit.MILLISECONDS.toSeconds(
-                            mDataConfigManager.getAnomalyNetworkConnectingTimeoutMs())
-                            + " seconds.", "58c56403-7ea7-4e56-a0c7-e467114d09b8");
-                    // Setup data failed. Use the retry logic defined in
-                    // CarrierConfigManager.KEY_TELEPHONY_DATA_SETUP_RETRY_RULES_STRING_ARRAY.
-                    mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED;
-                    mFailCause = DataFailCause.NO_RETRY_FAILURE;
-                    transitionTo(mDisconnectedState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    /**
-     * The connected state. This is the state when data network becomes usable.
-     *
-     * @see DataNetwork for the state machine diagram.
-     */
-    private final class ConnectedState extends State {
-        @Override
-        public void enter() {
-            // Note that reaching here could mean from connecting -> connected, or from
-            // handover -> connected.
-            if (!mEverConnected) {
-                // Transited from ConnectingState
-                log("network connected.");
-                mEverConnected = true;
-                mNetworkAgent.markConnected();
-                mDataNetworkCallback.invokeFromExecutor(
-                        () -> mDataNetworkCallback.onConnected(DataNetwork.this));
-
-                mQosCallbackTracker = new QosCallbackTracker(mNetworkAgent, mPhone);
-                mQosCallbackTracker.updateSessions(mQosBearerSessions);
-                mKeepaliveTracker = new KeepaliveTracker(mPhone,
-                        getHandler().getLooper(), DataNetwork.this, mNetworkAgent);
-                if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
-                    registerForWwanEvents();
-                }
-
-                // Create the VCN policy changed listener. When the policy changed, we might need
-                // to tear down the VCN-managed network.
-                if (mVcnManager != null) {
-                    mVcnPolicyChangeListener = () -> {
-                        log("VCN policy changed.");
-                        if (mVcnManager.applyVcnNetworkPolicy(mNetworkCapabilities, mLinkProperties)
-                                .isTeardownRequested()) {
-                            tearDown(TEAR_DOWN_REASON_VCN_REQUESTED);
-                        } else {
-                            updateNetworkCapabilities();
-                        }
-                    };
-                    mVcnManager.addVcnNetworkPolicyChangeListener(
-                            getHandler()::post, mVcnPolicyChangeListener);
-                }
-            }
-
-            notifyPreciseDataConnectionState();
-            updateSuspendState();
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            logv("event=" + eventToString(msg.what));
-            switch (msg.what) {
-                case EVENT_TEAR_DOWN_NETWORK:
-                    if (mInvokedDataDeactivation) {
-                        log("Ignore tear down request because network is being torn down.");
-                        break;
-                    }
-
-                    int tearDownReason = msg.arg1;
-                    // If the tear down request is from upper layer, for example, IMS service
-                    // releases network request, we don't need to delay. The purpose of the delay
-                    // is to have IMS service have time to perform IMS de-registration, so if this
-                    // request is from IMS service itself, that means IMS service is already aware
-                    // of the tear down. So there is no need to delay in this case.
-                    if (tearDownReason != TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED
-                            && shouldDelayImsTearDown()) {
-                        logl("Delay IMS tear down until call ends. reason="
-                                + tearDownReasonToString(tearDownReason));
-                        break;
-                    }
-
-                    removeMessages(EVENT_TEAR_DOWN_NETWORK);
-                    removeDeferredMessages(EVENT_TEAR_DOWN_NETWORK);
-                    transitionTo(mDisconnectingState);
-                    onTearDown(tearDownReason);
-                    break;
-                case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED:
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    if (ar.exception != null) {
-                        log("EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED: error ignoring, e="
-                                + ar.exception);
-                        break;
-                    }
-                    onBandwidthUpdatedFromModem((List<LinkCapacityEstimate>) ar.result);
-                    break;
-                case EVENT_DISPLAY_INFO_CHANGED:
-                    onDisplayInfoChanged();
-                    break;
-                case EVENT_START_HANDOVER:
-                    onStartHandover(msg.arg1, (DataHandoverRetryEntry) msg.obj);
-                    break;
-                case EVENT_SUBSCRIPTION_PLAN_OVERRIDE:
-                    updateMeteredAndCongested();
-                    break;
-                case EVENT_PCO_DATA_RECEIVED:
-                    ar = (AsyncResult) msg.obj;
-                    onPcoDataReceived((PcoData) ar.result);
-                    break;
-                case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE:
-                    int resultCode = msg.arg1;
-                    onDeactivateResponse(resultCode);
-                    break;
-                case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
-                    transitionTo(mDisconnectingState);
-                    sendMessageDelayed(EVENT_TEAR_DOWN_NETWORK, msg.arg1, msg.arg2);
-                    break;
-                case EVENT_VOICE_CALL_STARTED:
-                case EVENT_VOICE_CALL_ENDED:
-                case EVENT_CSS_INDICATOR_CHANGED:
-                    updateSuspendState();
-                    updateNetworkCapabilities();
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    /**
-     * The handover state. This is the state when data network handover between IWLAN and cellular.
-     *
-     * @see DataNetwork for the state machine diagram.
-     */
-    private final class HandoverState extends State {
-        @Override
-        public void enter() {
-            sendMessageDelayed(EVENT_STUCK_IN_TRANSIENT_STATE,
-                    mDataConfigManager.getNetworkHandoverTimeoutMs());
-            notifyPreciseDataConnectionState();
-        }
-
-        @Override
-        public void exit() {
-            removeMessages(EVENT_STUCK_IN_TRANSIENT_STATE);
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            logv("event=" + eventToString(msg.what));
-            switch (msg.what) {
-                case EVENT_DATA_STATE_CHANGED:
-                    // The data call list changed event should be conditionally deferred.
-                    // Otherwise the deferred message might be incorrectly treated as "disconnected"
-                    // signal. So we only defer the related data call list changed event, and drop
-                    // the unrelated.
-                    if (shouldDeferDataStateChangedEvent(msg)) {
-                        log("Defer message " + eventToString(msg.what));
-                        deferMessage(msg);
-                    }
-                    break;
-                case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
-                case EVENT_DISPLAY_INFO_CHANGED:
-                case EVENT_TEAR_DOWN_NETWORK:
-                case EVENT_CSS_INDICATOR_CHANGED:
-                case EVENT_VOICE_CALL_ENDED:
-                case EVENT_VOICE_CALL_STARTED:
-                    // Defer the request until handover succeeds or fails.
-                    log("Defer message " + eventToString(msg.what));
-                    deferMessage(msg);
-                    break;
-                case EVENT_HANDOVER_RESPONSE:
-                    int resultCode = msg.arg1;
-                    DataCallResponse dataCallResponse =
-                            msg.getData().getParcelable(DataServiceManager.DATA_CALL_RESPONSE);
-                    onHandoverResponse(resultCode, dataCallResponse,
-                            (DataHandoverRetryEntry) msg.obj);
-                    break;
-                case EVENT_PCO_DATA_RECEIVED:
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    onPcoDataReceived((PcoData) ar.result);
-                    break;
-                case EVENT_STUCK_IN_TRANSIENT_STATE:
-                    reportAnomaly("Data service did not respond the handover request within "
-                            + TimeUnit.MILLISECONDS.toSeconds(
-                            mDataConfigManager.getNetworkHandoverTimeoutMs()) + " seconds.",
-                            "1afe68cb-8b41-4964-a737-4f34372429ea");
-
-                    // Handover failed. Use the retry logic defined in
-                    // CarrierConfigManager.KEY_TELEPHONY_DATA_HANDOVER_RETRY_RULES_STRING_ARRAY.
-                    long retry = DataCallResponse.RETRY_DURATION_UNDEFINED;
-                    int handoverFailureMode =
-                            DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL;
-                    mFailCause = DataFailCause.ERROR_UNSPECIFIED;
-                    mDataNetworkCallback.invokeFromExecutor(
-                            () -> mDataNetworkCallback.onHandoverFailed(DataNetwork.this,
-                                    mFailCause, retry, handoverFailureMode));
-                    // No matter handover succeeded or not, transit back to connected state.
-                    transitionTo(mConnectedState);
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-
-        /**
-         * Check if the data call list changed event should be deferred or dropped when handover
-         * is in progress.
-         *
-         * @param msg The data call list changed message.
-         *
-         * @return {@code true} if the message should be deferred.
-         */
-        private boolean shouldDeferDataStateChangedEvent(@NonNull Message msg) {
-            // The data call list changed event should be conditionally deferred.
-            // Otherwise the deferred message might be incorrectly treated as "disconnected"
-            // signal. So we only defer the related data call list changed event, and drop
-            // the unrelated.
-            AsyncResult ar = (AsyncResult) msg.obj;
-            int transport = (int) ar.userObj;
-            List<DataCallResponse> responseList = (List<DataCallResponse>) ar.result;
-            if (transport != mTransport) {
-                log("Dropped unrelated " + AccessNetworkConstants.transportTypeToString(transport)
-                        + " data call list changed event. " + responseList);
-                return false;
-            }
-
-            // Check if the data call list changed event are related to the current data network.
-            boolean related = responseList.stream().anyMatch(
-                    r -> mCid.get(mTransport) == r.getId());
-            if (related) {
-                log("Deferred the related data call list changed event." + responseList);
-            } else {
-                log("Dropped unrelated data call list changed event. " + responseList);
-            }
-            return related;
-        }
-    }
-
-    /**
-     * The disconnecting state. This is the state when data network is about to be disconnected.
-     * The network is still usable in this state, but the clients should be prepared to lose the
-     * network in any moment. This state is particular useful for IMS graceful tear down, where
-     * the network enters disconnecting state while waiting for IMS de-registration signal.
-     *
-     * @see DataNetwork for the state machine diagram.
-     */
-    private final class DisconnectingState extends State {
-        @Override
-        public void enter() {
-            sendMessageDelayed(EVENT_STUCK_IN_TRANSIENT_STATE,
-                    mDataConfigManager.getAnomalyNetworkDisconnectingTimeoutMs());
-            notifyPreciseDataConnectionState();
-        }
-
-        @Override
-        public void exit() {
-            removeMessages(EVENT_STUCK_IN_TRANSIENT_STATE);
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            logv("event=" + eventToString(msg.what));
-            switch (msg.what) {
-                case EVENT_TEAR_DOWN_NETWORK:
-                    if (mInvokedDataDeactivation) {
-                        log("Ignore tear down request because network is being torn down.");
-                        break;
-                    }
-                    removeMessages(EVENT_TEAR_DOWN_NETWORK);
-                    removeDeferredMessages(EVENT_TEAR_DOWN_NETWORK);
-                    onTearDown(msg.arg1);
-                    break;
-                case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE:
-                    int resultCode = msg.arg1;
-                    onDeactivateResponse(resultCode);
-                    break;
-                case EVENT_STUCK_IN_TRANSIENT_STATE:
-                    // After frameworks issues deactivate data call request, RIL should report
-                    // data disconnected through data call list changed event subsequently.
-                    reportAnomaly("RIL did not send data call list changed event after "
-                            + "deactivate data call request within "
-                            + TimeUnit.MILLISECONDS.toSeconds(
-                            mDataConfigManager.getAnomalyNetworkDisconnectingTimeoutMs())
-                            + " seconds.", "d0e4fa1c-c57b-4ba5-b4b6-8955487012cc");
-                    mFailCause = DataFailCause.LOST_CONNECTION;
-                    transitionTo(mDisconnectedState);
-                    break;
-                case EVENT_DISPLAY_INFO_CHANGED:
-                    onDisplayInfoChanged();
-                    break;
-                case EVENT_CSS_INDICATOR_CHANGED:
-                case EVENT_VOICE_CALL_STARTED:
-                case EVENT_VOICE_CALL_ENDED:
-                    updateSuspendState();
-                    updateNetworkCapabilities();
-                    break;
-                default:
-                    return NOT_HANDLED;
-            }
-            return HANDLED;
-        }
-    }
-
-    /**
-     * The disconnected state. This is the final state of a data network.
-     *
-     * @see DataNetwork for the state machine diagram.
-     */
-    private final class DisconnectedState extends State {
-        @Override
-        public void enter() {
-            logl("Data network disconnected. mEverConnected=" + mEverConnected);
-            // Preserve the list for onSetupDataFailed callback, because we need to pass that list
-            // back to DataNetworkController, but after EVENT_DETACH_ALL_NETWORK_REQUESTS gets
-            // processed, the network request list would become empty.
-            NetworkRequestList requestList = new NetworkRequestList(mAttachedNetworkRequestList);
-
-            // The detach all network requests must be the last message to handle.
-            sendMessage(EVENT_DETACH_ALL_NETWORK_REQUESTS);
-            // Gracefully handle all the un-processed events then quit the state machine.
-            // quit() throws a QUIT event to the end of message queue. All the events before quit()
-            // will be processed. Events after quit() will not be processed.
-            quit();
-
-            //************************************************************//
-            // DO NOT POST ANY EVENTS AFTER HERE.                         //
-            // THE STATE MACHINE WONT PROCESS EVENTS AFTER QUIT.          //
-            // ONLY CLEANUP SHOULD BE PERFORMED AFTER THIS.               //
-            //************************************************************//
-
-            if (mEverConnected) {
-                mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
-                        .onDisconnected(DataNetwork.this, mFailCause));
-                if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
-                    unregisterForWwanEvents();
-                }
-            } else {
-                mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
-                        .onSetupDataFailed(DataNetwork.this,
-                                requestList, mFailCause, mRetryDelayMillis));
-            }
-            notifyPreciseDataConnectionState();
-            mNetworkAgent.unregister();
-            mDataCallSessionStats.onDataCallDisconnected(mFailCause);
-
-            if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
-                    && mPduSessionId != DataCallResponse.PDU_SESSION_ID_NOT_SET) {
-                mRil.releasePduSessionId(null, mPduSessionId);
-            }
-
-            if (mVcnManager != null && mVcnPolicyChangeListener != null) {
-                mVcnManager.removeVcnNetworkPolicyChangeListener(mVcnPolicyChangeListener);
-            }
-        }
-
-        @Override
-        public boolean processMessage(Message msg) {
-            logv("event=" + eventToString(msg.what));
-            return NOT_HANDLED;
-        }
-    }
-
-    /**
-     * Register for events that can only happen on cellular networks.
-     */
-    private void registerForWwanEvents() {
-        registerForBandwidthUpdate();
-        mKeepaliveTracker.registerForKeepaliveStatus();
-        mRil.registerForPcoData(this.getHandler(), EVENT_PCO_DATA_RECEIVED, null);
-    }
-
-    /**
-     * Unregister for events that can only happen on cellular networks.
-     */
-    private void unregisterForWwanEvents() {
-        unregisterForBandwidthUpdate();
-        mKeepaliveTracker.unregisterForKeepaliveStatus();
-        mRil.unregisterForPcoData(this.getHandler());
-    }
-
-    @Override
-    protected void unhandledMessage(Message msg) {
-        IState state = getCurrentState();
-        loge("Unhandled message " + msg.what + " in state "
-                + (state == null ? "null" : state.getName()));
-    }
-
-    /**
-     * Attempt to attach the network request list to this data network. Whether the network can
-     * satisfy the request or not will be checked when EVENT_ATTACH_NETWORK_REQUEST is processed.
-     * If the request can't be attached, {@link DataNetworkCallback#onAttachFailed(
-     * DataNetwork, NetworkRequestList)}.
-     *
-     * @param requestList Network request list to attach.
-     * @return {@code false} if the network is already disconnected. {@code true} means the request
-     * has been scheduled to attach to the network. If attach succeeds, the network request's state
-     * will be set to {@link TelephonyNetworkRequest#REQUEST_STATE_SATISFIED}. If failed, the
-     * callback {@link DataNetworkCallback#onAttachFailed(DataNetwork, NetworkRequestList)} will
-     * be called.
-     */
-    public boolean attachNetworkRequests(@NonNull NetworkRequestList requestList) {
-        // If the network is already ended, we still attach the network request to the data network,
-        // so it can be retried later by data network controller.
-        if (getCurrentState() == null || isDisconnected()) {
-            // The state machine has already stopped. This is due to data network is disconnected.
-            return false;
-        }
-        sendMessage(obtainMessage(EVENT_ATTACH_NETWORK_REQUEST, requestList));
-        return true;
-    }
-
-    /**
-     * Called when attaching network request list to this data network.
-     *
-     * @param requestList Network request list to attach.
-     */
-    public void onAttachNetworkRequests(@NonNull NetworkRequestList requestList) {
-        NetworkRequestList failedList = new NetworkRequestList();
-        for (TelephonyNetworkRequest networkRequest : requestList) {
-            if (!mDataNetworkController.isNetworkRequestExisting(networkRequest)) {
-                failedList.add(networkRequest);
-                log("Attached failed. Network request was already removed. " + networkRequest);
-            } else if (!networkRequest.canBeSatisfiedBy(getNetworkCapabilities())) {
-                failedList.add(networkRequest);
-                log("Attached failed. Cannot satisfy the network request "
-                        + networkRequest);
-            } else {
-                mAttachedNetworkRequestList.add(networkRequest);
-                networkRequest.setAttachedNetwork(DataNetwork.this);
-                networkRequest.setState(
-                        TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
-                log("Successfully attached network request " + networkRequest);
-            }
-        }
-        if (failedList.size() > 0) {
-            mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
-                    .onAttachFailed(DataNetwork.this, failedList));
-        }
-    }
-
-    /**
-     * Called when detaching the network request from this data network.
-     *
-     * @param networkRequest Network request to detach.
-     */
-    private void onDetachNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) {
-        mAttachedNetworkRequestList.remove(networkRequest);
-        networkRequest.setState(TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED);
-        networkRequest.setAttachedNetwork(null);
-
-        if (mAttachedNetworkRequestList.isEmpty()) {
-            log("All network requests are detached.");
-
-            // If there is no network request attached, and we are not preferred data phone, then
-            // this detach is likely due to temp DDS switch. We should tear down the network when
-            // all requests are detached so the other network on preferred data sub can be
-            // established properly.
-            int preferredDataPhoneId = PhoneSwitcher.getInstance().getPreferredDataPhoneId();
-            if (preferredDataPhoneId != SubscriptionManager.INVALID_PHONE_INDEX
-                    && preferredDataPhoneId != mPhone.getPhoneId()) {
-                tearDown(TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED);
-            }
-        }
-    }
-
-    /**
-     * Detach the network request from this data network. Note that this will not tear down the
-     * network.
-     *
-     * @param networkRequest Network request to detach.
-     */
-    public void detachNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) {
-        if (getCurrentState() == null || isDisconnected()) {
-            return;
-        }
-        sendMessage(obtainMessage(EVENT_DETACH_NETWORK_REQUEST, networkRequest));
-    }
-
-    /**
-     * Register for bandwidth update.
-     */
-    private void registerForBandwidthUpdate() {
-        int bandwidthEstimateSource = mDataConfigManager.getBandwidthEstimateSource();
-        if (bandwidthEstimateSource == BANDWIDTH_SOURCE_MODEM) {
-            mPhone.mCi.registerForLceInfo(
-                    getHandler(), EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED, null);
-        } else if (bandwidthEstimateSource == BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR) {
-            if (mLinkBandwidthEstimatorCallback == null) {
-                mLinkBandwidthEstimatorCallback =
-                        new LinkBandwidthEstimatorCallback(getHandler()::post) {
-                            @Override
-                            public void onBandwidthChanged(int uplinkBandwidthKbps,
-                                    int downlinkBandwidthKbps) {
-                                if (isConnected()) {
-                                    onBandwidthUpdated(uplinkBandwidthKbps, downlinkBandwidthKbps);
-                                }
-                            }
-                        };
-                mPhone.getLinkBandwidthEstimator().registerCallback(
-                        mLinkBandwidthEstimatorCallback);
-            }
-        } else {
-            loge("Invalid bandwidth source configuration: " + bandwidthEstimateSource);
-        }
-    }
-
-    /**
-     * Unregister bandwidth update.
-     */
-    private void unregisterForBandwidthUpdate() {
-        int bandwidthEstimateSource = mDataConfigManager.getBandwidthEstimateSource();
-        if (bandwidthEstimateSource == BANDWIDTH_SOURCE_MODEM) {
-            mPhone.mCi.unregisterForLceInfo(getHandler());
-        } else if (bandwidthEstimateSource == BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR) {
-            if (mLinkBandwidthEstimatorCallback != null) {
-                mPhone.getLinkBandwidthEstimator()
-                        .unregisterCallback(mLinkBandwidthEstimatorCallback);
-                mLinkBandwidthEstimatorCallback = null;
-            }
-        } else {
-            loge("Invalid bandwidth source configuration: " + bandwidthEstimateSource);
-        }
-    }
-
-    /**
-     * Remove network requests that can't be satisfied anymore.
-     */
-    private void removeUnsatisfiedNetworkRequests() {
-        for (TelephonyNetworkRequest networkRequest : mAttachedNetworkRequestList) {
-            if (!networkRequest.canBeSatisfiedBy(mNetworkCapabilities)) {
-                log("removeUnsatisfiedNetworkRequests: " + networkRequest
-                        + " can't be satisfied anymore. Will be detached.");
-                detachNetworkRequest(networkRequest);
-            }
-        }
-    }
-
-    /**
-     * Check if the new link properties are compatible with the old link properties. For example,
-     * if IP changes, that's considered incompatible.
-     *
-     * @param oldLinkProperties Old link properties.
-     * @param newLinkProperties New Link properties.
-     *
-     * @return {@code true} if the new link properties is compatible with the old link properties.
-     */
-    private boolean isLinkPropertiesCompatible(@NonNull LinkProperties oldLinkProperties,
-            @NonNull LinkProperties newLinkProperties) {
-        if (Objects.equals(oldLinkProperties, newLinkProperties)) return true;
-
-        if (!LinkPropertiesUtils.isIdenticalAddresses(oldLinkProperties, newLinkProperties)) {
-            // If the same address type was removed and added we need to cleanup.
-            LinkPropertiesUtils.CompareOrUpdateResult<Integer, LinkAddress> result =
-                    new LinkPropertiesUtils.CompareOrUpdateResult<>(
-                            oldLinkProperties.getLinkAddresses(),
-                            newLinkProperties.getLinkAddresses(),
-                            linkAddress -> Objects.hash(linkAddress.getAddress(),
-                                    linkAddress.getPrefixLength(), linkAddress.getScope()));
-            log("isLinkPropertiesCompatible: old=" + oldLinkProperties
-                    + " new=" + newLinkProperties + " result=" + result);
-            for (LinkAddress added : result.added) {
-                for (LinkAddress removed : result.removed) {
-                    if (NetUtils.addressTypeMatches(removed.getAddress(), added.getAddress())) {
-                        return false;
-                    }
-                }
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Check if there are immutable capabilities changed. The connectivity service is not able
-     * to handle immutable capabilities changed, but in very rare scenarios, immutable capabilities
-     * need to be changed dynamically, such as in setup data call response, modem responded with the
-     * same cid. In that case, we need to merge the new capabilities into the existing data network.
-     *
-     * @param oldCapabilities The old network capabilities.
-     * @param newCapabilities The new network capabilities.
-     * @return {@code true} if there are immutable network capabilities changed.
-     */
-    private static boolean areImmutableCapabilitiesChanged(
-            @NonNull NetworkCapabilities oldCapabilities,
-            @NonNull NetworkCapabilities newCapabilities) {
-        if (oldCapabilities == null
-                || ArrayUtils.isEmpty(oldCapabilities.getCapabilities())) return false;
-
-        // Remove mutable capabilities from both old and new capabilities, the remaining
-        // capabilities would be immutable capabilities.
-        List<Integer> oldImmutableCapabilities = Arrays.stream(oldCapabilities.getCapabilities())
-                .boxed().collect(Collectors.toList());
-        oldImmutableCapabilities.removeAll(MUTABLE_CAPABILITIES);
-        List<Integer> newImmutableCapabilities = Arrays.stream(newCapabilities.getCapabilities())
-                .boxed().collect(Collectors.toList());
-        newImmutableCapabilities.removeAll(MUTABLE_CAPABILITIES);
-        return oldImmutableCapabilities.size() != newImmutableCapabilities.size()
-                || !oldImmutableCapabilities.containsAll(newImmutableCapabilities);
-    }
-
-    /**
-     * Update the network capabilities.
-     */
-    private void updateNetworkCapabilities() {
-        final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder()
-                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
-        boolean roaming = mPhone.getServiceState().getDataRoaming();
-
-        builder.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
-                .setSubscriptionId(mSubId).build());
-        builder.setSubscriptionIds(Collections.singleton(mSubId));
-
-        ApnSetting apnSetting = mDataProfile.getApnSetting();
-
-        if (apnSetting != null) {
-            apnSetting.getApnTypes().stream()
-                    .map(DataUtils::apnTypeToNetworkCapability)
-                    .filter(cap -> cap >= 0)
-                    .forEach(builder::addCapability);
-            if (apnSetting.getApnTypes().contains(ApnSetting.TYPE_ENTERPRISE)) {
-                builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-            }
-        }
-
-        // Once we set the MMTEL capability, we should never remove it because it's an immutable
-        // capability defined by connectivity service. When the device enters from VoPS to non-VoPS,
-        // we should perform grace tear down from data network controller if needed.
-        if (mNetworkCapabilities != null
-                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)) {
-            // Previous capability has MMTEL, so add it again.
-            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
-        } else {
-            // Always add MMTEL capability on IMS network unless network explicitly indicates VoPS
-            // not supported.
-            if (mDataProfile.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS)) {
-                builder.addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
-                if (mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
-                    NetworkRegistrationInfo nri = getNetworkRegistrationInfo();
-                    if (nri != null) {
-                        DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
-                        // Check if the network is non-VoPS.
-                        if (dsri != null && dsri.getVopsSupportInfo() != null
-                                && !dsri.getVopsSupportInfo().isVopsSupported()) {
-                            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
-                        }
-                        log("updateNetworkCapabilities: dsri=" + dsri);
-                    }
-                }
-            }
-        }
-
-        // Extract network capabilities from the traffic descriptor.
-        for (TrafficDescriptor trafficDescriptor : mTrafficDescriptors) {
-            try {
-                if (trafficDescriptor.getOsAppId() == null) continue;
-                OsAppId osAppId = new OsAppId(trafficDescriptor.getOsAppId());
-                if (!osAppId.getOsId().equals(OsAppId.ANDROID_OS_ID)) {
-                    loge("Received non-Android OS id " + osAppId.getOsId());
-                    continue;
-                }
-                int networkCapability = DataUtils.getNetworkCapabilityFromString(
-                        osAppId.getAppId());
-                switch (networkCapability) {
-                    case NetworkCapabilities.NET_CAPABILITY_ENTERPRISE:
-                        builder.addCapability(networkCapability);
-                        // Always add internet if TD contains enterprise.
-                        builder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-                        builder.addEnterpriseId(osAppId.getDifferentiator());
-                        break;
-                    case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY:
-                    case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH:
-                    case NetworkCapabilities.NET_CAPABILITY_CBS:
-                        builder.addCapability(networkCapability);
-                        break;
-                    default:
-                        loge("Invalid app id " + osAppId.getAppId());
-                }
-            } catch (Exception e) {
-                loge("Exception: " + e + ". Failed to create osAppId from "
-                        + new BigInteger(1, trafficDescriptor.getOsAppId()).toString(16));
-            }
-        }
-
-        if (!mCongested) {
-            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED);
-        }
-
-        if (mTempNotMeteredSupported && mTempNotMetered) {
-            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
-        }
-
-        // Always start with NOT_VCN_MANAGED, then remove if VcnManager indicates this is part of a
-        // VCN.
-        builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
-        final VcnNetworkPolicyResult vcnPolicy = getVcnPolicy(builder.build());
-        if (vcnPolicy != null && !vcnPolicy.getNetworkCapabilities()
-                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)) {
-            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
-        }
-
-        if (!roaming) {
-            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
-        }
-
-        if (!mSuspended) {
-            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
-        }
-
-        if (mCarrierServicePackageUid != Process.INVALID_UID
-                && ArrayUtils.contains(mAdministratorUids, mCarrierServicePackageUid)) {
-            builder.setOwnerUid(mCarrierServicePackageUid);
-            builder.setAllowedUids(Collections.singleton(mCarrierServicePackageUid));
-        }
-        builder.setAdministratorUids(mAdministratorUids);
-
-        Set<Integer> meteredCapabilities = mDataConfigManager
-                .getMeteredNetworkCapabilities(roaming).stream()
-                .filter(cap -> mAccessNetworksManager.getPreferredTransportByNetworkCapability(cap)
-                        == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .collect(Collectors.toSet());
-        boolean unmeteredNetwork = meteredCapabilities.stream().noneMatch(
-                Arrays.stream(builder.build().getCapabilities()).boxed()
-                        .collect(Collectors.toSet())::contains);
-
-        if (unmeteredNetwork) {
-            builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
-        }
-
-        // Always start with not-restricted, and then remove if needed.
-        builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
-
-        // When data is disabled, or data roaming is disabled and the device is roaming, we need
-        // to remove certain capabilities depending on scenarios.
-        if (!mDataNetworkController.getDataSettingsManager().isDataEnabled()
-                || (mPhone.getServiceState().getDataRoaming()
-                && !mDataNetworkController.getDataSettingsManager().isDataRoamingEnabled())) {
-            // If data is allowed because the request is a restricted network request, we need
-            // to mark the network as restricted when data is disabled or data roaming is disabled
-            // and the device is roaming. If we don't do that, non-privileged apps will be able
-            // to use this network when data is disabled.
-            if (mDataAllowedReason == DataAllowedReason.RESTRICTED_REQUEST) {
-                builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
-            } else if (mDataAllowedReason == DataAllowedReason.UNMETERED_USAGE
-                    || mDataAllowedReason == DataAllowedReason.MMS_REQUEST
-                    || mDataAllowedReason == DataAllowedReason.EMERGENCY_SUPL) {
-                // If data is allowed due to unmetered usage, or MMS always-allowed, we need to
-                // remove unrelated-but-metered capabilities.
-                for (int capability : meteredCapabilities) {
-                    // 1. If it's unmetered usage, remove all metered capabilities.
-                    // 2. If it's MMS always-allowed, then remove all metered capabilities but MMS.
-                    // 3/ If it's for emergency SUPL, then remove all metered capabilities but SUPL.
-                    if ((capability == NetworkCapabilities.NET_CAPABILITY_MMS
-                            && mDataAllowedReason == DataAllowedReason.MMS_REQUEST)
-                            || (capability == NetworkCapabilities.NET_CAPABILITY_SUPL
-                            && mDataAllowedReason == DataAllowedReason.EMERGENCY_SUPL)) {
-                        // Not removing the capability for special uses.
-                        continue;
-                    }
-                    builder.removeCapability(capability);
-                }
-            }
-        }
-
-        // If one of the capabilities are for special use, for example, IMS, CBS, then this
-        // network should be restricted, regardless data is enabled or not.
-        if (NetworkCapabilitiesUtils.inferRestrictedCapability(builder.build())
-                || (vcnPolicy != null && !vcnPolicy.getNetworkCapabilities()
-                        .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED))) {
-            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
-        }
-
-        // Set the bandwidth information.
-        builder.setLinkDownstreamBandwidthKbps(mNetworkBandwidth.downlinkBandwidthKbps);
-        builder.setLinkUpstreamBandwidthKbps(mNetworkBandwidth.uplinkBandwidthKbps);
-
-        NetworkCapabilities nc = builder.build();
-        if (mNetworkCapabilities == null || mNetworkAgent == null) {
-            // This is the first time when network capabilities is created. The agent is not created
-            // at this time. Just return here. The network capabilities will be used when network
-            // agent is created.
-            mNetworkCapabilities = nc;
-            logl("Initial capabilities " + mNetworkCapabilities);
-            return;
-        }
-
-        if (!nc.equals(mNetworkCapabilities)) {
-            // Check if we are changing the immutable capabilities. Note that we should be very
-            // careful and limit the use cases of changing immutable capabilities. Connectivity
-            // service would not close sockets for clients if a network request becomes
-            // unsatisfiable.
-            if (mEverConnected && areImmutableCapabilitiesChanged(mNetworkCapabilities, nc)
-                    && (isConnected() || isHandoverInProgress())) {
-                // Before connectivity service supports making all capabilities mutable, it is
-                // suggested to de-register and re-register the network agent if it is needed to
-                // add/remove immutable capabilities.
-                logl("updateNetworkCapabilities: Immutable capabilities changed. Re-create the "
-                        + "network agent. Attempted to change from " + mNetworkCapabilities + " to "
-                        + nc);
-                // Abandon the network agent because we are going to create a new one.
-                mNetworkAgent.abandon();
-                // Update the capabilities first so the new network agent would be created with the
-                // new capabilities.
-                mNetworkCapabilities = nc;
-                mNetworkAgent = createNetworkAgent();
-                mNetworkAgent.markConnected();
-            } else {
-                // Now we need to inform connectivity service and data network controller
-                // about the capabilities changed.
-                mNetworkCapabilities = nc;
-                log("Capabilities changed to " + mNetworkCapabilities);
-                mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities);
-            }
-
-            removeUnsatisfiedNetworkRequests();
-            mDataNetworkCallback.invokeFromExecutor(() -> mDataNetworkCallback
-                    .onNetworkCapabilitiesChanged(DataNetwork.this));
-        } else {
-            log("updateNetworkCapabilities: Capabilities not changed.");
-        }
-    }
-
-    /**
-     * @return The network capabilities of this data network.
-     */
-    public @NonNull NetworkCapabilities getNetworkCapabilities() {
-        return mNetworkCapabilities;
-    }
-
-    /**
-     * @return The link properties of this data network.
-     */
-    public @NonNull LinkProperties getLinkProperties() {
-        return mLinkProperties;
-    }
-
-    /**
-     * @return The data profile of this data network.
-     */
-    public @NonNull DataProfile getDataProfile() {
-        return mDataProfile;
-    }
-
-    /**
-     * Update data suspended state.
-     */
-    private void updateSuspendState() {
-        if (isConnecting() || isDisconnected()) {
-            // Return if not in the right state.
-            return;
-        }
-
-        boolean newSuspendedState = false;
-        // Get the uncombined service state directly.
-        NetworkRegistrationInfo nri = getNetworkRegistrationInfo();
-        if (nri == null) return;
-
-        // Never set suspended for emergency apn. Emergency data connection
-        // can work while device is not in service.
-        if (mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
-            newSuspendedState = false;
-            // If we are not in service, change to suspended.
-        } else if (nri.getRegistrationState()
-                != NetworkRegistrationInfo.REGISTRATION_STATE_HOME
-                && nri.getRegistrationState()
-                != NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING) {
-            newSuspendedState = true;
-            // Check voice/data concurrency.
-        } else if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()
-                && mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
-            newSuspendedState = mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE;
-        }
-
-        // Only notify when there is a change.
-        if (mSuspended != newSuspendedState) {
-            mSuspended = newSuspendedState;
-            logl("Network becomes " + (mSuspended ? "suspended" : "unsuspended"));
-            // To update NOT_SUSPENDED capability.
-            updateNetworkCapabilities();
-            notifyPreciseDataConnectionState();
-            mDataNetworkCallback.invokeFromExecutor(() ->
-                    mDataNetworkCallback.onSuspendedStateChanged(DataNetwork.this, mSuspended));
-        }
-    }
-
-    /**
-     * Allocate PDU session ID from the modem. This is only needed when the data network is
-     * initiated on IWLAN.
-     */
-    private void allocatePduSessionId() {
-        mRil.allocatePduSessionId(obtainMessage(EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE));
-    }
-
-    /**
-     * Setup a data network.
-     */
-    private void setupData() {
-        int dataNetworkType = getDataNetworkType();
-
-        // We need to use the actual modem roaming state instead of the framework roaming state
-        // here. This flag is only passed down to ril_service for picking the correct protocol (for
-        // old modem backward compatibility).
-        boolean isModemRoaming = mPhone.getServiceState().getDataRoamingFromRegistration();
-
-        // Set this flag to true if the user turns on data roaming. Or if we override the roaming
-        // state in framework, we should set this flag to true as well so the modem will not reject
-        // the data call setup (because the modem actually thinks the device is roaming).
-        boolean allowRoaming = mPhone.getDataRoamingEnabled()
-                || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming()
-                /*|| isUnmeteredUseOnly()*/));
-
-        TrafficDescriptor trafficDescriptor = mDataProfile.getTrafficDescriptor();
-        final boolean matchAllRuleAllowed = trafficDescriptor == null
-                || !TextUtils.isEmpty(trafficDescriptor.getDataNetworkName());
-
-        int accessNetwork = DataUtils.networkTypeToAccessNetworkType(dataNetworkType);
-
-        mDataServiceManagers.get(mTransport)
-                .setupDataCall(accessNetwork, mDataProfile, isModemRoaming, allowRoaming,
-                        DataService.REQUEST_REASON_NORMAL, null, mPduSessionId, null,
-                        trafficDescriptor, matchAllRuleAllowed,
-                        obtainMessage(EVENT_SETUP_DATA_NETWORK_RESPONSE));
-
-        int apnTypeBitmask = mDataProfile.getApnSetting() != null
-                ? mDataProfile.getApnSetting().getApnTypeBitmask() : ApnSetting.TYPE_NONE;
-        mDataCallSessionStats.onSetupDataCall(apnTypeBitmask);
-
-        logl("setupData: accessNetwork="
-                + AccessNetworkType.toString(accessNetwork) + ", " + mDataProfile
-                + ", isModemRoaming=" + isModemRoaming + ", allowRoaming=" + allowRoaming
-                + ", PDU session id=" + mPduSessionId + ", matchAllRuleAllowed="
-                + matchAllRuleAllowed);
-        TelephonyMetrics.getInstance().writeSetupDataCall(mPhone.getPhoneId(),
-                ServiceState.networkTypeToRilRadioTechnology(dataNetworkType),
-                mDataProfile.getProfileId(), mDataProfile.getApn(), mDataProfile.getProtocolType());
-    }
-
-    /**
-     * Get fail cause from {@link DataCallResponse} and the result code.
-     *
-     * @param resultCode The result code returned from
-     * {@link DataServiceCallback#onSetupDataCallComplete(int, DataCallResponse)}.
-     * @param response The data call response returned from
-     * {@link DataServiceCallback#onSetupDataCallComplete(int, DataCallResponse)}.
-     *
-     * @return The fail cause. {@link DataFailCause#NONE} if succeeds.
-     */
-    private @DataFailureCause int getFailCauseFromDataCallResponse(
-            @DataServiceCallback.ResultCode int resultCode, @Nullable DataCallResponse response) {
-        int failCause = DataFailCause.NONE;
-        switch (resultCode) {
-            case DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE:
-                failCause = DataFailCause.RADIO_NOT_AVAILABLE;
-                break;
-            case DataServiceCallback.RESULT_ERROR_BUSY:
-            case DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE:
-                failCause = DataFailCause.SERVICE_TEMPORARILY_UNAVAILABLE;
-                break;
-            case DataServiceCallback.RESULT_ERROR_INVALID_ARG:
-                failCause = DataFailCause.UNACCEPTABLE_NETWORK_PARAMETER;
-                break;
-            case DataServiceCallback.RESULT_ERROR_UNSUPPORTED:
-                failCause = DataFailCause.REQUEST_NOT_SUPPORTED;
-                break;
-            case DataServiceCallback.RESULT_SUCCESS:
-                if (response != null) {
-                    failCause = DataFailCause.getFailCause(response.getCause());
-                }
-                break;
-        }
-        return failCause;
-    }
-
-    /**
-     * Update data network based on the latest {@link DataCallResponse}.
-     *
-     * @param response The data call response from data service.
-     */
-    private void updateDataNetwork(@NonNull DataCallResponse response) {
-        mCid.put(mTransport, response.getId());
-        LinkProperties linkProperties = new LinkProperties();
-
-        // Set interface name
-        linkProperties.setInterfaceName(response.getInterfaceName());
-
-        // Set PDU session id
-        if (mPduSessionId != response.getPduSessionId()) {
-            mPduSessionId = response.getPduSessionId();
-            log("PDU session id updated to " + mPduSessionId);
-        }
-
-        // Set the link status
-        if (mLinkStatus != response.getLinkStatus()) {
-            mLinkStatus = response.getLinkStatus();
-            log("Link status updated to " + DataUtils.linkStatusToString(mLinkStatus));
-            mDataNetworkCallback.invokeFromExecutor(
-                    () -> mDataNetworkCallback.onLinkStatusChanged(DataNetwork.this, mLinkStatus));
-        }
-
-        // Set link addresses
-        if (response.getAddresses().size() > 0) {
-            for (LinkAddress la : response.getAddresses()) {
-                if (!la.getAddress().isAnyLocalAddress()) {
-                    logv("addr/pl=" + la.getAddress() + "/" + la.getPrefixLength());
-                    linkProperties.addLinkAddress(la);
-                }
-            }
-        } else {
-            loge("no address for ifname=" + response.getInterfaceName());
-        }
-
-        // Set DNS servers
-        if (response.getDnsAddresses().size() > 0) {
-            for (InetAddress dns : response.getDnsAddresses()) {
-                if (!dns.isAnyLocalAddress()) {
-                    linkProperties.addDnsServer(dns);
-                }
-            }
-        } else {
-            loge("Empty dns response");
-        }
-
-        // Set PCSCF
-        if (response.getPcscfAddresses().size() > 0) {
-            for (InetAddress pcscf : response.getPcscfAddresses()) {
-                linkProperties.addPcscfServer(pcscf);
-            }
-        }
-
-        // For backwards compatibility, use getMtu() if getMtuV4() is not available.
-        int mtuV4 = response.getMtuV4() > 0 ? response.getMtuV4() : response.getMtu();
-
-        if (mtuV4 <= 0) {
-            // Use back up value from data profile.
-            if (mDataProfile.getApnSetting() != null) {
-                mtuV4 = mDataProfile.getApnSetting().getMtuV4();
-            }
-            if (mtuV4 <= 0) {
-                mtuV4 = mDataConfigManager.getDefaultMtu();
-            }
-        }
-
-        // For backwards compatibility, use getMtu() if getMtuV6() is not available.
-        int mtuV6 = response.getMtuV6() > 0 ? response.getMtuV6() : response.getMtu();
-        if (mtuV6 <= 0) {
-            // Use back up value from data profile.
-            if (mDataProfile.getApnSetting() != null) {
-                mtuV6 = mDataProfile.getApnSetting().getMtuV6();
-            }
-            if (mtuV6 <= 0) {
-                mtuV6 = mDataConfigManager.getDefaultMtu();
-            }
-        }
-
-        // Set MTU for each route.
-        for (InetAddress gateway : response.getGatewayAddresses()) {
-            int mtu = gateway instanceof java.net.Inet6Address ? mtuV6 : mtuV4;
-            linkProperties.addRoute(new RouteInfo(null, gateway, null,
-                    RouteInfo.RTN_UNICAST, mtu));
-        }
-
-        // LinkProperties.setMtu should be deprecated. The mtu for each route has been already
-        // provided in addRoute() above. For backwards compatibility, we still need to provide
-        // a value for the legacy MTU. Use the higher value of v4 and v6 value here.
-        linkProperties.setMtu(Math.max(mtuV4, mtuV6));
-
-        if (mDataProfile.getApnSetting() != null
-                && !TextUtils.isEmpty(mDataProfile.getApnSetting().getProxyAddressAsString())) {
-            int port = mDataProfile.getApnSetting().getProxyPort();
-            if (port == -1) {
-                port = 8080;
-            }
-            ProxyInfo proxy = ProxyInfo.buildDirectProxy(
-                    mDataProfile.getApnSetting().getProxyAddressAsString(), port);
-            linkProperties.setHttpProxy(proxy);
-        }
-
-        linkProperties.setTcpBufferSizes(mTcpBufferSizes);
-
-        mNetworkSliceInfo = response.getSliceInfo();
-
-        mTrafficDescriptors.clear();
-        mTrafficDescriptors.addAll(response.getTrafficDescriptors());
-
-        mQosBearerSessions.clear();
-        mQosBearerSessions.addAll(response.getQosBearerSessions());
-        if (mQosCallbackTracker != null) {
-            mQosCallbackTracker.updateSessions(mQosBearerSessions);
-        }
-
-        if (!linkProperties.equals(mLinkProperties)) {
-            // If the new link properties is not compatible (e.g. IP changes, interface changes),
-            // then we should de-register the network agent and re-create a new one.
-            if ((isConnected() || isHandoverInProgress())
-                    && !isLinkPropertiesCompatible(linkProperties, mLinkProperties)) {
-                logl("updateDataNetwork: Incompatible link properties detected. Re-create the "
-                        + "network agent. Changed from " + mLinkProperties + " to "
-                        + linkProperties);
-
-                mLinkProperties = linkProperties;
-
-                // Abandon the network agent because we are going to create a new one.
-                mNetworkAgent.abandon();
-                // Update the link properties first so the new network agent would be created with
-                // the new link properties.
-                mLinkProperties = linkProperties;
-                mNetworkAgent = createNetworkAgent();
-                mNetworkAgent.markConnected();
-            } else {
-                mLinkProperties = linkProperties;
-                log("sendLinkProperties " + mLinkProperties);
-                mNetworkAgent.sendLinkProperties(mLinkProperties);
-            }
-        }
-
-        updateNetworkCapabilities();
-    }
-
-    /**
-     * Called when receiving setup data network response from the data service.
-     *
-     * @param resultCode The result code.
-     * @param response The response.
-     */
-    private void onSetupResponse(@DataServiceCallback.ResultCode int resultCode,
-            @Nullable DataCallResponse response) {
-        logl("onSetupResponse: resultCode=" + DataServiceCallback.resultCodeToString(resultCode)
-                + ", response=" + response);
-        mFailCause = getFailCauseFromDataCallResponse(resultCode, response);
-        validateDataCallResponse(response);
-        if (mFailCause == DataFailCause.NONE) {
-            if (mDataNetworkController.isNetworkInterfaceExisting(response.getInterfaceName())) {
-                logl("Interface " + response.getInterfaceName() + " already existing. Silently "
-                        + "tear down now.");
-                // If this is a pre-5G data setup, that means APN database has some problems. For
-                // example, different APN settings have the same APN name.
-                if (response.getTrafficDescriptors().isEmpty()) {
-                    reportAnomaly("Duplicate network interface " + response.getInterfaceName()
-                            + " detected.", "62f66e7e-8d71-45de-a57b-dc5c78223fd5");
-                }
-
-                // Do not actually invoke onTearDown, otherwise the existing data network will be
-                // torn down.
-                mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED;
-                mFailCause = DataFailCause.NO_RETRY_FAILURE;
-                transitionTo(mDisconnectedState);
-                return;
-            }
-
-            updateDataNetwork(response);
-
-            // TODO: Evaluate all network requests and see if each request still can be satisfied.
-            //  For requests that can't be satisfied anymore, we need to put them back to the
-            //  unsatisfied pool. If none of network requests can be satisfied, then there is no
-            //  need to mark network agent connected. Just silently deactivate the data network.
-            if (mAttachedNetworkRequestList.size() == 0) {
-                log("Tear down the network since there is no live network request.");
-                // Directly call onTearDown here. Calling tearDown will cause deadlock because
-                // EVENT_TEAR_DOWN_NETWORK is deferred until state machine enters connected state,
-                // which will never happen in this case.
-                onTearDown(TEAR_DOWN_REASON_NO_LIVE_REQUEST);
-                return;
-            }
-
-            if (mVcnManager != null && mVcnManager.applyVcnNetworkPolicy(mNetworkCapabilities,
-                    mLinkProperties).isTeardownRequested()) {
-                log("VCN service requested to tear down the network.");
-                // Directly call onTearDown here. Calling tearDown will cause deadlock because
-                // EVENT_TEAR_DOWN_NETWORK is deferred until state machine enters connected state,
-                // which will never happen in this case.
-                onTearDown(TEAR_DOWN_REASON_VCN_REQUESTED);
-                return;
-            }
-
-            transitionTo(mConnectedState);
-        } else {
-            // Setup data failed.
-            mRetryDelayMillis = response != null ? response.getRetryDurationMillis()
-                    : DataCallResponse.RETRY_DURATION_UNDEFINED;
-            transitionTo(mDisconnectedState);
-        }
-
-        int apnTypeBitmask = ApnSetting.TYPE_NONE;
-        int protocol = ApnSetting.PROTOCOL_UNKNOWN;
-        if (mDataProfile.getApnSetting() != null) {
-            apnTypeBitmask = mDataProfile.getApnSetting().getApnTypeBitmask();
-            protocol = mDataProfile.getApnSetting().getProtocol();
-        }
-        mDataCallSessionStats.onSetupDataCallResponse(response,
-                getDataNetworkType(),
-                apnTypeBitmask,
-                protocol,
-                mFailCause);
-    }
-
-    /**
-     * If the {@link DataCallResponse} contains invalid info, triggers an anomaly report.
-     *
-     * @param response The response to be validated
-     */
-    private void validateDataCallResponse(@Nullable DataCallResponse response) {
-        if (response == null
-                || response.getLinkStatus() == DataCallResponse.LINK_STATUS_INACTIVE) return;
-        int failCause = response.getCause();
-        if (failCause == DataFailCause.NONE) {
-            if (TextUtils.isEmpty(response.getInterfaceName())
-                    || response.getAddresses().isEmpty()
-                    // if out of range
-                    || response.getLinkStatus() < DataCallResponse.LINK_STATUS_UNKNOWN
-                    || response.getLinkStatus() > DataCallResponse.LINK_STATUS_ACTIVE
-                    || response.getProtocolType() < ApnSetting.PROTOCOL_UNKNOWN
-                    || response.getProtocolType() > ApnSetting.PROTOCOL_UNSTRUCTURED
-                    || response.getHandoverFailureMode()
-                    < DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN
-                    || response.getHandoverFailureMode()
-                    > DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL) {
-                loge("Invalid DataCallResponse:" + response);
-                reportAnomaly("Invalid DataCallResponse detected",
-                        "1f273e9d-b09c-46eb-ad1c-421d01f61164");
-            }
-        } else if (!DataFailCause.isFailCauseExisting(failCause)) { // Setup data failed.
-            loge("Invalid DataFailCause in " + response);
-            reportAnomaly("Invalid DataFailCause: (0x" + Integer.toHexString(failCause)
-                            + ")",
-                    "6b264f28-9f58-4cbd-9e0e-d7624ba30879");
-        }
-    }
-
-    /**
-     * Called when receiving deactivate data network response from the data service.
-     *
-     * @param resultCode The result code.
-     */
-    private void onDeactivateResponse(@DataServiceCallback.ResultCode int resultCode) {
-        logl("onDeactivateResponse: resultCode="
-                + DataServiceCallback.resultCodeToString(resultCode));
-        if (resultCode == DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE) {
-            log("Remove network since deactivate request returned an error.");
-            mFailCause = DataFailCause.RADIO_NOT_AVAILABLE;
-            transitionTo(mDisconnectedState);
-        } else if (mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_2_0)) {
-            log("Remove network on deactivate data response on old HAL "
-                    + mPhone.getHalVersion());
-            mFailCause = DataFailCause.LOST_CONNECTION;
-            transitionTo(mDisconnectedState);
-        }
-    }
-
-    /**
-     * Tear down the data network immediately.
-     *
-     * @param reason The reason of tearing down the network.
-     */
-    public void tearDown(@TearDownReason int reason) {
-        if (getCurrentState() == null || isDisconnected()) {
-            return;
-        }
-        sendMessage(obtainMessage(EVENT_TEAR_DOWN_NETWORK, reason));
-    }
-
-    private void onTearDown(@TearDownReason int reason) {
-        logl("onTearDown: reason=" + tearDownReasonToString(reason));
-
-        // track frequent NetworkAgent.onNetworkUnwanted() call of IMS and INTERNET
-        if (reason == TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED
-                && isConnected()
-                && (mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                || mNetworkCapabilities.hasCapability(
-                        NetworkCapabilities.NET_CAPABILITY_INTERNET))) {
-            mDataNetworkCallback.onTrackNetworkUnwanted(this);
-        }
-
-        mDataServiceManagers.get(mTransport).deactivateDataCall(mCid.get(mTransport),
-                reason == TEAR_DOWN_REASON_AIRPLANE_MODE_ON ? DataService.REQUEST_REASON_SHUTDOWN
-                        : DataService.REQUEST_REASON_NORMAL,
-                obtainMessage(EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE));
-        mDataCallSessionStats.setDeactivateDataCallReason(DataService.REQUEST_REASON_NORMAL);
-        mInvokedDataDeactivation = true;
-    }
-
-    /**
-     * @return {@code true} if this is an IMS network and tear down should be delayed until call
-     * ends on this data network.
-     */
-    public boolean shouldDelayImsTearDown() {
-        return mDataConfigManager.isImsDelayTearDownEnabled()
-                && mNetworkCapabilities != null
-                && mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)
-                && mPhone.getImsPhone() != null
-                && mPhone.getImsPhone().getCallTracker().getState()
-                != PhoneConstants.State.IDLE;
-    }
-
-    /**
-     * Tear down the data network when condition is met or timed out. Data network will enter
-     * {@link DisconnectingState} immediately and waiting for condition met. When condition is met,
-     * {@link DataNetworkController} should invoke {@link Consumer#accept(Object)} so the actual
-     * tear down work can be performed.
-     *
-     * This is primarily used for IMS graceful tear down. {@link DataNetworkController} inform
-     * {@link DataNetwork} to enter {@link DisconnectingState}. IMS service can observe this
-     * through {@link PreciseDataConnectionState#getState()} and then perform IMS de-registration
-     * work. After IMS de-registered, {@link DataNetworkController} informs {@link DataNetwork}
-     * that it's okay to tear down the network.
-     *
-     * @param reason The tear down reason.
-     *
-     * @param timeoutMillis Timeout in milliseconds. Within the time window, clients will have to
-     * call {@link Consumer#accept(Object)}, otherwise, data network will be torn down when
-     * timed out.
-     *
-     * @return The runnable for client to execute when condition is met. When executed, tear down
-     * will be performed. {@code null} if the data network is already disconnected or being
-     * disconnected.
-     */
-    public @Nullable Runnable tearDownWhenConditionMet(@TearDownReason int reason,
-            long timeoutMillis) {
-        if (getCurrentState() == null || isDisconnected() || isDisconnecting()) {
-            loge("tearDownWhenConditionMet: Not in the right state. State=" + getCurrentState());
-            return null;
-        }
-        logl("tearDownWhenConditionMet: reason=" + tearDownReasonToString(reason) + ", timeout="
-                + timeoutMillis + "ms.");
-        sendMessage(EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET, reason, (int) timeoutMillis);
-        return () -> this.tearDown(reason);
-    }
-
-    /**
-     * Called when receiving {@link DataServiceCallback#onDataCallListChanged(List)} from the data
-     * service.
-     *
-     * @param transport The transport where this event from.
-     * @param responseList The data call response list.
-     */
-    private void onDataStateChanged(@TransportType int transport,
-            @NonNull List<DataCallResponse> responseList) {
-        // Ignore the update if it's not from the data service on the right transport.
-        // Also if never received data call response from setup call response, which updates the
-        // cid, ignore the update here.
-        logv("onDataStateChanged: " + responseList);
-        if (transport != mTransport || mCid.get(mTransport) == INVALID_CID || isDisconnected()) {
-            return;
-        }
-
-        DataCallResponse response = responseList.stream()
-                .filter(r -> mCid.get(mTransport) == r.getId())
-                .findFirst()
-                .orElse(null);
-        if (response != null) {
-            if (!response.equals(mDataCallResponse)) {
-                log("onDataStateChanged: " + response);
-                validateDataCallResponse(response);
-                mDataCallResponse = response;
-                if (response.getLinkStatus() != DataCallResponse.LINK_STATUS_INACTIVE) {
-                    updateDataNetwork(response);
-                } else {
-                    log("onDataStateChanged: PDN inactive reported by "
-                            + AccessNetworkConstants.transportTypeToString(mTransport)
-                            + " data service.");
-                    mFailCause = mEverConnected ? response.getCause()
-                            : DataFailCause.NO_RETRY_FAILURE;
-                    mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED;
-                    transitionTo(mDisconnectedState);
-                }
-            }
-        } else {
-            // The data call response is missing from the list. This means the PDN is gone. This
-            // is the PDN lost reported by the modem. We don't send another DEACTIVATE_DATA request
-            // for that
-            log("onDataStateChanged: PDN disconnected reported by "
-                    + AccessNetworkConstants.transportTypeToString(mTransport) + " data service.");
-            mFailCause = mEverConnected ? DataFailCause.LOST_CONNECTION
-                    : DataFailCause.NO_RETRY_FAILURE;
-            mRetryDelayMillis = DataCallResponse.RETRY_DURATION_UNDEFINED;
-            transitionTo(mDisconnectedState);
-        }
-    }
-
-    /**
-     * Called when data config updated.
-     */
-    private void onDataConfigUpdated() {
-        log("onDataConfigUpdated");
-
-        updateBandwidthFromDataConfig();
-        updateTcpBufferSizes();
-        updateMeteredAndCongested();
-    }
-
-    /**
-     * Called when receiving bandwidth update from the modem.
-     *
-     * @param linkCapacityEstimates The link capacity estimate list from the modem.
-     */
-    private void onBandwidthUpdatedFromModem(
-            @NonNull List<LinkCapacityEstimate> linkCapacityEstimates) {
-        Objects.requireNonNull(linkCapacityEstimates);
-        if (linkCapacityEstimates.isEmpty()) return;
-
-        int uplinkBandwidthKbps = 0, downlinkBandwidthKbps = 0;
-        for (LinkCapacityEstimate linkCapacityEstimate : linkCapacityEstimates) {
-            if (linkCapacityEstimate.getType() == LinkCapacityEstimate.LCE_TYPE_COMBINED) {
-                uplinkBandwidthKbps = linkCapacityEstimate.getUplinkCapacityKbps();
-                downlinkBandwidthKbps = linkCapacityEstimate.getDownlinkCapacityKbps();
-                break;
-            } else if (linkCapacityEstimate.getType() == LinkCapacityEstimate.LCE_TYPE_PRIMARY
-                    || linkCapacityEstimate.getType() == LinkCapacityEstimate.LCE_TYPE_SECONDARY) {
-                uplinkBandwidthKbps += linkCapacityEstimate.getUplinkCapacityKbps();
-                downlinkBandwidthKbps += linkCapacityEstimate.getDownlinkCapacityKbps();
-            } else {
-                loge("Invalid LinkCapacityEstimate type " + linkCapacityEstimate.getType());
-            }
-        }
-        onBandwidthUpdated(uplinkBandwidthKbps, downlinkBandwidthKbps);
-    }
-
-    /**
-     * Called when bandwidth estimation updated from either modem or the bandwidth estimator.
-     *
-     * @param uplinkBandwidthKbps Uplink bandwidth estimate in Kbps.
-     * @param downlinkBandwidthKbps Downlink bandwidth estimate in Kbps.
-     */
-    private void onBandwidthUpdated(int uplinkBandwidthKbps, int downlinkBandwidthKbps) {
-        log("onBandwidthUpdated: downlinkBandwidthKbps=" + downlinkBandwidthKbps
-                + ", uplinkBandwidthKbps=" + uplinkBandwidthKbps);
-        NetworkBandwidth bandwidthFromConfig = mDataConfigManager.getBandwidthForNetworkType(
-                mTelephonyDisplayInfo);
-
-        if (downlinkBandwidthKbps == LinkCapacityEstimate.INVALID && bandwidthFromConfig != null) {
-            // Fallback to carrier config.
-            downlinkBandwidthKbps = bandwidthFromConfig.downlinkBandwidthKbps;
-        }
-
-        if (uplinkBandwidthKbps == LinkCapacityEstimate.INVALID && bandwidthFromConfig != null) {
-            // Fallback to carrier config.
-            uplinkBandwidthKbps = bandwidthFromConfig.uplinkBandwidthKbps;
-        }
-
-        // Make sure uplink is not greater than downlink.
-        uplinkBandwidthKbps = Math.min(uplinkBandwidthKbps, downlinkBandwidthKbps);
-        mNetworkBandwidth = new NetworkBandwidth(downlinkBandwidthKbps, uplinkBandwidthKbps);
-
-        updateNetworkCapabilities();
-    }
-
-    /**
-     * Called when {@link TelephonyDisplayInfo} changed. This can happen when network types or
-     * override network types (5G NSA, 5G MMWAVE) change.
-     */
-    private void onDisplayInfoChanged() {
-        mTelephonyDisplayInfo = mPhone.getDisplayInfoController().getTelephonyDisplayInfo();
-        updateBandwidthFromDataConfig();
-        updateTcpBufferSizes();
-        updateMeteredAndCongested();
-    }
-
-    /**
-     * Update the bandwidth from carrier config. Note this is no-op if the bandwidth source is not
-     * carrier config.
-     */
-    private void updateBandwidthFromDataConfig() {
-        if (mDataConfigManager.getBandwidthEstimateSource() != BANDWIDTH_SOURCE_CARRIER_CONFIG) {
-            return;
-        }
-        log("updateBandwidthFromDataConfig");
-        mNetworkBandwidth = mDataConfigManager.getBandwidthForNetworkType(mTelephonyDisplayInfo);
-        updateNetworkCapabilities();
-    }
-
-    /**
-     * Update the TCP buffer sizes from resource overlays.
-     */
-    private void updateTcpBufferSizes() {
-        log("updateTcpBufferSizes");
-        mTcpBufferSizes = mDataConfigManager.getTcpConfigString(mTelephonyDisplayInfo);
-        LinkProperties linkProperties = new LinkProperties(mLinkProperties);
-        linkProperties.setTcpBufferSizes(mTcpBufferSizes);
-        if (!linkProperties.equals(mLinkProperties)) {
-            mLinkProperties = linkProperties;
-            log("sendLinkProperties " + mLinkProperties);
-            mNetworkAgent.sendLinkProperties(mLinkProperties);
-        }
-    }
-
-    /**
-     * Update the metered and congested values from carrier configs and subscription overrides
-     */
-    private void updateMeteredAndCongested() {
-        int networkType = mTelephonyDisplayInfo.getNetworkType();
-        switch (mTelephonyDisplayInfo.getOverrideNetworkType()) {
-            case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED:
-            case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA:
-                networkType = TelephonyManager.NETWORK_TYPE_NR;
-                break;
-            case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO:
-            case TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA:
-                networkType = TelephonyManager.NETWORK_TYPE_LTE_CA;
-                break;
-        }
-        log("updateMeteredAndCongested: networkType="
-                + TelephonyManager.getNetworkTypeName(networkType));
-        boolean changed = false;
-        if (mDataConfigManager.isTempNotMeteredSupportedByCarrier() != mTempNotMeteredSupported) {
-            mTempNotMeteredSupported = !mTempNotMeteredSupported;
-            changed = true;
-            log("updateMeteredAndCongested: mTempNotMeteredSupported changed to "
-                    + mTempNotMeteredSupported);
-        }
-        if ((mDataNetworkController.getUnmeteredOverrideNetworkTypes().contains(networkType)
-                || isNetworkTypeUnmetered(networkType)) != mTempNotMetered) {
-            mTempNotMetered = !mTempNotMetered;
-            changed = true;
-            log("updateMeteredAndCongested: mTempNotMetered changed to " + mTempNotMetered);
-        }
-        if (mDataNetworkController.getCongestedOverrideNetworkTypes().contains(networkType)
-                != mCongested) {
-            mCongested = !mCongested;
-            changed = true;
-            log("updateMeteredAndCongested: mCongested changed to " + mCongested);
-        }
-        if (changed) {
-            updateNetworkCapabilities();
-        }
-    }
-
-    /**
-     * Get whether the network type is unmetered from SubscriptionPlans, from either an unmetered
-     * general plan or specific plan for the given network type.
-     *
-     * @param networkType The network type to check meteredness for
-     * @return Whether the given network type is unmetered based on SubscriptionPlans
-     */
-    private boolean isNetworkTypeUnmetered(@NetworkType int networkType) {
-        List<SubscriptionPlan> plans = mDataNetworkController.getSubscriptionPlans();
-        if (plans.isEmpty()) return false;
-        boolean isGeneralUnmetered = true;
-        Set<Integer> allNetworkTypes = Arrays.stream(TelephonyManager.getAllNetworkTypes())
-                .boxed().collect(Collectors.toSet());
-        for (SubscriptionPlan plan : plans) {
-            // Check if plan is general (applies to all network types) or specific
-            if (Arrays.stream(plan.getNetworkTypes()).boxed().collect(Collectors.toSet())
-                    .containsAll(allNetworkTypes)) {
-                if (plan.getDataLimitBytes() != SubscriptionPlan.BYTES_UNLIMITED) {
-                    // Metered takes precedence over unmetered for safety
-                    isGeneralUnmetered = false;
-                }
-            } else {
-                // Check if plan applies to given network type
-                if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
-                    for (int planNetworkType : plan.getNetworkTypes()) {
-                        if (planNetworkType == networkType) {
-                            return plan.getDataLimitBytes() == SubscriptionPlan.BYTES_UNLIMITED;
-                        }
-                    }
-                }
-            }
-        }
-        return isGeneralUnmetered;
-    }
-
-    /**
-     * @return The unique context id assigned by the data service in
-     * {@link DataCallResponse#getId()}.
-     */
-    public int getId() {
-        return mCid.get(mTransport);
-    }
-
-    /**
-     * @return The current network type reported by the network service.
-     */
-    private @NetworkType int getDataNetworkType() {
-        return getDataNetworkType(mTransport);
-    }
-
-    /**
-     * Get the data network type on the specified transport.
-     *
-     * @param transport The transport.
-     * @return The data network type.
-     */
-    private @NetworkType int getDataNetworkType(@TransportType int transport) {
-        // WLAN transport can't have network type other than IWLAN. Ideally service state tracker
-        // should report the correct RAT, but sometimes race condition could happen that service
-        // state is reset to out of service and RAT not updated to IWLAN yet.
-        if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
-            return TelephonyManager.NETWORK_TYPE_IWLAN;
-        }
-
-        ServiceState ss = mPhone.getServiceState();
-        NetworkRegistrationInfo nrs = ss.getNetworkRegistrationInfo(
-                NetworkRegistrationInfo.DOMAIN_PS, transport);
-        if (nrs != null) {
-            return nrs.getAccessNetworkTechnology();
-        }
-        return TelephonyManager.NETWORK_TYPE_UNKNOWN;
-    }
-
-    /**
-     * @return The physical link status (i.e. RRC state).
-     */
-    public @LinkStatus int getLinkStatus() {
-        return mLinkStatus;
-    }
-
-    /**
-     * Update the network score and report to connectivity service if necessary.
-     */
-    private void updateNetworkScore() {
-        int networkScore = getNetworkScore();
-        if (networkScore != mNetworkScore) {
-            logl("Updating score from " + mNetworkScore + " to " + networkScore);
-            mNetworkScore = networkScore;
-            mNetworkAgent.sendNetworkScore(mNetworkScore);
-        }
-    }
-
-    /**
-     * @return The network score. The higher score of the network has higher chance to be
-     * selected by the connectivity service as active network.
-     */
-    private int getNetworkScore() {
-        // If it's serving a network request that asks NET_CAPABILITY_INTERNET and doesn't have
-        // specify a sub id, this data network is considered to be default internet data
-        // connection. In this case we assign a slightly higher score of 50. The intention is
-        // it will not be replaced by other data networks accidentally in DSDS use case.
-        int score = OTHER_NETWORK_SCORE;
-        for (TelephonyNetworkRequest networkRequest : mAttachedNetworkRequestList) {
-            if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                    && networkRequest.getNetworkSpecifier() == null) {
-                score = DEFAULT_INTERNET_NETWORK_SCORE;
-            }
-        }
-
-        return score;
-    }
-
-    /**
-     * @return Network registration info on the current transport.
-     */
-    private @Nullable NetworkRegistrationInfo getNetworkRegistrationInfo() {
-        NetworkRegistrationInfo nri = mPhone.getServiceStateTracker().getServiceState()
-                .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS, mTransport);
-        if (nri == null) {
-            loge("Can't get network registration info for "
-                    + AccessNetworkConstants.transportTypeToString(mTransport));
-            return null;
-        }
-        return nri;
-    }
-
-    /**
-     * Get the APN type network capability. If there are more than one capabilities that are
-     * APN types, then return the highest priority one which also has associated network request.
-     * For example, if the network supports both MMS and internet, but only internet request
-     * attached at this time, then the capability would be internet. Later on if MMS network request
-     * attached to this network, then the APN type capability would be MMS.
-     *
-     * @return The APN type network capability from this network.
-     *
-     * @see #getPriority()
-     */
-    public @NetCapability int getApnTypeNetworkCapability() {
-        if (!mAttachedNetworkRequestList.isEmpty()) {
-            // The highest priority network request is always at the top of list.
-            return mAttachedNetworkRequestList.get(0).getApnTypeNetworkCapability();
-        } else {
-            return Arrays.stream(getNetworkCapabilities().getCapabilities()).boxed()
-                    .filter(cap -> DataUtils.networkCapabilityToApnType(cap)
-                            != ApnSetting.TYPE_NONE)
-                    .max(Comparator.comparingInt(mDataConfigManager::getNetworkCapabilityPriority))
-                    .orElse(-1);
-        }
-    }
-
-    /**
-     * Get the priority of the network. The priority is derived from the highest priority capability
-     * which also has such associated network request. For example, if the network supports both
-     * MMS and internet, but only has internet request attached, then this network has internet's
-     * priority. Later on when the MMS request attached to this network, the network's priority will
-     * be updated to MMS's priority.
-     *
-     * @return The priority of the network.
-     *
-     * @see #getApnTypeNetworkCapability()
-     */
-    public int getPriority() {
-        if (!mAttachedNetworkRequestList.isEmpty()) {
-            // The highest priority network request is always at the top of list.
-            return mAttachedNetworkRequestList.get(0).getPriority();
-        } else {
-            // If all network requests are already detached, then just pick the highest priority
-            // capability's priority.
-            return Arrays.stream(getNetworkCapabilities().getCapabilities()).boxed()
-                    .map(mDataConfigManager::getNetworkCapabilityPriority)
-                    .max(Integer::compare)
-                    .orElse(0);
-        }
-    }
-
-    /**
-     * @return The attached network request list.
-     */
-    public @NonNull NetworkRequestList getAttachedNetworkRequestList() {
-        return mAttachedNetworkRequestList;
-    }
-
-    /**
-     * @return {@code true} if in connecting state.
-     */
-    public boolean isConnecting() {
-        return getCurrentState() == mConnectingState;
-    }
-
-    /**
-     * @return {@code true} if in connected state.
-     */
-    public boolean isConnected() {
-        return getCurrentState() == mConnectedState;
-    }
-
-    /**
-     * @return {@code true} if in disconnecting state.
-     */
-    public boolean isDisconnecting() {
-        return getCurrentState() == mDisconnectingState;
-    }
-
-    /**
-     * @return {@code true} if in disconnected state.
-     */
-    public boolean isDisconnected() {
-        return getCurrentState() == mDisconnectedState;
-    }
-
-    /**
-     * @return {@code true} if in handover state.
-     */
-    public boolean isHandoverInProgress() {
-        return getCurrentState() == mHandoverState;
-    }
-
-    /**
-     * @return {@code true} if the data network is suspended.
-     */
-    public boolean isSuspended() {
-        return getState() == TelephonyManager.DATA_SUSPENDED;
-    }
-
-    /**
-     * @return The current transport of the data network.
-     */
-    public @TransportType int getTransport() {
-        return mTransport;
-    }
-
-    private @DataState int getState() {
-        IState state = getCurrentState();
-        if (state == null || isDisconnected()) {
-            return TelephonyManager.DATA_DISCONNECTED;
-        } else if (isConnecting()) {
-            return TelephonyManager.DATA_CONNECTING;
-        } else if (isConnected()) {
-            // The data connection can only be suspended when it's in active state.
-            if (mSuspended) {
-                return TelephonyManager.DATA_SUSPENDED;
-            }
-            return TelephonyManager.DATA_CONNECTED;
-        } else if (isDisconnecting()) {
-            return TelephonyManager.DATA_DISCONNECTING;
-        } else if (isHandoverInProgress()) {
-            return TelephonyManager.DATA_HANDOVER_IN_PROGRESS;
-        }
-
-        return TelephonyManager.DATA_UNKNOWN;
-    }
-
-    /**
-     * @return {@code true} if this data network supports internet.
-     */
-    public boolean isInternetSupported() {
-        return mNetworkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                && mNetworkCapabilities.hasCapability(
-                        NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                && mNetworkCapabilities.hasCapability(
-                        NetworkCapabilities.NET_CAPABILITY_TRUSTED)
-                && mNetworkCapabilities.hasCapability(
-                        NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                && mNetworkCapabilities.hasCapability(
-                        NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
-    }
-
-    /**
-     * @return {@code true} if this network was setup for SUPL during emergency call. {@code false}
-     * otherwise.
-     */
-    public boolean isEmergencySupl() {
-        return mDataAllowedReason == DataAllowedReason.EMERGENCY_SUPL;
-    }
-
-    /**
-     * Get precise data connection state
-     *
-     * @return The {@link PreciseDataConnectionState}
-     */
-    private PreciseDataConnectionState getPreciseDataConnectionState() {
-        return new PreciseDataConnectionState.Builder()
-                .setTransportType(mTransport)
-                .setId(mCid.get(mTransport))
-                .setState(getState())
-                .setApnSetting(mDataProfile.getApnSetting())
-                .setLinkProperties(mLinkProperties)
-                .setNetworkType(getDataNetworkType())
-                .setFailCause(mFailCause)
-                .build();
-    }
-
-    /**
-     * Send the precise data connection state to the listener of
-     * {@link android.telephony.TelephonyCallback.PreciseDataConnectionStateListener}.
-     */
-    private void notifyPreciseDataConnectionState() {
-        PreciseDataConnectionState pdcs = getPreciseDataConnectionState();
-        logv("notifyPreciseDataConnectionState=" + pdcs);
-        mPhone.notifyDataConnection(pdcs);
-    }
-
-    /**
-     * Request the data network to handover to the target transport.
-     *
-     * @param targetTransport The target transport.
-     * @param retryEntry Data handover retry entry. This would be {@code null} for first time
-     * handover attempt.
-     * @return {@code true} if the request has been accepted.
-     */
-    public boolean startHandover(@TransportType int targetTransport,
-            @Nullable DataHandoverRetryEntry retryEntry) {
-        if (getCurrentState() == null || isDisconnected() || isDisconnecting()) {
-            // Fail the request if not in the appropriate state.
-            if (retryEntry != null) retryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
-            return false;
-        }
-        sendMessage(obtainMessage(EVENT_START_HANDOVER, targetTransport, 0, retryEntry));
-        return true;
-    }
-
-    /**
-     * Called when handover between IWLAN and cellular is needed.
-     *
-     * @param targetTransport The target transport.
-     * @param retryEntry Data handover retry entry. This would be {@code null} for first time
-     * handover attempt.
-     */
-    private void onStartHandover(@TransportType int targetTransport,
-            @Nullable DataHandoverRetryEntry retryEntry) {
-        if (mTransport == targetTransport) {
-            log("onStartHandover: The network is already on "
-                    + AccessNetworkConstants.transportTypeToString(mTransport)
-                    + ", handover is not needed.");
-            if (retryEntry != null) retryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
-            return;
-        }
-
-        // We need to use the actual modem roaming state instead of the framework roaming state
-        // here. This flag is only passed down to ril_service for picking the correct protocol (for
-        // old modem backward compatibility).
-        boolean isModemRoaming = mPhone.getServiceState().getDataRoamingFromRegistration();
-
-        // Set this flag to true if the user turns on data roaming. Or if we override the roaming
-        // state in framework, we should set this flag to true as well so the modem will not reject
-        // the data call setup (because the modem actually thinks the device is roaming).
-        boolean allowRoaming = mPhone.getDataRoamingEnabled()
-                || (isModemRoaming && (!mPhone.getServiceState().getDataRoaming()));
-
-        mHandoverDataProfile = mDataProfile;
-        int targetNetworkType = getDataNetworkType(targetTransport);
-        if (targetNetworkType != TelephonyManager.NETWORK_TYPE_UNKNOWN
-                && !mAttachedNetworkRequestList.isEmpty()) {
-            TelephonyNetworkRequest networkRequest = mAttachedNetworkRequestList.get(0);
-            DataProfile dataProfile = mDataNetworkController.getDataProfileManager()
-                    .getDataProfileForNetworkRequest(networkRequest, targetNetworkType);
-            // Some carriers have different profiles between cellular and IWLAN. We need to
-            // dynamically switch profile, but only when those profiles have same APN name.
-            if (dataProfile != null && dataProfile.getApnSetting() != null
-                    && mDataProfile.getApnSetting() != null
-                    && TextUtils.equals(dataProfile.getApnSetting().getApnName(),
-                    mDataProfile.getApnSetting().getApnName())
-                    && !dataProfile.equals(mDataProfile)) {
-                mHandoverDataProfile = dataProfile;
-                log("Used different data profile for handover. " + mDataProfile);
-            }
-        }
-
-        logl("Start handover from " + AccessNetworkConstants.transportTypeToString(mTransport)
-                + " to " + AccessNetworkConstants.transportTypeToString(targetTransport));
-        // Send the handover request to the target transport data service.
-        mDataServiceManagers.get(targetTransport).setupDataCall(
-                DataUtils.networkTypeToAccessNetworkType(getDataNetworkType(targetTransport)),
-                mHandoverDataProfile, isModemRoaming, allowRoaming,
-                DataService.REQUEST_REASON_HANDOVER, mLinkProperties, mPduSessionId,
-                mNetworkSliceInfo, mHandoverDataProfile.getTrafficDescriptor(), true,
-                obtainMessage(EVENT_HANDOVER_RESPONSE, retryEntry));
-        transitionTo(mHandoverState);
-    }
-
-    /**
-     * Called when receiving handover response from the data service.
-     *
-     * @param resultCode The result code.
-     * @param response The response.
-     * @param retryEntry Data handover retry entry. This would be {@code null} for first time
-     * handover attempt.
-     */
-    private void onHandoverResponse(@DataServiceCallback.ResultCode int resultCode,
-            @Nullable DataCallResponse response, @Nullable DataHandoverRetryEntry retryEntry) {
-        logl("onHandoverResponse: resultCode=" + DataServiceCallback.resultCodeToString(resultCode)
-                + ", response=" + response);
-        mFailCause = getFailCauseFromDataCallResponse(resultCode, response);
-        validateDataCallResponse(response);
-        if (mFailCause == DataFailCause.NONE) {
-            // Handover succeeded.
-
-            // Clean up on the source transport.
-            mDataServiceManagers.get(mTransport).deactivateDataCall(mCid.get(mTransport),
-                    DataService.REQUEST_REASON_HANDOVER, null);
-            // Switch the transport to the target.
-            mTransport = DataUtils.getTargetTransport(mTransport);
-            // Update the logging tag
-            mLogTag = "DN-" + mInitialNetworkAgentId + "-"
-                    + ((mTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) ? "C" : "I");
-            // Switch the data profile. This is no-op in most of the case since almost all carriers
-            // use same data profile between IWLAN and cellular.
-            mDataProfile = mHandoverDataProfile;
-            updateDataNetwork(response);
-            if (mTransport != AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
-                // Handover from WWAN to WLAN
-                mPcoData.clear();
-                unregisterForWwanEvents();
-            } else {
-                // Handover from WLAN to WWAN
-                registerForWwanEvents();
-            }
-            if (retryEntry != null) retryEntry.setState(DataRetryEntry.RETRY_STATE_SUCCEEDED);
-            mDataNetworkCallback.invokeFromExecutor(
-                    () -> mDataNetworkCallback.onHandoverSucceeded(DataNetwork.this));
-        } else {
-            // Handover failed.
-            long retry = response != null ? response.getRetryDurationMillis()
-                    : DataCallResponse.RETRY_DURATION_UNDEFINED;
-            int handoverFailureMode = response != null ? response.getHandoverFailureMode()
-                    : DataCallResponse.HANDOVER_FAILURE_MODE_LEGACY;
-            if (retryEntry != null) retryEntry.setState(DataRetryEntry.RETRY_STATE_FAILED);
-            mDataNetworkCallback.invokeFromExecutor(
-                    () -> mDataNetworkCallback.onHandoverFailed(DataNetwork.this,
-                            mFailCause, retry, handoverFailureMode));
-            mDataCallSessionStats.onHandoverFailure(mFailCause);
-        }
-
-        // No matter handover succeeded or not, transit back to connected state.
-        transitionTo(mConnectedState);
-    }
-
-    /**
-     * Called when receiving PCO (Protocol Configuration Options) data from the cellular network.
-     *
-     * @param pcoData PCO data.
-     */
-    private void onPcoDataReceived(@NonNull PcoData pcoData) {
-        if (pcoData.cid != getId()) return;
-        PcoData oldData = mPcoData.put(pcoData.pcoId, pcoData);
-        if (!Objects.equals(oldData, pcoData)) {
-            log("onPcoDataReceived: " + pcoData);
-            mDataNetworkCallback.invokeFromExecutor(
-                    () -> mDataNetworkCallback.onPcoDataChanged(DataNetwork.this));
-            if (mDataProfile.getApnSetting() != null) {
-                for (int apnType : mDataProfile.getApnSetting().getApnTypes()) {
-                    Intent intent = new Intent(TelephonyManager.ACTION_CARRIER_SIGNAL_PCO_VALUE);
-                    intent.putExtra(TelephonyManager.EXTRA_APN_TYPE, apnType);
-                    intent.putExtra(TelephonyManager.EXTRA_APN_PROTOCOL,
-                            ApnSetting.getProtocolIntFromString(pcoData.bearerProto));
-                    intent.putExtra(TelephonyManager.EXTRA_PCO_ID, pcoData.pcoId);
-                    intent.putExtra(TelephonyManager.EXTRA_PCO_VALUE, pcoData.contents);
-                    mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
-                }
-            }
-        }
-    }
-
-    /**
-     * @return The PCO data received from the network.
-     */
-    public @NonNull Map<Integer, PcoData> getPcoData() {
-        return mPcoData;
-    }
-
-    /**
-     * Check if the this data network is VCN-managed.
-     *
-     * @param networkCapabilities The network capabilities of this data network.
-     * @return The VCN's policy for this DataNetwork.
-     */
-    private VcnNetworkPolicyResult getVcnPolicy(NetworkCapabilities networkCapabilities) {
-        if (mVcnManager == null) {
-            return null;
-        }
-
-        return mVcnManager.applyVcnNetworkPolicy(networkCapabilities, getLinkProperties());
-    }
-
-    /**
-     * Convert the data tear down reason to string.
-     *
-     * @param reason Data deactivation reason.
-     * @return The deactivation reason in string format.
-     */
-    public static @NonNull String tearDownReasonToString(@TearDownReason int reason) {
-        switch (reason) {
-            case TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED:
-                return "CONNECTIVITY_SERVICE_UNWANTED";
-            case TEAR_DOWN_REASON_SIM_REMOVAL:
-                return "SIM_REMOVAL";
-            case TEAR_DOWN_REASON_AIRPLANE_MODE_ON:
-                return "AIRPLANE_MODE_ON";
-            case TEAR_DOWN_REASON_DATA_DISABLED:
-                return "DATA_DISABLED";
-            case TEAR_DOWN_REASON_NO_LIVE_REQUEST:
-                return "TEAR_DOWN_REASON_NO_LIVE_REQUEST";
-            case TEAR_DOWN_REASON_RAT_NOT_ALLOWED:
-                return "TEAR_DOWN_REASON_RAT_NOT_ALLOWED";
-            case TEAR_DOWN_REASON_ROAMING_DISABLED:
-                return "TEAR_DOWN_REASON_ROAMING_DISABLED";
-            case TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED:
-                return "TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED";
-            case TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY:
-                return "TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY";
-            case TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER:
-                return "TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER";
-            case TEAR_DOWN_REASON_DATA_STALL:
-                return "TEAR_DOWN_REASON_DATA_STALL";
-            case TEAR_DOWN_REASON_HANDOVER_FAILED:
-                return "TEAR_DOWN_REASON_HANDOVER_FAILED";
-            case TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED:
-                return "TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED";
-            case TEAR_DOWN_REASON_VCN_REQUESTED:
-                return "TEAR_DOWN_REASON_VCN_REQUESTED";
-            case TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED:
-                return "TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED";
-            case TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED:
-                return "TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED";
-            case TEAR_DOWN_REASON_NOT_IN_SERVICE:
-                return "TEAR_DOWN_REASON_NOT_IN_SERVICE";
-            case TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY:
-                return "TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY";
-            case TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL:
-                return "TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL";
-            case TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE:
-                return "TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE";
-            case TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE:
-                return "TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE";
-            case TEAR_DOWN_REASON_RETRY_SCHEDULED:
-                return "TEAR_DOWN_REASON_RETRY_SCHEDULED";
-            case TEAR_DOWN_REASON_DATA_THROTTLED:
-                return "TEAR_DOWN_REASON_DATA_THROTTLED";
-            case TEAR_DOWN_REASON_DATA_PROFILE_INVALID:
-                return "TEAR_DOWN_REASON_DATA_PROFILE_INVALID";
-            case TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED:
-                return "TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED";
-            case TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY:
-                return "TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY";
-            case TEAR_DOWN_REASON_ILLEGAL_STATE:
-                return "TEAR_DOWN_REASON_ILLEGAL_STATE";
-            case TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK:
-                return "TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK";
-            case TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED:
-                return "TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED";
-            default:
-                return "UNKNOWN(" + reason + ")";
-        }
-    }
-
-    /**
-     * Convert event to string
-     *
-     * @param event The event
-     * @return The event in string format.
-     */
-    private static @NonNull String eventToString(int event) {
-        switch (event) {
-            case EVENT_DATA_CONFIG_UPDATED:
-                return "EVENT_DATA_CONFIG_UPDATED";
-            case EVENT_ATTACH_NETWORK_REQUEST:
-                return "EVENT_ATTACH_NETWORK_REQUEST";
-            case EVENT_DETACH_NETWORK_REQUEST:
-                return "EVENT_DETACH_NETWORK_REQUEST";
-            case EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE:
-                return "EVENT_ALLOCATE_PDU_SESSION_ID_RESPONSE";
-            case EVENT_SETUP_DATA_NETWORK_RESPONSE:
-                return "EVENT_SETUP_DATA_NETWORK_RESPONSE";
-            case EVENT_TEAR_DOWN_NETWORK:
-                return "EVENT_TEAR_DOWN_NETWORK";
-            case EVENT_DATA_STATE_CHANGED:
-                return "EVENT_DATA_STATE_CHANGED";
-            case EVENT_SERVICE_STATE_CHANGED:
-                return "EVENT_DATA_NETWORK_TYPE_REG_STATE_CHANGED";
-            case EVENT_DETACH_ALL_NETWORK_REQUESTS:
-                return "EVENT_DETACH_ALL_NETWORK_REQUESTS";
-            case EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED:
-                return "EVENT_BANDWIDTH_ESTIMATE_FROM_MODEM_CHANGED";
-            case EVENT_DISPLAY_INFO_CHANGED:
-                return "EVENT_DISPLAY_INFO_CHANGED";
-            case EVENT_START_HANDOVER:
-                return "EVENT_START_HANDOVER";
-            case EVENT_HANDOVER_RESPONSE:
-                return "EVENT_HANDOVER_RESPONSE";
-            case EVENT_SUBSCRIPTION_PLAN_OVERRIDE:
-                return "EVENT_SUBSCRIPTION_PLAN_OVERRIDE";
-            case EVENT_PCO_DATA_RECEIVED:
-                return "EVENT_PCO_DATA_RECEIVED";
-            case EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED:
-                return "EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED";
-            case EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE:
-                return "EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE";
-            case EVENT_STUCK_IN_TRANSIENT_STATE:
-                return "EVENT_STUCK_IN_TRANSIENT_STATE";
-            case EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET:
-                return "EVENT_WAITING_FOR_TEARING_DOWN_CONDITION_MET";
-            case EVENT_VOICE_CALL_STARTED:
-                return "EVENT_VOICE_CALL_STARTED";
-            case EVENT_VOICE_CALL_ENDED:
-                return "EVENT_VOICE_CALL_ENDED";
-            case EVENT_CSS_INDICATOR_CHANGED:
-                return "EVENT_CSS_INDICATOR_CHANGED";
-            default:
-                return "Unknown(" + event + ")";
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "[DataNetwork: " + mLogTag + ", " + (mDataProfile.getApnSetting() != null
-                ? mDataProfile.getApnSetting().getApnName() : null) + ", state="
-                + (getCurrentState() != null ? getCurrentState().getName() : null) + "]";
-    }
-
-    /**
-     * @return The short name of the data network (e.g. DN-C-1)
-     */
-    public @NonNull String name() {
-        return mLogTag;
-    }
-
-    /**
-     * Trigger the anomaly report with the specified UUID.
-     *
-     * @param anomalyMsg Description of the event
-     * @param uuid UUID associated with that event
-     */
-    private void reportAnomaly(@NonNull String anomalyMsg, @NonNull String uuid) {
-        logl(anomalyMsg);
-        AnomalyReporter.reportAnomaly(UUID.fromString(uuid), anomalyMsg, mPhone.getCarrierId());
-    }
-
-    /**
-     * Log debug messages.
-     * @param s debug messages
-     */
-    @Override
-    protected void log(@NonNull String s) {
-        Rlog.d(mLogTag, (getCurrentState() != null
-                ? (getCurrentState().getName() + ": ") : "") + s);
-    }
-
-    /**
-     * Log error messages.
-     * @param s error messages
-     */
-    @Override
-    protected void loge(@NonNull String s) {
-        Rlog.e(mLogTag, (getCurrentState() != null
-                ? (getCurrentState().getName() + ": ") : "") + s);
-    }
-
-    /**
-     * Log verbose messages.
-     * @param s error messages
-     */
-    @Override
-    protected void logv(@NonNull String s) {
-        if (VDBG) {
-            Rlog.v(mLogTag, (getCurrentState() != null
-                    ? (getCurrentState().getName() + ": ") : "") + s);
-        }
-    }
-
-    /**
-     * Log debug messages and also log into the local log.
-     * @param s debug messages
-     */
-    private void logl(@NonNull String s) {
-        log(s);
-        mLocalLog.log((getCurrentState() != null ? (getCurrentState().getName() + ": ") : "") + s);
-    }
-
-    /**
-     * Dump the state of DataNetwork
-     *
-     * @param fd File descriptor
-     * @param printWriter Print writer
-     * @param args Arguments
-     */
-    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
-        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
-        super.dump(fd, pw, args);
-        pw.println("Tag: " + name());
-        pw.increaseIndent();
-        pw.println("mSubId=" + mSubId);
-        pw.println("mTransport=" + AccessNetworkConstants.transportTypeToString(mTransport));
-        pw.println("WWAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
-        pw.println("WLAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN));
-        pw.println("mNetworkScore=" + mNetworkScore);
-        pw.println("mDataAllowedReason=" + mDataAllowedReason);
-        pw.println("mPduSessionId=" + mPduSessionId);
-        pw.println("mDataProfile=" + mDataProfile);
-        pw.println("mNetworkCapabilities=" + mNetworkCapabilities);
-        pw.println("mLinkProperties=" + mLinkProperties);
-        pw.println("mNetworkSliceInfo=" + mNetworkSliceInfo);
-        pw.println("mNetworkBandwidth=" + mNetworkBandwidth);
-        pw.println("mTcpBufferSizes=" + mTcpBufferSizes);
-        pw.println("mTelephonyDisplayInfo=" + mTelephonyDisplayInfo);
-        pw.println("mTempNotMeteredSupported=" + mTempNotMeteredSupported);
-        pw.println("mTempNotMetered=" + mTempNotMetered);
-        pw.println("mCongested=" + mCongested);
-        pw.println("mSuspended=" + mSuspended);
-        pw.println("mDataCallResponse=" + mDataCallResponse);
-        pw.println("mFailCause=" + DataFailCause.toString(mFailCause));
-        pw.println("mAdministratorUids=" + Arrays.toString(mAdministratorUids));
-        pw.println("mCarrierServicePackageUid=" + mCarrierServicePackageUid);
-        pw.println("mEverConnected=" + mEverConnected);
-        pw.println("mInvokedDataDeactivation=" + mInvokedDataDeactivation);
-
-        pw.println("Attached network requests:");
-        pw.increaseIndent();
-        for (TelephonyNetworkRequest request : mAttachedNetworkRequestList) {
-            pw.println(request);
-        }
-        pw.decreaseIndent();
-        pw.println("mQosBearerSessions=" + mQosBearerSessions);
-
-        mNetworkAgent.dump(fd, pw, args);
-        pw.println("Local logs:");
-        pw.increaseIndent();
-        mLocalLog.dump(fd, pw, args);
-        pw.decreaseIndent();
-        pw.decreaseIndent();
-        pw.println("---------------");
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/DataNetworkController.java b/src/java/com/android/internal/telephony/data/DataNetworkController.java
deleted file mode 100644
index 7be0a4d..0000000
--- a/src/java/com/android/internal/telephony/data/DataNetworkController.java
+++ /dev/null
@@ -1,3571 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-
-import android.annotation.CallbackExecutor;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.NetworkAgent;
-import android.net.NetworkCapabilities;
-import android.net.NetworkPolicyManager;
-import android.net.NetworkPolicyManager.SubscriptionCallback;
-import android.net.NetworkRequest;
-import android.net.Uri;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
-import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.Annotation.DataActivityType;
-import android.telephony.Annotation.DataFailureCause;
-import android.telephony.Annotation.NetCapability;
-import android.telephony.Annotation.NetworkType;
-import android.telephony.Annotation.ValidationStatus;
-import android.telephony.AnomalyReporter;
-import android.telephony.CarrierConfigManager;
-import android.telephony.CellSignalStrength;
-import android.telephony.DataFailCause;
-import android.telephony.DataSpecificRegistrationInfo;
-import android.telephony.NetworkRegistrationInfo;
-import android.telephony.NetworkRegistrationInfo.RegistrationState;
-import android.telephony.PcoData;
-import android.telephony.ServiceState;
-import android.telephony.SubscriptionManager;
-import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
-import android.telephony.SubscriptionPlan;
-import android.telephony.TelephonyManager;
-import android.telephony.TelephonyManager.DataState;
-import android.telephony.TelephonyManager.SimState;
-import android.telephony.TelephonyRegistryManager;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataCallResponse.HandoverFailureMode;
-import android.telephony.data.DataCallResponse.LinkStatus;
-import android.telephony.data.DataProfile;
-import android.telephony.ims.ImsException;
-import android.telephony.ims.ImsManager;
-import android.telephony.ims.ImsReasonInfo;
-import android.telephony.ims.ImsRegistrationAttributes;
-import android.telephony.ims.ImsStateCallback;
-import android.telephony.ims.RegistrationManager;
-import android.telephony.ims.feature.ImsFeature;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.IndentingPrintWriter;
-import android.util.LocalLog;
-import android.util.SparseArray;
-import android.util.SparseBooleanArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.SlidingWindowEventCounter;
-import com.android.internal.telephony.SubscriptionInfoUpdater;
-import com.android.internal.telephony.TelephonyComponentFactory;
-import com.android.internal.telephony.data.AccessNetworksManager.AccessNetworksManagerCallback;
-import com.android.internal.telephony.data.DataEvaluation.DataAllowedReason;
-import com.android.internal.telephony.data.DataEvaluation.DataDisallowedReason;
-import com.android.internal.telephony.data.DataEvaluation.DataEvaluationReason;
-import com.android.internal.telephony.data.DataNetwork.DataNetworkCallback;
-import com.android.internal.telephony.data.DataNetwork.TearDownReason;
-import com.android.internal.telephony.data.DataProfileManager.DataProfileManagerCallback;
-import com.android.internal.telephony.data.DataRetryManager.DataHandoverRetryEntry;
-import com.android.internal.telephony.data.DataRetryManager.DataRetryEntry;
-import com.android.internal.telephony.data.DataRetryManager.DataRetryManagerCallback;
-import com.android.internal.telephony.data.DataRetryManager.DataSetupRetryEntry;
-import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
-import com.android.internal.telephony.data.DataStallRecoveryManager.DataStallRecoveryManagerCallback;
-import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
-import com.android.internal.telephony.ims.ImsResolver;
-import com.android.internal.telephony.util.TelephonyUtils;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.function.Function;
-import java.util.stream.Collectors;
-
-/**
- * DataNetworkController in the central module of the telephony data stack. It is responsible to
- * create and manage all the mobile data networks. It is per-SIM basis which means for DSDS devices,
- * there will be two DataNetworkController instances. Unlike the Android 12 DcTracker, which is
- * designed to be per-transport (i.e. cellular, IWLAN), DataNetworkController is designed to handle
- * data networks on both cellular and IWLAN.
- */
-public class DataNetworkController extends Handler {
-    private static final boolean VDBG = false;
-
-    /** Event for data config updated. */
-    private static final int EVENT_DATA_CONFIG_UPDATED = 1;
-
-    /** Event for adding a network request. */
-    private static final int EVENT_ADD_NETWORK_REQUEST = 2;
-
-    /** Event for removing a network request. */
-    private static final int EVENT_REMOVE_NETWORK_REQUEST = 3;
-
-    /** Re-evaluate all unsatisfied network requests. */
-    private static final int EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS = 5;
-
-    /** Event for packet switch restricted enabled by network. */
-    private static final int EVENT_PS_RESTRICT_ENABLED = 6;
-
-    /** Event for packet switch restricted disabled by network. */
-    private static final int EVENT_PS_RESTRICT_DISABLED = 7;
-
-    /** Event for data service binding changed. */
-    private static final int EVENT_DATA_SERVICE_BINDING_CHANGED = 8;
-
-    /** Event for SIM state changed. */
-    private static final int EVENT_SIM_STATE_CHANGED = 9;
-
-    /** Event for tearing down all data networks. */
-    private static final int EVENT_TEAR_DOWN_ALL_DATA_NETWORKS = 12;
-
-    /** Event for registering data network controller callback. */
-    private static final int EVENT_REGISTER_DATA_NETWORK_CONTROLLER_CALLBACK = 13;
-
-    /** Event for unregistering data network controller callback. */
-    private static final int EVENT_UNREGISTER_DATA_NETWORK_CONTROLLER_CALLBACK = 14;
-
-    /** Event for subscription info changed. */
-    private static final int EVENT_SUBSCRIPTION_CHANGED = 15;
-
-    /** Event for re-evaluating existing data networks. */
-    private static final int EVENT_REEVALUATE_EXISTING_DATA_NETWORKS = 16;
-
-    /** Event for data RAT or registration state changed. */
-    private static final int EVENT_SERVICE_STATE_CHANGED = 17;
-
-    /** Event for voice call ended. */
-    private static final int EVENT_VOICE_CALL_ENDED = 18;
-
-    /** Event for registering all events. */
-    private static final int EVENT_REGISTER_ALL_EVENTS = 19;
-
-    /** Event for emergency call started or ended. */
-    private static final int EVENT_EMERGENCY_CALL_CHANGED = 20;
-
-    /** Event for evaluating preferred transport. */
-    private static final int EVENT_EVALUATE_PREFERRED_TRANSPORT = 21;
-
-    /** Event for subscription plans changed. */
-    private static final int EVENT_SUBSCRIPTION_PLANS_CHANGED = 22;
-
-    /** Event for unmetered or congested subscription override. */
-    private static final int EVENT_SUBSCRIPTION_OVERRIDE = 23;
-
-    /** Event for slice config changed. */
-    private static final int EVENT_SLICE_CONFIG_CHANGED = 24;
-
-    /** Event for tracking area code changed. */
-    private static final int EVENT_TAC_CHANGED = 25;
-
-    /** The supported IMS features. This is for IMS graceful tear down support. */
-    private static final Collection<Integer> SUPPORTED_IMS_FEATURES =
-            List.of(ImsFeature.FEATURE_MMTEL, ImsFeature.FEATURE_RCS);
-
-    /** The maximum number of previously connected data networks for debugging purposes. */
-    private static final int MAX_HISTORICAL_CONNECTED_DATA_NETWORKS = 10;
-
-    /**
-     * The delay in milliseconds to re-evaluate preferred transport when handover failed and
-     * fallback to source.
-     */
-    private static final long REEVALUATE_PREFERRED_TRANSPORT_DELAY_MILLIS =
-            TimeUnit.SECONDS.toMillis(3);
-
-    /** The delay in milliseconds to re-evaluate unsatisfied network requests after call end. */
-    private static final long REEVALUATE_UNSATISFIED_NETWORK_REQUESTS_AFTER_CALL_END_DELAY_MILLIS =
-            TimeUnit.MILLISECONDS.toMillis(500);
-
-    /** The delay in milliseconds to re-evaluate unsatisfied network requests after TAC changes. */
-    private static final long REEVALUATE_UNSATISFIED_NETWORK_REQUESTS_TAC_CHANGED_DELAY_MILLIS =
-            TimeUnit.MILLISECONDS.toMillis(100);
-
-    private final Phone mPhone;
-    private final String mLogTag;
-    private final LocalLog mLocalLog = new LocalLog(128);
-
-    private final @NonNull DataConfigManager mDataConfigManager;
-    private final @NonNull DataSettingsManager mDataSettingsManager;
-    private final @NonNull DataProfileManager mDataProfileManager;
-    private final @NonNull DataStallRecoveryManager mDataStallRecoveryManager;
-    private final @NonNull AccessNetworksManager mAccessNetworksManager;
-    private final @NonNull DataRetryManager mDataRetryManager;
-    private final @NonNull ImsManager mImsManager;
-    private final @NonNull NetworkPolicyManager mNetworkPolicyManager;
-    private final @NonNull SparseArray<DataServiceManager> mDataServiceManagers =
-            new SparseArray<>();
-
-    /** The subscription index associated with this data network controller. */
-    private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-
-    /** The current service state of the device. */
-    // Note that keeping a copy here instead of directly using ServiceStateTracker.getServiceState()
-    // is intended for detecting the delta.
-    private @NonNull ServiceState mServiceState;
-
-    /** The list of SubscriptionPlans, updated when initialized and when plans are changed. */
-    private final @NonNull List<SubscriptionPlan> mSubscriptionPlans = new ArrayList<>();
-
-    /**
-     * The set of network types an unmetered override applies to, set by onSubscriptionOverride
-     * and cleared when the device is rebooted or the override expires.
-     */
-    private final @NonNull @NetworkType Set<Integer> mUnmeteredOverrideNetworkTypes =
-            new ArraySet<>();
-
-    /**
-     * The set of network types a congested override applies to, set by onSubscriptionOverride
-     * and cleared when the device is rebooted or the override expires.
-     */
-    private final @NonNull @NetworkType Set<Integer> mCongestedOverrideNetworkTypes =
-            new ArraySet<>();
-
-    /**
-     * The list of all network requests.
-     */
-    private final @NonNull NetworkRequestList mAllNetworkRequestList = new NetworkRequestList();
-
-    /**
-     * The current data network list, including the ones that are connected, connecting, or
-     * disconnecting.
-     */
-    private final @NonNull List<DataNetwork> mDataNetworkList = new ArrayList<>();
-
-    /** {@code true} indicating at least one data network exists. */
-    private boolean mAnyDataNetworkExisting;
-
-    /**
-     * Contain the last 10 data networks that were connected. This is for debugging purposes only.
-     */
-    private final @NonNull List<DataNetwork> mPreviousConnectedDataNetworkList = new ArrayList<>();
-
-    /**
-     * The internet data network state. Note that this is the best effort if more than one
-     * data network supports internet.
-     */
-    private @DataState int mInternetDataNetworkState = TelephonyManager.DATA_DISCONNECTED;
-
-    /**
-     * The IMS data network state. For now this is just for debugging purposes.
-     */
-    private @DataState int mImsDataNetworkState = TelephonyManager.DATA_DISCONNECTED;
-
-    /** Overall aggregated link status from internet data networks. */
-    private @LinkStatus int mInternetLinkStatus = DataCallResponse.LINK_STATUS_UNKNOWN;
-
-    /** Data network controller callbacks. */
-    private final @NonNull Set<DataNetworkControllerCallback> mDataNetworkControllerCallbacks =
-            new ArraySet<>();
-
-    /** Indicates if packet switch data is restricted by the network. */
-    private boolean mPsRestricted = false;
-
-    /** Indicates if NR advanced is allowed by PCO. */
-    private boolean mNrAdvancedCapableByPco = false;
-
-    /**
-     * Indicates if the data services are bound. Key if the transport type, and value is the boolean
-     * indicating service is bound or not.
-     */
-    private final @NonNull SparseBooleanArray mDataServiceBound = new SparseBooleanArray();
-
-    /** SIM state. */
-    private @SimState int mSimState = TelephonyManager.SIM_STATE_UNKNOWN;
-
-    /** Data activity. */
-    private @DataActivityType int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
-
-    /**
-     * IMS state callbacks. Key is the IMS feature, value is the callback.
-     */
-    private final @NonNull SparseArray<ImsStateCallback> mImsStateCallbacks = new SparseArray<>();
-
-    /** Registered IMS features. Unregistered IMS features are removed from the set. */
-    private final @NonNull Set<Integer> mRegisteredImsFeatures = new ArraySet<>();
-
-    /** IMS feature package names. Key is the IMS feature, value is the package name. */
-    private final @NonNull SparseArray<String> mImsFeaturePackageName = new SparseArray<>();
-
-    /**
-     * Networks that are pending IMS de-registration. Key is the data network, value is the function
-     * to tear down the network.
-     */
-    private final @NonNull Map<DataNetwork, Runnable> mPendingImsDeregDataNetworks =
-            new ArrayMap<>();
-
-    /**
-     * IMS feature registration callback. The key is the IMS feature, the value is the registration
-     * callback. When new SIM inserted, the old callbacks associated with the old subscription index
-     * will be unregistered.
-     */
-    private final @NonNull SparseArray<RegistrationManager.RegistrationCallback>
-            mImsFeatureRegistrationCallbacks = new SparseArray<>();
-
-    /** The counter to detect back to back release/request IMS network. */
-    private @NonNull SlidingWindowEventCounter mImsThrottleCounter;
-    /** Event counter for unwanted network within time window, is used to trigger anomaly report. */
-    private @NonNull SlidingWindowEventCounter mNetworkUnwantedCounter;
-    /** Event counter for WLAN setup data failure within time window to trigger anomaly report. */
-    private @NonNull SlidingWindowEventCounter mSetupDataCallWlanFailureCounter;
-    /** Event counter for WWAN setup data failure within time window to trigger anomaly report. */
-    private @NonNull SlidingWindowEventCounter mSetupDataCallWwanFailureCounter;
-
-    /**
-     * {@code true} if {@link #tearDownAllDataNetworks(int)} was invoked and waiting for all
-     * networks torn down.
-     */
-    private boolean mPendingTearDownAllNetworks = false;
-
-    /**
-     * The capabilities of the latest released IMS request. To detect back to back release/request
-     * IMS network.
-     */
-    private int[] mLastReleasedImsRequestCapabilities;
-
-    /** True after try to release an IMS network; False after try to request an IMS network. */
-    private boolean mLastImsOperationIsRelease;
-
-    /** The broadcast receiver. */
-    private final BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            switch(intent.getAction()) {
-                case TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED:
-                case TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED:
-                    if (mPhone.getPhoneId() == intent.getIntExtra(
-                            SubscriptionManager.EXTRA_SLOT_INDEX,
-                            SubscriptionManager.INVALID_SIM_SLOT_INDEX)) {
-                        int simState = intent.getIntExtra(TelephonyManager.EXTRA_SIM_STATE,
-                                TelephonyManager.SIM_STATE_UNKNOWN);
-                        sendMessage(obtainMessage(EVENT_SIM_STATE_CHANGED, simState, 0));
-                    }
-            }
-        }
-    };
-
-    /**
-     * The sorted network request list by priority. The highest priority network request stays at
-     * the head of the list. The highest priority is 100, the lowest is 0.
-     *
-     * Note this list is not thread-safe. Do not access the list from different threads.
-     */
-    @VisibleForTesting
-    public static class NetworkRequestList extends LinkedList<TelephonyNetworkRequest> {
-        /**
-         * Constructor
-         */
-        public NetworkRequestList() {
-        }
-
-        /**
-         * Copy constructor
-         *
-         * @param requestList The network request list.
-         */
-        public NetworkRequestList(@NonNull NetworkRequestList requestList) {
-            addAll(requestList);
-        }
-
-        /**
-         * Constructor
-         *
-         * @param requestList The network request list.
-         */
-        public NetworkRequestList(@NonNull List<TelephonyNetworkRequest> requestList) {
-            addAll(requestList);
-        }
-
-        /**
-         * Constructor
-         *
-         * @param newRequest The initial request of the list.
-         */
-        public NetworkRequestList(@NonNull TelephonyNetworkRequest newRequest) {
-            this();
-            add(newRequest);
-        }
-
-        /**
-         * Add the network request to the list. Note that the item will be inserted to the position
-         * based on the priority.
-         *
-         * @param newRequest The network request to be added.
-         * @return {@code true} if added successfully. {@code false} if the request already exists.
-         */
-        @Override
-        public boolean add(@NonNull TelephonyNetworkRequest newRequest) {
-            int index = 0;
-            while (index < size()) {
-                TelephonyNetworkRequest networkRequest = get(index);
-                if (networkRequest.equals(newRequest)) {
-                    return false;   // Do not allow duplicate
-                }
-                if (newRequest.getPriority() > networkRequest.getPriority()) {
-                    break;
-                }
-                index++;
-            }
-            super.add(index, newRequest);
-            return true;
-        }
-
-        @Override
-        public void add(int index, @NonNull TelephonyNetworkRequest newRequest) {
-            throw new UnsupportedOperationException("Insertion to certain position is illegal.");
-        }
-
-        @Override
-        public boolean addAll(Collection<? extends TelephonyNetworkRequest> requests) {
-            for (TelephonyNetworkRequest networkRequest : requests) {
-                add(networkRequest);
-            }
-            return true;
-        }
-        /**
-         * Get the first network request that contains all the provided network capabilities.
-         *
-         * @param netCaps The network capabilities.
-         * @return The first network request in the list that contains all the provided
-         * capabilities.
-         */
-        public @Nullable TelephonyNetworkRequest get(@NonNull @NetCapability int[] netCaps) {
-            int index = 0;
-            while (index < size()) {
-                TelephonyNetworkRequest networkRequest = get(index);
-                // Check if any network requests contains all the provided capabilities.
-                if (Arrays.stream(networkRequest.getCapabilities())
-                        .boxed()
-                        .collect(Collectors.toSet())
-                        .containsAll(Arrays.stream(netCaps).boxed()
-                                .collect(Collectors.toList()))) {
-                    return networkRequest;
-                }
-                index++;
-            }
-            return null;
-        }
-
-        /**
-         * Check if any network request is requested by the specified package.
-         *
-         * @param packageName The package name.
-         * @return {@code true} if any request is originated from the specified package.
-         */
-        public boolean hasNetworkRequestsFromPackage(@NonNull String packageName) {
-            for (TelephonyNetworkRequest networkRequest : this) {
-                if (packageName.equals(
-                        networkRequest.getNativeNetworkRequest().getRequestorPackageName())) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public String toString() {
-            return "[NetworkRequestList: size=" + size() + (size() > 0 ? ", leading by "
-                    + get(0) : "") + "]";
-        }
-
-        /**
-         * Dump the network request list.
-         *
-         * @param pw print writer.
-         */
-        public void dump(IndentingPrintWriter pw) {
-            pw.increaseIndent();
-            for (TelephonyNetworkRequest networkRequest : this) {
-                pw.println(networkRequest);
-            }
-            pw.decreaseIndent();
-        }
-    }
-
-    /**
-     * The data network controller callback. Note this is only used for passing information
-     * internally in the data stack, should not be used externally.
-     */
-    public static class DataNetworkControllerCallback extends DataCallback {
-        /**
-         * Constructor
-         *
-         * @param executor The executor of the callback.
-         */
-        public DataNetworkControllerCallback(@NonNull @CallbackExecutor Executor executor) {
-            super(executor);
-        }
-
-        /**
-         * Called when internet data network validation status changed.
-         *
-         * @param validationStatus The validation status.
-         */
-        public void onInternetDataNetworkValidationStatusChanged(
-                @ValidationStatus int validationStatus) {}
-
-        /**
-         * Called when internet data network is connected.
-         *
-         * @param dataProfiles The data profiles of the connected internet data network. It should
-         * be only one in most of the cases.
-         */
-        public void onInternetDataNetworkConnected(@NonNull List<DataProfile> dataProfiles) {}
-
-        /** Called when internet data network is disconnected. */
-        public void onInternetDataNetworkDisconnected() {}
-
-        /**
-         * Called when any data network existing status changed.
-         *
-         * @param anyDataExisting {@code true} indicating there is at least one data network
-         * existing regardless of its state. {@code false} indicating all data networks are
-         * disconnected.
-         */
-        public void onAnyDataNetworkExistingChanged(boolean anyDataExisting) {}
-
-        /**
-         * Called when {@link SubscriptionPlan}s change or an unmetered or congested subscription
-         * override is set.
-         */
-        public void onSubscriptionPlanOverride() {}
-
-        /**
-         * Called when the physical link status changed.
-         *
-         * @param status The latest link status.
-         */
-        public void onPhysicalLinkStatusChanged(@LinkStatus int status) {}
-
-        /**
-         * Called when NR advanced capable by PCO changed.
-         *
-         * @param nrAdvancedCapable {@code true} if at least one of the data network is NR advanced
-         * capable.
-         */
-        public void onNrAdvancedCapableByPcoChanged(boolean nrAdvancedCapable) {}
-
-        /**
-         * Called when data service is bound.
-         *
-         * @param transport The transport of the data service.
-         */
-        public void onDataServiceBound(@TransportType int transport) {}
-    }
-
-    /**
-     * This class represent a rule allowing or disallowing handover between IWLAN and cellular
-     * networks.
-     *
-     * @see CarrierConfigManager#KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY
-     */
-    public static class HandoverRule {
-        @Retention(RetentionPolicy.SOURCE)
-        @IntDef(prefix = {"RULE_TYPE_"},
-                value = {
-                        RULE_TYPE_ALLOWED,
-                        RULE_TYPE_DISALLOWED,
-                })
-        public @interface HandoverRuleType {}
-
-        /** Indicating this rule is for allowing handover. */
-        public static final int RULE_TYPE_ALLOWED = 1;
-
-        /** Indicating this rule is for disallowing handover. */
-        public static final int RULE_TYPE_DISALLOWED = 2;
-
-        private static final String RULE_TAG_SOURCE_ACCESS_NETWORKS = "source";
-
-        private static final String RULE_TAG_TARGET_ACCESS_NETWORKS = "target";
-
-        private static final String RULE_TAG_TYPE = "type";
-
-        private static final String RULE_TAG_CAPABILITIES = "capabilities";
-
-        private static final String RULE_TAG_ROAMING = "roaming";
-
-        /** Handover rule type. */
-        public final @HandoverRuleType int type;
-
-        /** The applicable source access networks for handover. */
-        public final @NonNull @RadioAccessNetworkType Set<Integer> sourceAccessNetworks;
-
-        /** The applicable target access networks for handover. */
-        public final @NonNull @RadioAccessNetworkType Set<Integer> targetAccessNetworks;
-
-        /**
-         * The network capabilities to any of which this handover rule applies.
-         * If is empty, then capability is ignored as a rule matcher.
-         */
-        public final @NonNull @NetCapability Set<Integer> networkCapabilities;
-
-        /** {@code true} indicates this policy is only applicable when the device is roaming. */
-        public final boolean isOnlyForRoaming;
-
-        /**
-         * Constructor
-         *
-         * @param ruleString The rule in string format.
-         *
-         * @see CarrierConfigManager#KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY
-         */
-        public HandoverRule(@NonNull String ruleString) {
-            if (TextUtils.isEmpty(ruleString)) {
-                throw new IllegalArgumentException("illegal rule " + ruleString);
-            }
-
-            Set<Integer> source = null, target = null, capabilities = Collections.emptySet();
-            int type = 0;
-            boolean roaming = false;
-
-            ruleString = ruleString.trim().toLowerCase(Locale.ROOT);
-            String[] expressions = ruleString.split("\\s*,\\s*");
-            for (String expression : expressions) {
-                String[] tokens = expression.trim().split("\\s*=\\s*");
-                if (tokens.length != 2) {
-                    throw new IllegalArgumentException("illegal rule " + ruleString + ", tokens="
-                            + Arrays.toString(tokens));
-                }
-                String key = tokens[0].trim();
-                String value = tokens[1].trim();
-                try {
-                    switch (key) {
-                        case RULE_TAG_SOURCE_ACCESS_NETWORKS:
-                            source = Arrays.stream(value.split("\\s*\\|\\s*"))
-                                    .map(String::trim)
-                                    .map(AccessNetworkType::fromString)
-                                    .collect(Collectors.toSet());
-                            break;
-                        case RULE_TAG_TARGET_ACCESS_NETWORKS:
-                            target = Arrays.stream(value.split("\\s*\\|\\s*"))
-                                    .map(String::trim)
-                                    .map(AccessNetworkType::fromString)
-                                    .collect(Collectors.toSet());
-                            break;
-                        case RULE_TAG_TYPE:
-                            if (value.toLowerCase(Locale.ROOT).equals("allowed")) {
-                                type = RULE_TYPE_ALLOWED;
-                            } else if (value.toLowerCase(Locale.ROOT).equals("disallowed")) {
-                                type = RULE_TYPE_DISALLOWED;
-                            } else {
-                                throw new IllegalArgumentException("unexpected rule type " + value);
-                            }
-                            break;
-                        case RULE_TAG_CAPABILITIES:
-                            capabilities = DataUtils.getNetworkCapabilitiesFromString(value);
-                            break;
-                        case RULE_TAG_ROAMING:
-                            roaming = Boolean.parseBoolean(value);
-                            break;
-                        default:
-                            throw new IllegalArgumentException("unexpected key " + key);
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                    throw new IllegalArgumentException("illegal rule \"" + ruleString + "\", e="
-                            + e);
-                }
-            }
-
-            if (source == null || target == null || source.isEmpty() || target.isEmpty()) {
-                throw new IllegalArgumentException("Need to specify both source and target. "
-                        + "\"" + ruleString + "\"");
-            }
-
-            if (source.contains(AccessNetworkType.UNKNOWN)) {
-                throw new IllegalArgumentException("Source access networks contains unknown. "
-                        + "\"" + ruleString + "\"");
-            }
-
-            if (target.contains(AccessNetworkType.UNKNOWN)) {
-                throw new IllegalArgumentException("Target access networks contains unknown. "
-                        + "\"" + ruleString + "\"");
-            }
-
-            if (type == 0) {
-                throw new IllegalArgumentException("Rule type is not specified correctly. "
-                        + "\"" + ruleString + "\"");
-            }
-
-            if (capabilities != null && capabilities.contains(-1)) {
-                throw new IllegalArgumentException("Network capabilities contains unknown. "
-                            + "\"" + ruleString + "\"");
-            }
-
-            if (!source.contains(AccessNetworkType.IWLAN)
-                    && !target.contains(AccessNetworkType.IWLAN)) {
-                throw new IllegalArgumentException("IWLAN must be specified in either source or "
-                        + "target access networks.\"" + ruleString + "\"");
-            }
-
-            sourceAccessNetworks = source;
-            targetAccessNetworks = target;
-            this.type = type;
-            networkCapabilities = capabilities;
-            isOnlyForRoaming = roaming;
-        }
-
-        @Override
-        public String toString() {
-            return "[HandoverRule: type=" + (type == RULE_TYPE_ALLOWED ? "allowed"
-                    : "disallowed") + ", source=" + sourceAccessNetworks.stream()
-                    .map(AccessNetworkType::toString).collect(Collectors.joining("|"))
-                    + ", target=" + targetAccessNetworks.stream().map(AccessNetworkType::toString)
-                    .collect(Collectors.joining("|")) + ", isRoaming=" + isOnlyForRoaming
-                    + ", capabilities=" + DataUtils.networkCapabilitiesToString(networkCapabilities)
-                    + "]";
-        }
-    }
-
-    /**
-     * Constructor
-     *
-     * @param phone The phone instance.
-     * @param looper The looper to be used by the handler. Currently the handler thread is the
-     * phone process's main thread.
-     */
-    public DataNetworkController(@NonNull Phone phone, @NonNull Looper looper) {
-        super(looper);
-        mPhone = phone;
-        mLogTag = "DNC-" + mPhone.getPhoneId();
-        log("DataNetworkController created.");
-
-        mAccessNetworksManager = phone.getAccessNetworksManager();
-        mDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                new DataServiceManager(mPhone, looper, AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
-        if (!mAccessNetworksManager.isInLegacyMode()) {
-            mDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
-                    new DataServiceManager(mPhone, looper,
-                            AccessNetworkConstants.TRANSPORT_TYPE_WLAN));
-        }
-        mDataConfigManager = new DataConfigManager(mPhone, looper);
-
-        // ========== Anomaly counters ==========
-        mImsThrottleCounter = new SlidingWindowEventCounter(
-                mDataConfigManager.getAnomalyImsReleaseRequestThreshold().timeWindow,
-                mDataConfigManager.getAnomalyImsReleaseRequestThreshold().eventNumOccurrence);
-        mNetworkUnwantedCounter = new SlidingWindowEventCounter(
-                mDataConfigManager.getAnomalyNetworkUnwantedThreshold().timeWindow,
-                mDataConfigManager.getAnomalyNetworkUnwantedThreshold().eventNumOccurrence);
-        mSetupDataCallWlanFailureCounter = new SlidingWindowEventCounter(
-                mDataConfigManager.getAnomalySetupDataCallThreshold().timeWindow,
-                mDataConfigManager.getAnomalySetupDataCallThreshold().eventNumOccurrence);
-        mSetupDataCallWwanFailureCounter = new SlidingWindowEventCounter(
-                mDataConfigManager.getAnomalySetupDataCallThreshold().timeWindow,
-                mDataConfigManager.getAnomalySetupDataCallThreshold().eventNumOccurrence);
-        // ========================================
-
-        mDataSettingsManager = TelephonyComponentFactory.getInstance().inject(
-                DataSettingsManager.class.getName())
-                .makeDataSettingsManager(mPhone, this, looper,
-                        new DataSettingsManagerCallback(this::post) {
-                            @Override
-                            public void onDataEnabledChanged(boolean enabled,
-                                    @TelephonyManager.DataEnabledChangedReason int reason,
-                                    @NonNull String callingPackage) {
-                                // If mobile data is enabled by the user, evaluate the unsatisfied
-                                // network requests and then attempt to setup data networks to
-                                // satisfy them. If mobile data is disabled, evaluate the existing
-                                // data networks and see if they need to be torn down.
-                                logl("onDataEnabledChanged: enabled=" + enabled);
-                                sendMessage(obtainMessage(enabled
-                                                ? EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS
-                                                : EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
-                                        DataEvaluationReason.DATA_ENABLED_CHANGED));
-                            }
-                            @Override
-                            public void onDataEnabledOverrideChanged(boolean enabled,
-                                    @TelephonyManager.MobileDataPolicy int policy) {
-                                // If data enabled override is enabled by the user, evaluate the
-                                // unsatisfied network requests and then attempt to setup data
-                                // networks to satisfy them. If data enabled override is disabled,
-                                // evaluate the existing data networks and see if they need to be
-                                // torn down.
-                                logl("onDataEnabledOverrideChanged: enabled=" + enabled);
-                                sendMessage(obtainMessage(enabled
-                                                ? EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS
-                                                : EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
-                                        DataEvaluationReason.DATA_ENABLED_OVERRIDE_CHANGED));
-                            }
-                            @Override
-                            public void onDataRoamingEnabledChanged(boolean enabled) {
-                                // If data roaming is enabled by the user, evaluate the unsatisfied
-                                // network requests and then attempt to setup data networks to
-                                // satisfy them. If data roaming is disabled, evaluate the existing
-                                // data networks and see if they need to be torn down.
-                                logl("onDataRoamingEnabledChanged: enabled=" + enabled);
-                                sendMessage(obtainMessage(enabled
-                                                ? EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS
-                                                : EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
-                                        DataEvaluationReason.ROAMING_ENABLED_CHANGED));
-                            }
-                        });
-        mDataProfileManager = TelephonyComponentFactory.getInstance().inject(
-                DataProfileManager.class.getName())
-                .makeDataProfileManager(mPhone, this, mDataServiceManagers
-                                .get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), looper,
-                        new DataProfileManagerCallback(this::post) {
-                            @Override
-                            public void onDataProfilesChanged() {
-                                sendMessage(
-                                        obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
-                                        DataEvaluationReason.DATA_PROFILES_CHANGED));
-                                sendMessage(
-                                        obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
-                                        DataEvaluationReason.DATA_PROFILES_CHANGED));
-                            }
-                        });
-        mDataStallRecoveryManager = new DataStallRecoveryManager(mPhone, this, mDataServiceManagers
-                .get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), looper,
-                new DataStallRecoveryManagerCallback(this::post) {
-                    @Override
-                    public void onDataStallReestablishInternet() {
-                        DataNetworkController.this.onDataStallReestablishInternet();
-                    }
-                });
-        mDataRetryManager = new DataRetryManager(mPhone, this,
-                mDataServiceManagers, looper,
-                new DataRetryManagerCallback(this::post) {
-                    @Override
-                    public void onDataNetworkSetupRetry(
-                            @NonNull DataSetupRetryEntry dataSetupRetryEntry) {
-                        Objects.requireNonNull(dataSetupRetryEntry);
-                        DataNetworkController.this.onDataNetworkSetupRetry(dataSetupRetryEntry);
-                    }
-                    @Override
-                    public void onDataNetworkHandoverRetry(
-                            @NonNull DataHandoverRetryEntry dataHandoverRetryEntry) {
-                        Objects.requireNonNull(dataHandoverRetryEntry);
-                        DataNetworkController.this
-                                .onDataNetworkHandoverRetry(dataHandoverRetryEntry);
-                    }
-                    @Override
-                    public void onDataNetworkHandoverRetryStopped(
-                            @NonNull DataNetwork dataNetwork) {
-                        Objects.requireNonNull(dataNetwork);
-                        int preferredTransport = mAccessNetworksManager
-                                .getPreferredTransportByNetworkCapability(
-                                        dataNetwork.getApnTypeNetworkCapability());
-                        if (dataNetwork.getTransport() == preferredTransport) {
-                            log("onDataNetworkHandoverRetryStopped: " + dataNetwork + " is already "
-                                    + "on the preferred transport "
-                                    + AccessNetworkConstants.transportTypeToString(
-                                            preferredTransport));
-                            return;
-                        }
-                        if (dataNetwork.shouldDelayImsTearDown()) {
-                            log("onDataNetworkHandoverRetryStopped: Delay IMS tear down until call "
-                                    + "ends. " + dataNetwork);
-                            return;
-                        }
-
-                        tearDownGracefully(dataNetwork,
-                                DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED);
-                    }
-                });
-        mImsManager = mPhone.getContext().getSystemService(ImsManager.class);
-        mNetworkPolicyManager = mPhone.getContext().getSystemService(NetworkPolicyManager.class);
-
-        // Use the raw one from ServiceStateTracker instead of the combined one from
-        // mPhone.getServiceState().
-        mServiceState = mPhone.getServiceStateTracker().getServiceState();
-
-        // Instead of calling onRegisterAllEvents directly from the constructor, send the event.
-        // The reason is that getImsPhone is null when we are still in the constructor here.
-        sendEmptyMessage(EVENT_REGISTER_ALL_EVENTS);
-    }
-
-    /**
-     * Called when needed to register for all events that data network controller is interested.
-     */
-    private void onRegisterAllEvents() {
-        IntentFilter filter = new IntentFilter();
-        filter.addAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
-        filter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
-        mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
-
-        mAccessNetworksManager.registerCallback(new AccessNetworksManagerCallback(this::post) {
-            @Override
-            public void onPreferredTransportChanged(@NetCapability int capability) {
-                int preferredTransport = mAccessNetworksManager
-                        .getPreferredTransportByNetworkCapability(capability);
-                logl("onPreferredTransportChanged: "
-                        + DataUtils.networkCapabilityToString(capability) + " preferred on "
-                        + AccessNetworkConstants.transportTypeToString(preferredTransport));
-                DataNetworkController.this.onEvaluatePreferredTransport(capability);
-                if (!hasMessages(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS)) {
-                    sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
-                            DataEvaluationReason.PREFERRED_TRANSPORT_CHANGED));
-                } else {
-                    log("onPreferredTransportChanged: Skipped evaluating unsatisfied network "
-                            + "requests because another evaluation was already scheduled.");
-                }
-            }
-        });
-
-        mNetworkPolicyManager.registerSubscriptionCallback(new SubscriptionCallback() {
-            @Override
-            public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) {
-                if (mSubId != subId) return;
-                obtainMessage(EVENT_SUBSCRIPTION_PLANS_CHANGED, plans).sendToTarget();
-            }
-
-            @Override
-            public void onSubscriptionOverride(int subId, int overrideMask, int overrideValue,
-                    int[] networkTypes) {
-                if (mSubId != subId) return;
-                obtainMessage(EVENT_SUBSCRIPTION_OVERRIDE, overrideMask, overrideValue,
-                        networkTypes).sendToTarget();
-            }
-        });
-
-        mPhone.getServiceStateTracker().registerForServiceStateChanged(this,
-                EVENT_SERVICE_STATE_CHANGED);
-        mDataConfigManager.registerForConfigUpdate(this, EVENT_DATA_CONFIG_UPDATED);
-        mPhone.getServiceStateTracker().registerForPsRestrictedEnabled(this,
-                EVENT_PS_RESTRICT_ENABLED, null);
-        mPhone.getServiceStateTracker().registerForPsRestrictedDisabled(this,
-                EVENT_PS_RESTRICT_DISABLED, null);
-        mPhone.getServiceStateTracker().registerForAreaCodeChanged(this, EVENT_TAC_CHANGED, null);
-        mPhone.registerForEmergencyCallToggle(this, EVENT_EMERGENCY_CALL_CHANGED, null);
-        mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .registerForServiceBindingChanged(this, EVENT_DATA_SERVICE_BINDING_CHANGED);
-
-        if (!mAccessNetworksManager.isInLegacyMode()) {
-            mPhone.getServiceStateTracker().registerForServiceStateChanged(this,
-                    EVENT_SERVICE_STATE_CHANGED);
-            mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
-                    .registerForServiceBindingChanged(this, EVENT_DATA_SERVICE_BINDING_CHANGED);
-        }
-
-        mPhone.getContext().getSystemService(TelephonyRegistryManager.class)
-                .addOnSubscriptionsChangedListener(new OnSubscriptionsChangedListener() {
-                    @Override
-                    public void onSubscriptionsChanged() {
-                        sendEmptyMessage(EVENT_SUBSCRIPTION_CHANGED);
-                    }
-                }, this::post);
-
-        // Register for call ended event for voice/data concurrent not supported case. It is
-        // intended to only listen for events from the same phone as most of the telephony modules
-        // are designed as per-SIM basis. For DSDS call ended on non-DDS sub, the frameworks relies
-        // on service state on DDS sub change from out-of-service to in-service to trigger data
-        // retry.
-        mPhone.getCallTracker().registerForVoiceCallEnded(this, EVENT_VOICE_CALL_ENDED, null);
-        // Check null for devices not supporting FEATURE_TELEPHONY_IMS.
-        if (mPhone.getImsPhone() != null) {
-            mPhone.getImsPhone().getCallTracker().registerForVoiceCallEnded(
-                    this, EVENT_VOICE_CALL_ENDED, null);
-        }
-        mPhone.mCi.registerForSlicingConfigChanged(this, EVENT_SLICE_CONFIG_CHANGED, null);
-
-        mPhone.getLinkBandwidthEstimator().registerCallback(
-                new LinkBandwidthEstimatorCallback(this::post) {
-                    @Override
-                    public void onDataActivityChanged(@DataActivityType int dataActivity) {
-                        DataNetworkController.this.updateDataActivity();
-                    }
-                }
-        );
-    }
-
-    @Override
-    public void handleMessage(@NonNull Message msg) {
-        switch (msg.what) {
-            case EVENT_DATA_CONFIG_UPDATED:
-                onDataConfigUpdated();
-                break;
-            case EVENT_REGISTER_ALL_EVENTS:
-                onRegisterAllEvents();
-                break;
-            case EVENT_ADD_NETWORK_REQUEST:
-                onAddNetworkRequest((TelephonyNetworkRequest) msg.obj);
-                break;
-            case EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS:
-                DataEvaluationReason reason = (DataEvaluationReason) msg.obj;
-                onReevaluateUnsatisfiedNetworkRequests(reason);
-                break;
-            case EVENT_REEVALUATE_EXISTING_DATA_NETWORKS:
-                reason = (DataEvaluationReason) msg.obj;
-                onReevaluateExistingDataNetworks(reason);
-                break;
-            case EVENT_REMOVE_NETWORK_REQUEST:
-                onRemoveNetworkRequest((TelephonyNetworkRequest) msg.obj);
-                break;
-            case EVENT_VOICE_CALL_ENDED:
-                // In some cases we need to tear down network after call ends. For example, when
-                // delay IMS tear down until call ends is turned on.
-                sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
-                        DataEvaluationReason.VOICE_CALL_ENDED));
-                // Delay evaluating unsatisfied network requests. In temporary DDS switch case, it
-                // takes some time to switch DDS after call end. We do not want to bring up network
-                // before switch completes.
-                sendMessageDelayed(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
-                        DataEvaluationReason.VOICE_CALL_ENDED),
-                        REEVALUATE_UNSATISFIED_NETWORK_REQUESTS_AFTER_CALL_END_DELAY_MILLIS);
-                break;
-            case EVENT_SLICE_CONFIG_CHANGED:
-                sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
-                        DataEvaluationReason.SLICE_CONFIG_CHANGED));
-                break;
-            case EVENT_PS_RESTRICT_ENABLED:
-                mPsRestricted = true;
-                break;
-            case EVENT_PS_RESTRICT_DISABLED:
-                mPsRestricted = false;
-                sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
-                        DataEvaluationReason.DATA_RESTRICTED_CHANGED));
-                break;
-            case EVENT_TAC_CHANGED:
-                // Re-evaluate unsatisfied network requests with some delays to let DataRetryManager
-                // clears the throttling record.
-                sendMessageDelayed(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
-                        DataEvaluationReason.TAC_CHANGED),
-                        REEVALUATE_UNSATISFIED_NETWORK_REQUESTS_TAC_CHANGED_DELAY_MILLIS);
-                break;
-            case EVENT_DATA_SERVICE_BINDING_CHANGED:
-                AsyncResult ar = (AsyncResult) msg.obj;
-                int transport = (int) ar.userObj;
-                boolean bound = (boolean) ar.result;
-                onDataServiceBindingChanged(transport, bound);
-                break;
-            case EVENT_SIM_STATE_CHANGED:
-                int simState = msg.arg1;
-                onSimStateChanged(simState);
-                break;
-            case EVENT_TEAR_DOWN_ALL_DATA_NETWORKS:
-                onTearDownAllDataNetworks(msg.arg1);
-                break;
-            case EVENT_REGISTER_DATA_NETWORK_CONTROLLER_CALLBACK:
-                mDataNetworkControllerCallbacks.add((DataNetworkControllerCallback) msg.obj);
-                break;
-            case EVENT_UNREGISTER_DATA_NETWORK_CONTROLLER_CALLBACK:
-                mDataNetworkControllerCallbacks.remove((DataNetworkControllerCallback) msg.obj);
-                break;
-            case EVENT_SUBSCRIPTION_CHANGED:
-                onSubscriptionChanged();
-                break;
-            case EVENT_SERVICE_STATE_CHANGED:
-                onServiceStateChanged();
-                break;
-            case EVENT_EMERGENCY_CALL_CHANGED:
-                if (mPhone.isInEcm()) {
-                    sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
-                            DataEvaluationReason.EMERGENCY_CALL_CHANGED));
-                } else {
-                    sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
-                            DataEvaluationReason.EMERGENCY_CALL_CHANGED));
-                }
-                break;
-            case EVENT_EVALUATE_PREFERRED_TRANSPORT:
-                onEvaluatePreferredTransport(msg.arg1);
-                break;
-            case EVENT_SUBSCRIPTION_PLANS_CHANGED:
-                SubscriptionPlan[] plans = (SubscriptionPlan[]) msg.obj;
-                log("Subscription plans changed: " + Arrays.toString(plans));
-                mSubscriptionPlans.clear();
-                mSubscriptionPlans.addAll(Arrays.asList(plans));
-                mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                        () -> callback.onSubscriptionPlanOverride()));
-                break;
-            case EVENT_SUBSCRIPTION_OVERRIDE:
-                int overrideMask = msg.arg1;
-                boolean override = msg.arg2 != 0;
-                int[] networkTypes = (int[]) msg.obj;
-
-                if (overrideMask == NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED) {
-                    log("Unmetered subscription override: override=" + override
-                            + ", networkTypes=" + Arrays.stream(networkTypes)
-                            .mapToObj(TelephonyManager::getNetworkTypeName)
-                            .collect(Collectors.joining(",")));
-                    for (int networkType : networkTypes) {
-                        if (override) {
-                            mUnmeteredOverrideNetworkTypes.add(networkType);
-                        } else {
-                            mUnmeteredOverrideNetworkTypes.remove(networkType);
-                        }
-                    }
-                    mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                            () -> callback.onSubscriptionPlanOverride()));
-                } else if (overrideMask == NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED) {
-                    log("Congested subscription override: override=" + override
-                            + ", networkTypes=" + Arrays.stream(networkTypes)
-                            .mapToObj(TelephonyManager::getNetworkTypeName)
-                            .collect(Collectors.joining(",")));
-                    for (int networkType : networkTypes) {
-                        if (override) {
-                            mCongestedOverrideNetworkTypes.add(networkType);
-                        } else {
-                            mCongestedOverrideNetworkTypes.remove(networkType);
-                        }
-                    }
-                    mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                            () -> callback.onSubscriptionPlanOverride()));
-                } else {
-                    loge("Unknown override mask: " + overrideMask);
-                }
-                break;
-            default:
-                loge("Unexpected event " + msg.what);
-        }
-    }
-
-    /**
-     * Add a network request, which is originated from the apps. Note that add a network request
-     * is not necessarily setting up a {@link DataNetwork}.
-     *
-     * @param networkRequest Network request
-     *
-     */
-    public void addNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) {
-        sendMessage(obtainMessage(EVENT_ADD_NETWORK_REQUEST, networkRequest));
-    }
-
-    /**
-     * Called when a network request arrives data network controller.
-     *
-     * @param networkRequest The network request.
-     */
-    private void onAddNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) {
-        // To detect IMS back-to-back release-request anomaly event
-        if (mLastImsOperationIsRelease) {
-            mLastImsOperationIsRelease = false;
-            if (Arrays.equals(
-                    mLastReleasedImsRequestCapabilities, networkRequest.getCapabilities())
-                    && mImsThrottleCounter.addOccurrence()) {
-                reportAnomaly(networkRequest.getNativeNetworkRequest().getRequestorPackageName()
-                                + " requested with same capabilities "
-                                + mImsThrottleCounter.getFrequencyString(),
-                        "ead6f8db-d2f2-4ed3-8da5-1d8560fe7daf");
-            }
-        }
-        if (!mAllNetworkRequestList.add(networkRequest)) {
-            loge("onAddNetworkRequest: Duplicate network request. " + networkRequest);
-            return;
-        }
-        log("onAddNetworkRequest: added " + networkRequest);
-        onSatisfyNetworkRequest(networkRequest);
-    }
-
-    /**
-     * Called when attempting to satisfy a network request. If after evaluation, the network
-     * request is determined that can be satisfied, the data network controller will establish
-     * the data network. If the network request can't be satisfied, it will remain in the
-     * unsatisfied pool until the environment changes.
-     *
-     * @param networkRequest The network request to be satisfied.
-     */
-    private void onSatisfyNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) {
-        if (networkRequest.getState() == TelephonyNetworkRequest.REQUEST_STATE_SATISFIED) {
-            logv("Already satisfied. " + networkRequest);
-            return;
-        }
-
-        // Check if there is any existing data network that can satisfy the network request, and
-        // attempt to attach if possible.
-        if (findCompatibleDataNetworkAndAttach(networkRequest)) {
-            return;
-        }
-
-        // If no data network can satisfy the requests, then start the evaluation process. Since
-        // all the requests in the list have the same capabilities, we can only evaluate one
-        // of them.
-        DataEvaluation evaluation = evaluateNetworkRequest(networkRequest,
-                DataEvaluationReason.NEW_REQUEST);
-        if (!evaluation.containsDisallowedReasons()) {
-            DataProfile dataProfile = evaluation.getCandidateDataProfile();
-            if (dataProfile != null) {
-                setupDataNetwork(dataProfile, null,
-                        evaluation.getDataAllowedReason());
-            }
-        } else if (evaluation.contains(DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK)) {
-            // Re-evaluate the existing data networks. If this request's priority is higher than
-            // the existing data network, the data network will be torn down so this request will
-            // get a chance to be satisfied.
-            sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
-                    DataEvaluationReason.SINGLE_DATA_NETWORK_ARBITRATION));
-        }
-    }
-
-    /**
-     * Attempt to attach a network request to an existing data network that can satisfy the
-     * network request.
-     *
-     * @param networkRequest The network request to attach.
-     *
-     * @return {@code false} if can't find the data network to to satisfy the network request.
-     * {@code true} if the network request has been scheduled to attach to the data network.
-     * If attach succeeds, the network request's state will be set to
-     * {@link TelephonyNetworkRequest#REQUEST_STATE_SATISFIED}. If failed,
-     * {@link #onAttachNetworkRequestsFailed(DataNetwork, NetworkRequestList)} will be invoked.
-     */
-    private boolean findCompatibleDataNetworkAndAttach(
-            @NonNull TelephonyNetworkRequest networkRequest) {
-        return findCompatibleDataNetworkAndAttach(new NetworkRequestList(networkRequest));
-    }
-
-    /**
-     * Attempt to attach a network request list to an existing data network that can satisfy all the
-     * network requests. Note this method does not support partial attach (i.e. Only attach some
-     * of the satisfiable requests to the network). All requests must be satisfied so they can be
-     * attached.
-     *
-     * @param requestList The network request list to attach. It is expected that every network
-     * request in this list has the same network capabilities.
-     *
-     * @return {@code false} if can't find the data network to to satisfy the network requests, even
-     * if only one of network request can't be satisfied. {@code true} if the network request
-     * has been scheduled to attach to the data network. If attach succeeds, the network request's
-     * state will be set to
-     * {@link TelephonyNetworkRequest#REQUEST_STATE_SATISFIED}. If failed,
-     * {@link #onAttachNetworkRequestsFailed(DataNetwork, NetworkRequestList)} will be invoked.
-     */
-    private boolean findCompatibleDataNetworkAndAttach(@NonNull NetworkRequestList requestList) {
-        // Try to find a data network that can satisfy all the network requests.
-        for (DataNetwork dataNetwork : mDataNetworkList) {
-            TelephonyNetworkRequest networkRequest = requestList.stream()
-                    .filter(request -> !request.canBeSatisfiedBy(
-                            dataNetwork.getNetworkCapabilities()))
-                    .findAny()
-                    .orElse(null);
-            // If found any request that can't be satisfied by this data network, continue to try
-            // next data network. We must find a data network that can satisfy all the provided
-            // network requests.
-            if (networkRequest != null) {
-                continue;
-            }
-
-            // When reaching here, it means this data network can satisfy all the network requests.
-            logv("Found a compatible data network " + dataNetwork + ". Attaching "
-                    + requestList);
-            return dataNetwork.attachNetworkRequests(requestList);
-        }
-        return false;
-    }
-
-    /**
-     * @return {@code true} if checking registration state is needed before setup data network.
-     * {@code false} indicates regardless in-service or out-of-service, setup data request will
-     * be sent down to the data service.
-     */
-    private boolean shouldCheckRegistrationState() {
-        // Always don't check registration state on non-DDS sub.
-        if (mPhone.getPhoneId() != PhoneSwitcher.getInstance().getPreferredDataPhoneId()) {
-            return false;
-        }
-
-        // TODO: Expand this method to support more scenarios if needed. On Android 12 or older
-        //  Android, auto attach is enabled by default. We dropped that support in Android 13 since
-        //  it's for the old 2G network. If there are other scenarios that we need to support
-        //  auto-attach, can implement the logic in this method.
-        return true;
-    }
-
-    /**
-     * @return {@code true} if the network only allows single data network at one time.
-     */
-    private boolean isOnlySingleDataNetworkAllowed(@TransportType int transport) {
-        if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) return false;
-
-        return mDataConfigManager.getNetworkTypesOnlySupportSingleDataNetwork()
-                .contains(getDataNetworkType(transport));
-    }
-
-    /**
-     * Evaluate if telephony frameworks would allow data setup for internet in current environment.
-     *
-     * @return {@code true} if the environment is allowed for internet data. {@code false} if not
-     * allowed. For example, if SIM is absent, or airplane mode is on, then data is NOT allowed.
-     * This API does not reflect the currently internet data network status. It's possible there is
-     * no internet data due to weak cellular signal or network side issue, but internet data is
-     * still allowed in this case.
-     */
-    public boolean isInternetDataAllowed() {
-        TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-                        .build(), mPhone);
-        DataEvaluation evaluation = evaluateNetworkRequest(internetRequest,
-                DataEvaluationReason.EXTERNAL_QUERY);
-        return !evaluation.containsDisallowedReasons();
-    }
-
-    /**
-     * @return {@code true} internet is unmetered.
-     */
-    public boolean isInternetUnmetered() {
-        return mDataNetworkList.stream()
-                .filter(dataNetwork -> !dataNetwork.isConnecting() && !dataNetwork.isDisconnected())
-                .filter(DataNetwork::isInternetSupported)
-                .allMatch(dataNetwork -> dataNetwork.getNetworkCapabilities()
-                        .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED)
-                        || dataNetwork.getNetworkCapabilities()
-                        .hasCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED));
-    }
-
-    /**
-     * @return List of the reasons why internet data is not allowed. An empty list if internet
-     * is allowed.
-     */
-    public @NonNull List<DataDisallowedReason> getInternetDataDisallowedReasons() {
-        TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-                        .build(), mPhone);
-        DataEvaluation evaluation = evaluateNetworkRequest(internetRequest,
-                DataEvaluationReason.EXTERNAL_QUERY);
-        return evaluation.getDataDisallowedReasons();
-    }
-
-    /**
-     * Evaluate a network request. The goal is to find a suitable {@link DataProfile} that can be
-     * used to setup the data network.
-     *
-     * @param networkRequest The network request to evaluate.
-     * @param reason The reason for evaluation.
-     * @return The data evaluation result.
-     */
-    private @NonNull DataEvaluation evaluateNetworkRequest(
-            @NonNull TelephonyNetworkRequest networkRequest, DataEvaluationReason reason) {
-        DataEvaluation evaluation = new DataEvaluation(reason);
-        int transport = mAccessNetworksManager.getPreferredTransportByNetworkCapability(
-                networkRequest.getApnTypeNetworkCapability());
-
-        // Bypass all checks for emergency network request.
-        if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
-            evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_REQUEST);
-            evaluation.setCandidateDataProfile(mDataProfileManager.getDataProfileForNetworkRequest(
-                    networkRequest, getDataNetworkType(transport)));
-            networkRequest.setEvaluation(evaluation);
-            log(evaluation.toString());
-            return evaluation;
-        }
-
-        int regState = getDataRegistrationState(transport);
-        if (shouldCheckRegistrationState()
-                && regState != NetworkRegistrationInfo.REGISTRATION_STATE_HOME
-                && regState != NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.NOT_IN_SERVICE);
-        }
-
-        // Check SIM state
-        if (mSimState != TelephonyManager.SIM_STATE_LOADED) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.SIM_NOT_READY);
-        }
-
-        // Check if carrier specific config is loaded or not.
-        if (!mDataConfigManager.isConfigCarrierSpecific()) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_CONFIG_NOT_READY);
-        }
-
-        // Check CS call state and see if concurrent voice/data is allowed.
-        if (mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE
-                && !mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
-            evaluation.addDataDisallowedReason(
-                    DataDisallowedReason.CONCURRENT_VOICE_DATA_NOT_ALLOWED);
-        }
-
-        // Check VoPS support
-        if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
-                && networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)) {
-            NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
-                    NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-            if (nri != null) {
-                DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
-                if (dsri != null && dsri.getVopsSupportInfo() != null
-                        && !dsri.getVopsSupportInfo().isVopsSupported()) {
-                    evaluation.addDataDisallowedReason(DataDisallowedReason.VOPS_NOT_SUPPORTED);
-                }
-            }
-        }
-
-        // Check if default data is selected.
-        if (!SubscriptionManager.isValidSubscriptionId(
-                SubscriptionManager.getDefaultDataSubscriptionId())) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.DEFAULT_DATA_UNSELECTED);
-        }
-
-        // Check if data roaming is disabled.
-        if (mServiceState.getDataRoaming() && !mDataSettingsManager.isDataRoamingEnabled()) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.ROAMING_DISABLED);
-        }
-
-        // Check if data is restricted by the network.
-        if (mPsRestricted) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_RESTRICTED_BY_NETWORK);
-        }
-
-        // Check if there are pending tear down all networks request.
-        if (mPendingTearDownAllNetworks) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.PENDING_TEAR_DOWN_ALL);
-        }
-
-        // Check if the request is preferred on cellular and radio is/will be turned off.
-        // We are using getDesiredPowerState() instead of isRadioOn() because we also don't want
-        // to setup data network when radio power is about to be turned off.
-        if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
-                && (!mPhone.getServiceStateTracker().getDesiredPowerState()
-                || mPhone.mCi.getRadioState() != TelephonyManager.RADIO_POWER_ON)) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.RADIO_POWER_OFF);
-        }
-
-        // Check if radio is/will be turned off by carrier.
-        if (!mPhone.getServiceStateTracker().getPowerStateFromCarrier()) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.RADIO_DISABLED_BY_CARRIER);
-        }
-
-        // Check if the underlying data service is bound.
-        if (!mDataServiceBound.get(transport)) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_SERVICE_NOT_READY);
-        }
-
-        // Check if device is in CDMA ECBM
-        if (mPhone.isInCdmaEcm()) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.CDMA_EMERGENCY_CALLBACK_MODE);
-        }
-
-        // Check if only one data network is allowed.
-        // Note any IMS network is ignored for the single-connection rule.
-        if (isOnlySingleDataNetworkAllowed(transport)
-                && !networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
-            // if exists non-IMS network
-            if (mDataNetworkList.stream()
-                    .anyMatch(dataNetwork -> !dataNetwork.getNetworkCapabilities()
-                                    .hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS))) {
-                evaluation.addDataDisallowedReason(
-                        DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK);
-            }
-        }
-
-        if (mDataSettingsManager.isDataInitialized()) {
-            if (!mDataSettingsManager.isDataEnabled(DataUtils.networkCapabilityToApnType(
-                    networkRequest.getApnTypeNetworkCapability()))) {
-                evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_DISABLED);
-            }
-        } else {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_SETTINGS_NOT_READY);
-        }
-
-        // Check whether to allow data in certain situations if data is disallowed for soft reasons
-        if (!evaluation.containsDisallowedReasons()) {
-            evaluation.addDataAllowedReason(DataAllowedReason.NORMAL);
-
-            if (!mDataSettingsManager.isDataEnabled()
-                    && networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
-                    && mDataSettingsManager.isMmsAlwaysAllowed()) {
-                // We reach here when data is disabled, but MMS always-allowed is enabled.
-                // (Note that isDataEnabled(ApnSetting.TYPE_MMS) returns true in this case, so it
-                // would not generate any soft disallowed reason. We need to explicitly handle it.)
-                evaluation.addDataAllowedReason(DataAllowedReason.MMS_REQUEST);
-            }
-        } else if (!evaluation.containsHardDisallowedReasons()) {
-            if ((mPhone.isInEmergencyCall() || mPhone.isInEcm())
-                    && networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
-                // Check if it's SUPL during emergency call.
-                evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_SUPL);
-            } else if (!networkRequest.hasCapability(
-                    NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
-                // Check if request is restricted.
-                evaluation.addDataAllowedReason(DataAllowedReason.RESTRICTED_REQUEST);
-            } else if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
-                // Check if request is unmetered (WiFi or unmetered APN).
-                evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE);
-            } else if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
-                if (!networkRequest.isMeteredRequest()) {
-                    evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE);
-                }
-            }
-        }
-
-        // Check if there is any compatible data profile
-        DataProfile dataProfile = mDataProfileManager
-                .getDataProfileForNetworkRequest(networkRequest, getDataNetworkType(transport));
-        if (dataProfile == null) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.NO_SUITABLE_DATA_PROFILE);
-        } else if (reason == DataEvaluationReason.NEW_REQUEST
-                && (mDataRetryManager.isAnySetupRetryScheduled(dataProfile, transport)
-                || mDataRetryManager.isSimilarNetworkRequestRetryScheduled(
-                        networkRequest, transport))) {
-            // If this is a new request, check if there is any retry already scheduled. For all
-            // other evaluation reasons, since they are all condition changes, so if there is any
-            // retry scheduled, we still want to go ahead and setup the data network.
-            evaluation.addDataDisallowedReason(DataDisallowedReason.RETRY_SCHEDULED);
-        } else if (mDataRetryManager.isDataProfileThrottled(dataProfile, transport)) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_THROTTLED);
-        }
-
-        if (!evaluation.containsDisallowedReasons()) {
-            evaluation.setCandidateDataProfile(dataProfile);
-        }
-
-        networkRequest.setEvaluation(evaluation);
-        // EXTERNAL_QUERY generates too many log spam.
-        if (reason != DataEvaluationReason.EXTERNAL_QUERY) {
-            log(evaluation.toString() + ", network type="
-                    + TelephonyManager.getNetworkTypeName(getDataNetworkType(transport))
-                    + ", reg state="
-                    + NetworkRegistrationInfo.registrationStateToString(
-                    getDataRegistrationState(transport))
-                    + ", " + networkRequest);
-        }
-        return evaluation;
-    }
-
-    /**
-     * @return The grouped unsatisfied network requests. The network requests that have the same
-     * network capabilities is grouped into one {@link NetworkRequestList}.
-     */
-    private @NonNull List<NetworkRequestList> getGroupedUnsatisfiedNetworkRequests() {
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-        for (TelephonyNetworkRequest networkRequest : mAllNetworkRequestList) {
-            if (networkRequest.getState() == TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED) {
-                networkRequestList.add(networkRequest);
-            }
-        }
-        return DataUtils.getGroupedNetworkRequestList(networkRequestList);
-    }
-
-    /**
-     * Called when it's needed to evaluate all unsatisfied network requests.
-     *
-     * @param reason The reason for evaluation.
-     */
-    private void onReevaluateUnsatisfiedNetworkRequests(@NonNull DataEvaluationReason reason) {
-        // First, try to group similar network request together.
-        List<NetworkRequestList> networkRequestLists = getGroupedUnsatisfiedNetworkRequests();
-        log("Re-evaluating " + networkRequestLists.stream().mapToInt(List::size).sum()
-                + " unsatisfied network requests in " + networkRequestLists.size()
-                + " groups, " + networkRequestLists.stream().map(
-                        requestList -> DataUtils.networkCapabilitiesToString(
-                                requestList.get(0).getCapabilities()))
-                .collect(Collectors.joining(", ")) + " due to " + reason);
-
-        // Second, see if any existing network can satisfy those network requests.
-        for (NetworkRequestList requestList : networkRequestLists) {
-            if (findCompatibleDataNetworkAndAttach(requestList)) {
-                continue;
-            }
-
-            // If no data network can satisfy the requests, then start the evaluation process. Since
-            // all the requests in the list have the same capabilities, we can only evaluate one
-            // of them.
-            DataEvaluation evaluation = evaluateNetworkRequest(requestList.get(0), reason);
-            if (!evaluation.containsDisallowedReasons()) {
-                DataProfile dataProfile = evaluation.getCandidateDataProfile();
-                if (dataProfile != null) {
-                    setupDataNetwork(dataProfile, null,
-                            evaluation.getDataAllowedReason());
-                }
-            }
-        }
-    }
-
-    /**
-     * Evaluate an existing data network to see if it is still allowed to exist. For example, if
-     * RAT changes from LTE to UMTS, an IMS data network is not allowed anymore. Or when SIM is
-     * removal, all data networks (except emergency) should be torn down.
-     *
-     * @param dataNetwork The data network to evaluate.
-     * @param reason The reason for evaluation.
-     *
-     * @return The data evaluation result.
-     */
-    private @NonNull DataEvaluation evaluateDataNetwork(@NonNull DataNetwork dataNetwork,
-            @NonNull DataEvaluationReason reason) {
-        DataEvaluation evaluation = new DataEvaluation(reason);
-        // Bypass all checks for emergency data network.
-        if (dataNetwork.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_EIMS)) {
-            evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_REQUEST);
-            log(evaluation.toString());
-            return evaluation;
-        }
-
-        // Check SIM state
-        if (mSimState != TelephonyManager.SIM_STATE_LOADED) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.SIM_NOT_READY);
-        }
-
-        // Check if device is in CDMA ECBM
-        if (mPhone.isInCdmaEcm()) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.CDMA_EMERGENCY_CALLBACK_MODE);
-        }
-
-        // Check if there are other network that has higher priority, and only single data network
-        // is allowed. Note IMS network is exempt from the single-connection rule.
-        if (isOnlySingleDataNetworkAllowed(dataNetwork.getTransport())
-                && !dataNetwork.getNetworkCapabilities()
-                .hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
-            // If there is network request that has higher priority than this data network, then
-            // tear down the network, regardless that network request is satisfied or not.
-            if (mAllNetworkRequestList.stream()
-                    .filter(request -> dataNetwork.getTransport()
-                            == mAccessNetworksManager.getPreferredTransportByNetworkCapability(
-                                    request.getApnTypeNetworkCapability()))
-                    .anyMatch(request -> request.getPriority() > dataNetwork.getPriority())) {
-                evaluation.addDataDisallowedReason(
-                        DataDisallowedReason.ONLY_ALLOWED_SINGLE_NETWORK);
-            } else {
-                log("evaluateDataNetwork: " + dataNetwork + " has the highest priority. "
-                        + "No need to tear down");
-            }
-        }
-
-        // If the data network is IMS that supports voice call, and has MMTEL request (client
-        // specified VoPS is required.)
-        if (dataNetwork.getAttachedNetworkRequestList().get(
-                new int[]{NetworkCapabilities.NET_CAPABILITY_MMTEL}) != null) {
-            // When reaching here, it means the network supports MMTEL, and also has MMTEL request
-            // attached to it.
-            if (!dataNetwork.shouldDelayImsTearDown()) {
-                if (dataNetwork.getTransport() == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
-                    NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
-                            NetworkRegistrationInfo.DOMAIN_PS,
-                            AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-                    if (nri != null) {
-                        DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
-                        if (dsri != null && dsri.getVopsSupportInfo() != null
-                                && !dsri.getVopsSupportInfo().isVopsSupported()) {
-                            evaluation.addDataDisallowedReason(
-                                    DataDisallowedReason.VOPS_NOT_SUPPORTED);
-                        }
-                    }
-                }
-            } else {
-                log("Ignored VoPS check due to delay IMS tear down until call ends.");
-            }
-        }
-
-        // Check if data is disabled
-        boolean dataDisabled = false;
-        if (!mDataSettingsManager.isDataEnabled()) {
-            dataDisabled = true;
-        }
-
-        // Check if data roaming is disabled
-        if (mServiceState.getDataRoaming() && !mDataSettingsManager.isDataRoamingEnabled()) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.ROAMING_DISABLED);
-        }
-
-        // Check if current data network type is allowed by the data profile. Use the lingering
-        // network type. Some data network is allowed to create on certain RATs, but can linger
-        // to extended RATs. For example, IMS is allowed to be created on LTE only, but can
-        // extend its life cycle to 3G.
-        int networkType = getDataNetworkType(dataNetwork.getTransport());
-        DataProfile dataProfile = dataNetwork.getDataProfile();
-        if (dataProfile.getApnSetting() != null) {
-            // Check if data is disabled for the APN type
-            dataDisabled = !mDataSettingsManager.isDataEnabled(DataUtils
-                    .networkCapabilityToApnType(DataUtils
-                            .getHighestPriorityNetworkCapabilityFromDataProfile(
-                                    mDataConfigManager, dataProfile)));
-
-            // Sometimes network temporarily OOS and network type becomes UNKNOWN. We don't
-            // tear down network in that case.
-            if (networkType != TelephonyManager.NETWORK_TYPE_UNKNOWN
-                    && !dataProfile.getApnSetting().canSupportLingeringNetworkType(networkType)) {
-                log("networkType=" + TelephonyManager.getNetworkTypeName(networkType)
-                        + ", networkTypeBitmask="
-                        + dataProfile.getApnSetting().getNetworkTypeBitmask()
-                        + ", lingeringNetworkTypeBitmask="
-                        + dataProfile.getApnSetting().getLingeringNetworkTypeBitmask());
-                evaluation.addDataDisallowedReason(
-                        DataDisallowedReason.DATA_NETWORK_TYPE_NOT_ALLOWED);
-            }
-        }
-
-        if (dataDisabled) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_DISABLED);
-        }
-
-        // Check if the data profile is still valid, sometimes the users can remove it from the APN
-        // editor. We use very loose check here because APN id can change after APN reset to
-        // default
-        if (mDataProfileManager.getDataProfile(
-                dataProfile.getApnSetting() != null
-                        ? dataProfile.getApnSetting().getApnName() : null,
-                dataProfile.getTrafficDescriptor()) == null) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_PROFILE_INVALID);
-        }
-
-        // If users switch preferred profile in APN editor, we need to tear down network.
-        if (dataNetwork.isInternetSupported()
-                && !mDataProfileManager.isDataProfilePreferred(dataProfile)
-                && mDataProfileManager.isAnyPreferredDataProfileExisting()) {
-            evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_PROFILE_NOT_PREFERRED);
-        }
-
-        // Check whether if there are any reason we should tear down the network.
-        if (!evaluation.containsDisallowedReasons()) {
-            // The data is allowed in the current condition.
-            evaluation.addDataAllowedReason(DataAllowedReason.NORMAL);
-        } else if (!evaluation.containsHardDisallowedReasons()) {
-            // If there are reasons we should tear down the network, check if those are hard reasons
-            // or soft reasons. In some scenarios, we can make exceptions if they are soft
-            // disallowed reasons.
-            if ((mPhone.isInEmergencyCall() || mPhone.isInEcm()) && dataNetwork.isEmergencySupl()) {
-                // Check if it's SUPL during emergency call.
-                evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_SUPL);
-            } else if (!dataNetwork.getNetworkCapabilities().hasCapability(
-                    NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
-                // Check if request is restricted
-                evaluation.addDataAllowedReason(DataAllowedReason.RESTRICTED_REQUEST);
-            } else if (dataNetwork.getTransport() == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
-                // Check if request is unmetered (WiFi or unmetered APN)
-                evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE);
-            } else {
-                boolean unmeteredNetwork = !mDataConfigManager.isAnyMeteredCapability(
-                        dataNetwork.getNetworkCapabilities()
-                                .getCapabilities(), mServiceState.getDataRoaming());
-                if (unmeteredNetwork) {
-                    evaluation.addDataAllowedReason(DataAllowedReason.UNMETERED_USAGE);
-                }
-            }
-        }
-
-        log("Evaluated " + dataNetwork + ", " + evaluation.toString());
-        return evaluation;
-    }
-
-    /**
-     * Called when needed to re-evaluate existing data networks and tear down networks if needed.
-     *
-     * @param reason The reason for this data evaluation.
-     */
-    private void onReevaluateExistingDataNetworks(@NonNull DataEvaluationReason reason) {
-        if (mDataNetworkList.isEmpty()) {
-            log("onReevaluateExistingDataNetworks: No existing data networks to re-evaluate.");
-            return;
-        }
-        log("Re-evaluating " + mDataNetworkList.size() + " existing data networks due to "
-                + reason);
-        for (DataNetwork dataNetwork : mDataNetworkList) {
-            if (dataNetwork.isConnecting() || dataNetwork.isConnected()) {
-                DataEvaluation dataEvaluation = evaluateDataNetwork(dataNetwork, reason);
-                if (dataEvaluation.containsDisallowedReasons()) {
-                    tearDownGracefully(dataNetwork, getTearDownReason(dataEvaluation));
-                }
-            }
-        }
-    }
-
-    /**
-     * Evaluate if it is allowed to handover the data network between IWLAN and cellular. Some
-     * carriers do not allow handover in certain conditions.
-     *
-     * @param dataNetwork The data network to be handover.
-     * @return The evaluation result.
-     *
-     * @see CarrierConfigManager#KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY
-     */
-    private @NonNull DataEvaluation evaluateDataNetworkHandover(@NonNull DataNetwork dataNetwork) {
-        DataEvaluation dataEvaluation = new DataEvaluation(DataEvaluationReason.DATA_HANDOVER);
-        if (!dataNetwork.isConnecting() && !dataNetwork.isConnected()) {
-            dataEvaluation.addDataDisallowedReason(DataDisallowedReason.ILLEGAL_STATE);
-            return dataEvaluation;
-        }
-
-        if (mDataRetryManager.isAnyHandoverRetryScheduled(dataNetwork)) {
-            dataEvaluation.addDataDisallowedReason(DataDisallowedReason.RETRY_SCHEDULED);
-            return dataEvaluation;
-        }
-
-        // If enhanced handover check is enabled, perform extra checks.
-        if (mDataConfigManager.isEnhancedIwlanHandoverCheckEnabled()) {
-            int targetTransport = DataUtils.getTargetTransport(dataNetwork.getTransport());
-            NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
-                    NetworkRegistrationInfo.DOMAIN_PS, targetTransport);
-            if (nri != null) {
-                // Check if OOS on target transport.
-                if (!nri.isInService()) {
-                    dataEvaluation.addDataDisallowedReason(DataDisallowedReason.NOT_IN_SERVICE);
-                }
-
-                // Check if VoPS is required, but the target transport is non-VoPS.
-                NetworkRequestList networkRequestList =
-                        dataNetwork.getAttachedNetworkRequestList();
-                if (networkRequestList.stream().anyMatch(request
-                        -> request.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL))) {
-                    DataSpecificRegistrationInfo dsri = nri.getDataSpecificInfo();
-                    // Check if the network is non-VoPS.
-                    if (dsri != null && dsri.getVopsSupportInfo() != null
-                            && !dsri.getVopsSupportInfo().isVopsSupported()) {
-                        dataEvaluation.addDataDisallowedReason(
-                                DataDisallowedReason.VOPS_NOT_SUPPORTED);
-                    }
-                }
-
-                if (dataEvaluation.containsDisallowedReasons()) {
-                    return dataEvaluation;
-                }
-            }
-        }
-
-        if (mDataConfigManager.isIwlanHandoverPolicyEnabled()) {
-            List<HandoverRule> handoverRules = mDataConfigManager.getHandoverRules();
-
-            int sourceAccessNetwork = DataUtils.networkTypeToAccessNetworkType(
-                    getDataNetworkType(dataNetwork.getTransport()));
-            int targetAccessNetwork = DataUtils.networkTypeToAccessNetworkType(
-                    getDataNetworkType(DataUtils.getTargetTransport(dataNetwork.getTransport())));
-            NetworkCapabilities capabilities = dataNetwork.getNetworkCapabilities();
-            log("evaluateDataNetworkHandover: "
-                    + "source=" + AccessNetworkType.toString(sourceAccessNetwork)
-                    + ", target=" + AccessNetworkType.toString(targetAccessNetwork)
-                    + ", ServiceState=" + mServiceState
-                    + ", capabilities=" + capabilities);
-
-            // Matching the rules by the configured order. Bail out if find first matching rule.
-            for (HandoverRule rule : handoverRules) {
-                // Check if the rule is only for roaming and we are not roaming. Use the real
-                // roaming state reported by modem instead of using the overridden roaming state.
-                if (rule.isOnlyForRoaming && !mServiceState.getDataRoamingFromRegistration()) {
-                    // If the rule is for roaming only, and the device is not roaming, then bypass
-                    // this rule.
-                    continue;
-                }
-
-                if (rule.sourceAccessNetworks.contains(sourceAccessNetwork)
-                        && rule.targetAccessNetworks.contains(targetAccessNetwork)) {
-                    // if no capability rule specified,
-                    // data network capability is considered matched.
-                    // otherwise, any capabilities overlap is also considered matched.
-                    if (rule.networkCapabilities.isEmpty()
-                            || rule.networkCapabilities.stream()
-                            .anyMatch(capabilities::hasCapability)) {
-                        log("evaluateDataNetworkHandover: Matched " + rule);
-                        if (rule.type == HandoverRule.RULE_TYPE_DISALLOWED) {
-                            dataEvaluation.addDataDisallowedReason(
-                                    DataDisallowedReason.NOT_ALLOWED_BY_POLICY);
-                        } else {
-                            dataEvaluation.addDataAllowedReason(DataAllowedReason.NORMAL);
-                        }
-                        log("evaluateDataNetworkHandover: " + dataEvaluation);
-                        return dataEvaluation;
-                    }
-                }
-            }
-            log("evaluateDataNetworkHandover: Did not find matching rule.");
-        } else {
-            log("evaluateDataNetworkHandover: IWLAN handover policy not enabled.");
-        }
-
-        // Allow handover by default if no rule is found/not enabled by config.
-        dataEvaluation.addDataAllowedReason(DataAllowedReason.NORMAL);
-        return dataEvaluation;
-    }
-
-    /**
-     * Get tear down reason from the evaluation result.
-     *
-     * @param dataEvaluation The evaluation result from
-     * {@link #evaluateDataNetwork(DataNetwork, DataEvaluationReason)}.
-     * @return The tear down reason.
-     */
-    private static @TearDownReason int getTearDownReason(@NonNull DataEvaluation dataEvaluation) {
-        if (dataEvaluation.containsDisallowedReasons()) {
-            switch (dataEvaluation.getDataDisallowedReasons().get(0)) {
-                case DATA_DISABLED:
-                    return DataNetwork.TEAR_DOWN_REASON_DATA_DISABLED;
-                case ROAMING_DISABLED:
-                    return DataNetwork.TEAR_DOWN_REASON_ROAMING_DISABLED;
-                case DEFAULT_DATA_UNSELECTED:
-                    return DataNetwork.TEAR_DOWN_REASON_DEFAULT_DATA_UNSELECTED;
-                case NOT_IN_SERVICE:
-                    return DataNetwork.TEAR_DOWN_REASON_NOT_IN_SERVICE;
-                case DATA_CONFIG_NOT_READY:
-                    return DataNetwork.TEAR_DOWN_REASON_DATA_CONFIG_NOT_READY;
-                case SIM_NOT_READY:
-                    return DataNetwork.TEAR_DOWN_REASON_SIM_REMOVAL;
-                case CONCURRENT_VOICE_DATA_NOT_ALLOWED:
-                    return DataNetwork.TEAR_DOWN_REASON_CONCURRENT_VOICE_DATA_NOT_ALLOWED;
-                case RADIO_POWER_OFF:
-                    return DataNetwork.TEAR_DOWN_REASON_AIRPLANE_MODE_ON;
-                case PENDING_TEAR_DOWN_ALL:
-                    return DataNetwork.TEAR_DOWN_REASON_PENDING_TEAR_DOWN_ALL;
-                case RADIO_DISABLED_BY_CARRIER:
-                    return DataNetwork.TEAR_DOWN_REASON_POWER_OFF_BY_CARRIER;
-                case DATA_SERVICE_NOT_READY:
-                    return DataNetwork.TEAR_DOWN_REASON_DATA_SERVICE_NOT_READY;
-                case NO_SUITABLE_DATA_PROFILE:
-                    return DataNetwork.TEAR_DOWN_REASON_NO_SUITABLE_DATA_PROFILE;
-                case DATA_NETWORK_TYPE_NOT_ALLOWED:
-                    return DataNetwork.TEAR_DOWN_REASON_RAT_NOT_ALLOWED;
-                case CDMA_EMERGENCY_CALLBACK_MODE:
-                    return DataNetwork.TEAR_DOWN_REASON_CDMA_EMERGENCY_CALLBACK_MODE;
-                case RETRY_SCHEDULED:
-                    return DataNetwork.TEAR_DOWN_REASON_RETRY_SCHEDULED;
-                case DATA_THROTTLED:
-                    return DataNetwork.TEAR_DOWN_REASON_DATA_THROTTLED;
-                case DATA_PROFILE_INVALID:
-                    return DataNetwork.TEAR_DOWN_REASON_DATA_PROFILE_INVALID;
-                case DATA_PROFILE_NOT_PREFERRED:
-                    return DataNetwork.TEAR_DOWN_REASON_DATA_PROFILE_NOT_PREFERRED;
-                case NOT_ALLOWED_BY_POLICY:
-                    return DataNetwork.TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY;
-                case ILLEGAL_STATE:
-                    return DataNetwork.TEAR_DOWN_REASON_ILLEGAL_STATE;
-                case VOPS_NOT_SUPPORTED:
-                    return DataNetwork.TEAR_DOWN_REASON_VOPS_NOT_SUPPORTED;
-                case ONLY_ALLOWED_SINGLE_NETWORK:
-                    return DataNetwork.TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK;
-            }
-        }
-        return 0;
-    }
-
-    /**
-     * Check whether a dataNetwork is actively capable of internet connection
-     * @param cid dataNetwork unique identifier
-     * @return true if the dataNetwork is connected and capable of internet connection
-     */
-    public boolean isInternetNetwork(int cid) {
-        for (DataNetwork dataNetwork : mDataNetworkList) {
-            if (dataNetwork.getId() == cid
-                    && dataNetwork.isConnected()
-                    && dataNetwork.getNetworkCapabilities()
-                    .hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * @return {@code true} if data is dormant.
-     */
-    private boolean isDataDormant() {
-        return mDataNetworkList.stream().anyMatch(
-                dataNetwork -> dataNetwork.getLinkStatus()
-                        == DataCallResponse.LINK_STATUS_DORMANT)
-                && mDataNetworkList.stream().noneMatch(
-                        dataNetwork -> dataNetwork.getLinkStatus()
-                                == DataCallResponse.LINK_STATUS_ACTIVE);
-    }
-
-    /**
-     * Update data activity.
-     */
-    private void updateDataActivity() {
-        int dataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
-        if (isDataDormant()) {
-            dataActivity = TelephonyManager.DATA_ACTIVITY_DORMANT;
-        } else if (mPhone.getLinkBandwidthEstimator() != null) {
-            dataActivity = mPhone.getLinkBandwidthEstimator().getDataActivity();
-        }
-
-        if (mDataActivity != dataActivity) {
-            logv("updateDataActivity: dataActivity="
-                    + DataUtils.dataActivityToString(dataActivity));
-            mDataActivity = dataActivity;
-            mPhone.notifyDataActivity();
-        }
-    }
-
-    /**
-     * Remove a network request, which is originated from the apps. Note that remove a network
-     * will not result in tearing down the network. The tear down request directly comes from
-     * {@link com.android.server.ConnectivityService} through
-     * {@link NetworkAgent#onNetworkUnwanted()}.
-     *
-     * @param networkRequest Network request
-     */
-    public void removeNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) {
-        sendMessage(obtainMessage(EVENT_REMOVE_NETWORK_REQUEST, networkRequest));
-    }
-
-    private void onRemoveNetworkRequest(@NonNull TelephonyNetworkRequest request) {
-        // The request generated from telephony network factory does not contain the information
-        // the original request has, for example, attached data network. We need to find the
-        // original one.
-        TelephonyNetworkRequest networkRequest = mAllNetworkRequestList.stream()
-                .filter(r -> r.equals(request))
-                .findFirst()
-                .orElse(null);
-        if (networkRequest == null || !mAllNetworkRequestList.remove(networkRequest)) {
-            loge("onRemoveNetworkRequest: Network request does not exist. " + networkRequest);
-            return;
-        }
-
-        if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
-            mImsThrottleCounter.addOccurrence();
-            mLastReleasedImsRequestCapabilities = networkRequest.getCapabilities();
-            mLastImsOperationIsRelease = true;
-        }
-
-        if (networkRequest.getAttachedNetwork() != null) {
-            networkRequest.getAttachedNetwork().detachNetworkRequest(networkRequest);
-        }
-        log("onRemoveNetworkRequest: Removed " + networkRequest);
-    }
-
-    /**
-     * Check if the network request is existing. Note this method is not thread safe so can be only
-     * called within the modules in {@link com.android.internal.telephony.data}.
-     *
-     * @param networkRequest Telephony network request to check.
-     * @return {@code true} if the network request exists.
-     */
-    public boolean isNetworkRequestExisting(@NonNull TelephonyNetworkRequest networkRequest) {
-        return mAllNetworkRequestList.contains(networkRequest);
-    }
-
-    /**
-     * Check if there are existing networks having the same interface name.
-     *
-     * @param interfaceName The interface name to check.
-     * @return {@code true} if the existing network has the same interface name.
-     */
-    public boolean isNetworkInterfaceExisting(@NonNull String interfaceName) {
-        return mDataNetworkList.stream()
-                .filter(dataNetwork -> !dataNetwork.isDisconnecting())
-                .anyMatch(dataNetwork -> interfaceName.equals(
-                        dataNetwork.getLinkProperties().getInterfaceName()));
-    }
-
-    /**
-     * Register for IMS feature registration state.
-     *
-     * @param subId The subscription index.
-     * @param imsFeature The IMS feature. Only {@link ImsFeature#FEATURE_MMTEL} and
-     * {@link ImsFeature#FEATURE_RCS} are supported at this point.
-     */
-    private void registerImsFeatureRegistrationState(int subId,
-            @ImsFeature.FeatureType int imsFeature) {
-        RegistrationManager.RegistrationCallback callback =
-                new RegistrationManager.RegistrationCallback() {
-                    @Override
-                    public void onRegistered(ImsRegistrationAttributes attributes) {
-                        log("IMS " + DataUtils.imsFeatureToString(imsFeature)
-                                + " registered. Attributes=" + attributes);
-                        mRegisteredImsFeatures.add(imsFeature);
-                    }
-
-                    @Override
-                    public void onUnregistered(ImsReasonInfo info) {
-                        log("IMS " + DataUtils.imsFeatureToString(imsFeature)
-                                + " deregistered. Info=" + info);
-                        mRegisteredImsFeatures.remove(imsFeature);
-                        evaluatePendingImsDeregDataNetworks();
-                    }
-                };
-
-        try {
-            // Use switch here as we can't make a generic callback registration logic because
-            // RcsManager does not implement RegistrationManager.
-            switch (imsFeature) {
-                case ImsFeature.FEATURE_MMTEL:
-                    mImsManager.getImsMmTelManager(subId).registerImsRegistrationCallback(
-                            DataNetworkController.this::post, callback);
-                    break;
-                case ImsFeature.FEATURE_RCS:
-                    mImsManager.getImsRcsManager(subId).registerImsRegistrationCallback(
-                            DataNetworkController.this::post, callback);
-                    break;
-            }
-
-            // Store the callback so that we can unregister in the future.
-            mImsFeatureRegistrationCallbacks.put(imsFeature, callback);
-            log("Successfully register " + DataUtils.imsFeatureToString(imsFeature)
-                    + " registration state. subId=" + subId);
-        } catch (ImsException e) {
-            loge("updateImsFeatureRegistrationStateListening: subId=" + subId
-                    + ", imsFeature=" + DataUtils.imsFeatureToString(imsFeature) + ", " + e);
-        }
-    }
-
-    /**
-     * Unregister IMS feature callback.
-     *
-     * @param subId The subscription index.
-     * @param imsFeature The IMS feature. Only {@link ImsFeature#FEATURE_MMTEL} and
-     * {@link ImsFeature#FEATURE_RCS} are supported at this point.
-     */
-    private void unregisterImsFeatureRegistrationState(int subId,
-            @ImsFeature.FeatureType int imsFeature) {
-        RegistrationManager.RegistrationCallback oldCallback =
-                mImsFeatureRegistrationCallbacks.get(imsFeature);
-        if (oldCallback != null) {
-            if (imsFeature == ImsFeature.FEATURE_MMTEL) {
-                mImsManager.getImsMmTelManager(subId)
-                        .unregisterImsRegistrationCallback(oldCallback);
-            } else if (imsFeature == ImsFeature.FEATURE_RCS) {
-                mImsManager.getImsRcsManager(subId)
-                        .unregisterImsRegistrationCallback(oldCallback);
-            }
-            log("Successfully unregistered " + DataUtils.imsFeatureToString(imsFeature)
-                    + " registration state. sudId=" + subId);
-            mImsFeatureRegistrationCallbacks.remove(imsFeature);
-        }
-    }
-
-    /**
-     * Register IMS state callback.
-     *
-     * @param subId Subscription index.
-     */
-    private void registerImsStateCallback(int subId) {
-        Function<Integer, ImsStateCallback> imsFeatureStateCallbackFactory =
-                imsFeature -> new ImsStateCallback() {
-                    @Override
-                    public void onUnavailable(int reason) {
-                        // Unregister registration state update when IMS service is unbound.
-                        unregisterImsFeatureRegistrationState(subId, imsFeature);
-                    }
-
-                    @Override
-                    public void onAvailable() {
-                        mImsFeaturePackageName.put(imsFeature, ImsResolver.getInstance()
-                                .getConfiguredImsServicePackageName(mPhone.getPhoneId(),
-                                        imsFeature));
-                        // Once IMS service is bound, register for registration state update.
-                        registerImsFeatureRegistrationState(subId, imsFeature);
-                    }
-
-                    @Override
-                    public void onError() {
-                    }
-                };
-
-        try {
-            ImsStateCallback callback = imsFeatureStateCallbackFactory
-                    .apply(ImsFeature.FEATURE_MMTEL);
-            mImsManager.getImsMmTelManager(subId).registerImsStateCallback(this::post,
-                    callback);
-            mImsStateCallbacks.put(ImsFeature.FEATURE_MMTEL, callback);
-            log("Successfully register MMTEL state on sub " + subId);
-
-            callback = imsFeatureStateCallbackFactory.apply(ImsFeature.FEATURE_RCS);
-            mImsManager.getImsRcsManager(subId).registerImsStateCallback(this::post, callback);
-            mImsStateCallbacks.put(ImsFeature.FEATURE_RCS, callback);
-            log("Successfully register RCS state on sub " + subId);
-        } catch (ImsException e) {
-            loge("Exception when registering IMS state callback. " + e);
-        }
-    }
-
-    /**
-     * Unregister IMS feature state callbacks.
-     *
-     * @param subId Subscription index.
-     */
-    private void unregisterImsStateCallbacks(int subId) {
-        ImsStateCallback callback = mImsStateCallbacks.get(ImsFeature.FEATURE_MMTEL);
-        if (callback != null) {
-            mImsManager.getImsMmTelManager(subId).unregisterImsStateCallback(callback);
-            mImsStateCallbacks.remove(ImsFeature.FEATURE_MMTEL);
-            log("Unregister MMTEL state on sub " + subId);
-        }
-
-        callback = mImsStateCallbacks.get(ImsFeature.FEATURE_RCS);
-        if (callback != null) {
-            mImsManager.getImsRcsManager(subId).unregisterImsStateCallback(callback);
-            mImsStateCallbacks.remove(ImsFeature.FEATURE_RCS);
-            log("Unregister RCS state on sub " + subId);
-        }
-    }
-
-    /** Called when subscription info changed. */
-    private void onSubscriptionChanged() {
-        if (mSubId != mPhone.getSubId()) {
-            log("onDataConfigUpdated: mSubId changed from " + mSubId + " to "
-                    + mPhone.getSubId());
-            if (isImsGracefulTearDownSupported()) {
-                if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
-                    registerImsStateCallback(mPhone.getSubId());
-                } else {
-                    unregisterImsStateCallbacks(mSubId);
-                }
-            }
-            mSubId = mPhone.getSubId();
-            updateSubscriptionPlans();
-        }
-    }
-
-    /**
-     * Called when data config was updated.
-     */
-    private void onDataConfigUpdated() {
-        log("onDataConfigUpdated: config is "
-                + (mDataConfigManager.isConfigCarrierSpecific() ? "" : "not ")
-                + "carrier specific. mSimState="
-                + SubscriptionInfoUpdater.simStateString(mSimState)
-                + ". DeviceConfig updated.");
-
-        updateAnomalySlidingWindowCounters();
-        updateNetworkRequestsPriority();
-        sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
-                DataEvaluationReason.DATA_CONFIG_CHANGED));
-    }
-
-    /**
-     * Update each network request's priority.
-     */
-    private void updateNetworkRequestsPriority() {
-        for (TelephonyNetworkRequest networkRequest : mAllNetworkRequestList) {
-            networkRequest.updatePriority();
-        }
-    }
-
-    /**
-     * Update the threshold of anomaly report counters
-     */
-    private void updateAnomalySlidingWindowCounters() {
-        mImsThrottleCounter = new SlidingWindowEventCounter(
-                mDataConfigManager.getAnomalyImsReleaseRequestThreshold().timeWindow,
-                mDataConfigManager.getAnomalyImsReleaseRequestThreshold().eventNumOccurrence);
-        mNetworkUnwantedCounter = new SlidingWindowEventCounter(
-                mDataConfigManager.getAnomalyNetworkUnwantedThreshold().timeWindow,
-                mDataConfigManager.getAnomalyNetworkUnwantedThreshold().eventNumOccurrence);
-        mSetupDataCallWwanFailureCounter = new SlidingWindowEventCounter(
-                mDataConfigManager.getAnomalySetupDataCallThreshold().timeWindow,
-                mDataConfigManager.getAnomalySetupDataCallThreshold().eventNumOccurrence);
-        mSetupDataCallWlanFailureCounter = new SlidingWindowEventCounter(
-                mDataConfigManager.getAnomalySetupDataCallThreshold().timeWindow,
-                mDataConfigManager.getAnomalySetupDataCallThreshold().eventNumOccurrence);
-    }
-
-    /**
-     * There have been several bugs where a RECONNECT loop kicks off where a data network
-     * is brought up, but connectivity service indicates that the network is unwanted so telephony
-     * tears down the network. But later telephony bring up the data network again and becomes an
-     * infinite loop. By the time we get the bug report it's too late because there have already
-     * been hundreds of bring up/tear down. This is meant to capture the issue when it first starts.
-     */
-    private void onTrackNetworkUnwanted() {
-        if (mNetworkUnwantedCounter.addOccurrence()) {
-            reportAnomaly("Network Unwanted called "
-                            + mNetworkUnwantedCounter.getFrequencyString(),
-                    "9f3bc55b-bfa6-4e26-afaa-5031426a66d3");
-        }
-    }
-
-    /**
-     * Find unsatisfied network requests that can be satisfied by the given data profile.
-     *
-     * @param dataProfile The data profile.
-     * @return The network requests list.
-     */
-    private @NonNull NetworkRequestList findSatisfiableNetworkRequests(
-            @NonNull DataProfile dataProfile) {
-        return new NetworkRequestList(mAllNetworkRequestList.stream()
-                .filter(request -> request.getState()
-                        == TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED)
-                .filter(request -> request.canBeSatisfiedBy(dataProfile))
-                .collect(Collectors.toList()));
-    }
-
-    /**
-     * Setup data network.
-     *
-     * @param dataProfile The data profile to setup the data network.
-     * @param dataSetupRetryEntry Data retry entry. {@code null} if this data network setup is not
-     * initiated by a data retry.
-     * @param allowedReason The reason that why setting up this data network is allowed.
-     */
-    private void setupDataNetwork(@NonNull DataProfile dataProfile,
-            @Nullable DataSetupRetryEntry dataSetupRetryEntry,
-            @NonNull DataAllowedReason allowedReason) {
-        log("onSetupDataNetwork: dataProfile=" + dataProfile + ", retryEntry="
-                + dataSetupRetryEntry + ", allowed reason=" + allowedReason + ", service state="
-                + mServiceState);
-        for (DataNetwork dataNetwork : mDataNetworkList) {
-            if (dataNetwork.getDataProfile().equals(dataProfile)) {
-                log("onSetupDataNetwork: Found existing data network " + dataNetwork
-                        + " has the same data profile.");
-                if (dataSetupRetryEntry != null) {
-                    dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
-                }
-                return;
-            }
-        }
-
-        NetworkRequestList networkRequestList = findSatisfiableNetworkRequests(dataProfile);
-
-        if (networkRequestList.isEmpty()) {
-            log("Can't find any unsatisfied network requests that can be satisfied by this data "
-                    + "profile.");
-            if (dataSetupRetryEntry != null) {
-                dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
-            }
-
-            return;
-        }
-
-        int transport = mAccessNetworksManager.getPreferredTransportByNetworkCapability(
-                networkRequestList.get(0).getApnTypeNetworkCapability());
-        logl("Creating data network on "
-                + AccessNetworkConstants.transportTypeToString(transport) + " with " + dataProfile
-                + ", and attaching " + networkRequestList.size() + " network requests to it.");
-
-        mDataNetworkList.add(new DataNetwork(mPhone, getLooper(), mDataServiceManagers,
-                dataProfile, networkRequestList, transport, allowedReason,
-                new DataNetworkCallback(this::post) {
-                    @Override
-                    public void onSetupDataFailed(@NonNull DataNetwork dataNetwork,
-                            @NonNull NetworkRequestList requestList, @DataFailureCause int cause,
-                            long retryDelayMillis) {
-                        if (dataSetupRetryEntry != null) {
-                            dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_FAILED);
-                        }
-                        DataNetworkController.this.onDataNetworkSetupFailed(
-                                dataNetwork, requestList, cause, retryDelayMillis);
-                    }
-
-                    @Override
-                    public void onConnected(@NonNull DataNetwork dataNetwork) {
-                        if (dataSetupRetryEntry != null) {
-                            dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_SUCCEEDED);
-                        }
-                        DataNetworkController.this.onDataNetworkConnected(dataNetwork);
-                    }
-
-                    @Override
-                    public void onAttachFailed(@NonNull DataNetwork dataNetwork,
-                            @NonNull NetworkRequestList requestList) {
-                        DataNetworkController.this.onAttachNetworkRequestsFailed(
-                                dataNetwork, requestList);
-                    }
-
-                    @Override
-                    public void onValidationStatusChanged(@NonNull DataNetwork dataNetwork,
-                            @ValidationStatus int status, @Nullable Uri redirectUri) {
-                        DataNetworkController.this.onDataNetworkValidationStatusChanged(
-                                dataNetwork, status, redirectUri);
-                    }
-
-                    @Override
-                    public void onSuspendedStateChanged(@NonNull DataNetwork dataNetwork,
-                            boolean suspended) {
-                        DataNetworkController.this.onDataNetworkSuspendedStateChanged(
-                                dataNetwork, suspended);
-                    }
-
-                    @Override
-                    public void onDisconnected(@NonNull DataNetwork dataNetwork,
-                            @DataFailureCause int cause) {
-                        DataNetworkController.this.onDataNetworkDisconnected(
-                                dataNetwork, cause);
-                    }
-
-                    @Override
-                    public void onHandoverSucceeded(@NonNull DataNetwork dataNetwork) {
-                        DataNetworkController.this.onDataNetworkHandoverSucceeded(dataNetwork);
-                    }
-
-                    @Override
-                    public void onHandoverFailed(@NonNull DataNetwork dataNetwork,
-                            @DataFailureCause int cause, long retryDelayMillis,
-                            @HandoverFailureMode int handoverFailureMode) {
-                        DataNetworkController.this.onDataNetworkHandoverFailed(
-                                dataNetwork, cause, retryDelayMillis, handoverFailureMode);
-                    }
-
-                    @Override
-                    public void onLinkStatusChanged(@NonNull DataNetwork dataNetwork,
-                            @LinkStatus int linkStatus) {
-                        DataNetworkController.this.onLinkStatusChanged(dataNetwork, linkStatus);
-                    }
-
-                    @Override
-                    public void onPcoDataChanged(@NonNull DataNetwork dataNetwork) {
-                        DataNetworkController.this.onPcoDataChanged(dataNetwork);
-                    }
-
-                    @Override
-                    public void onNetworkCapabilitiesChanged(@NonNull DataNetwork dataNetwork) {
-                        DataNetworkController.this.onNetworkCapabilitiesChanged(dataNetwork);
-                    }
-
-                    @Override
-                    public void onTrackNetworkUnwanted(@NonNull DataNetwork dataNetwork) {
-                        DataNetworkController.this.onTrackNetworkUnwanted();
-                    }
-                }
-        ));
-        if (!mAnyDataNetworkExisting) {
-            mAnyDataNetworkExisting = true;
-            mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                    () -> callback.onAnyDataNetworkExistingChanged(mAnyDataNetworkExisting)));
-        }
-    }
-
-    /**
-     * Called when setup data network failed.
-     *
-     * @param dataNetwork The data network.
-     * @param requestList The network requests attached to the data network.
-     * @param cause The fail cause
-     * @param retryDelayMillis The retry timer suggested by the network/data service.
-     */
-    private void onDataNetworkSetupFailed(@NonNull DataNetwork dataNetwork,
-            @NonNull NetworkRequestList requestList, @DataFailureCause int cause,
-            long retryDelayMillis) {
-        logl("onDataNetworkSetupDataFailed: " + dataNetwork + ", cause="
-                + DataFailCause.toString(cause) + ", retryDelayMillis=" + retryDelayMillis + "ms.");
-        mDataNetworkList.remove(dataNetwork);
-        trackSetupDataCallFailure(dataNetwork.getTransport());
-        if (mAnyDataNetworkExisting && mDataNetworkList.isEmpty()) {
-            mPendingTearDownAllNetworks = false;
-            mAnyDataNetworkExisting = false;
-            mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                    () -> callback.onAnyDataNetworkExistingChanged(mAnyDataNetworkExisting)));
-        }
-
-        requestList.removeIf(request -> !mAllNetworkRequestList.contains(request));
-        if (requestList.isEmpty()) {
-            log("onDataNetworkSetupFailed: All requests have been released. "
-                    + "Will not evaluate retry.");
-            return;
-        }
-
-        // Data retry manager will determine if retry is needed. If needed, retry will be scheduled.
-        mDataRetryManager.evaluateDataSetupRetry(dataNetwork.getDataProfile(),
-                dataNetwork.getTransport(), requestList, cause, retryDelayMillis);
-    }
-
-    /**
-     * Track the frequency of setup data failure on each
-     * {@link AccessNetworkConstants.TransportType} data service.
-     *
-     * @param transport The transport of the data service.
-     */
-    private void trackSetupDataCallFailure(@TransportType int transport) {
-        switch (transport) {
-            case AccessNetworkConstants.TRANSPORT_TYPE_WWAN:
-                // Skip when poor signal strength
-                if (mPhone.getSignalStrength().getLevel()
-                        <= CellSignalStrength.SIGNAL_STRENGTH_POOR) {
-                    return;
-                }
-                if (mSetupDataCallWwanFailureCounter.addOccurrence()) {
-                    reportAnomaly("RIL fails setup data call request "
-                                    + mSetupDataCallWwanFailureCounter.getFrequencyString(),
-                            "e6a98b97-9e34-4977-9a92-01d52a6691f6");
-                }
-                break;
-            case AccessNetworkConstants.TRANSPORT_TYPE_WLAN:
-                if (mSetupDataCallWlanFailureCounter.addOccurrence()) {
-                    reportAnomaly("IWLAN data service fails setup data call request "
-                                    + mSetupDataCallWlanFailureCounter.getFrequencyString(),
-                            "e2248d8b-d55f-42bd-871c-0cfd80c3ddd1");
-                }
-                break;
-            default:
-                loge("trackSetupDataCallFailure: INVALID transport.");
-        }
-    }
-
-    /**
-     * Trigger the anomaly report with the specified UUID.
-     *
-     * @param anomalyMsg Description of the event
-     * @param uuid UUID associated with that event
-     */
-    private void reportAnomaly(@NonNull String anomalyMsg, @NonNull String uuid) {
-        logl(anomalyMsg);
-        AnomalyReporter.reportAnomaly(UUID.fromString(uuid), anomalyMsg, mPhone.getCarrierId());
-    }
-
-    /**
-     * Called when data network is connected.
-     *
-     * @param dataNetwork The data network.
-     */
-    private void onDataNetworkConnected(@NonNull DataNetwork dataNetwork) {
-        logl("onDataNetworkConnected: " + dataNetwork);
-        mPreviousConnectedDataNetworkList.add(0, dataNetwork);
-        // Preserve the connected data networks for debugging purposes.
-        if (mPreviousConnectedDataNetworkList.size() > MAX_HISTORICAL_CONNECTED_DATA_NETWORKS) {
-            mPreviousConnectedDataNetworkList.remove(MAX_HISTORICAL_CONNECTED_DATA_NETWORKS);
-        }
-
-        updateOverallInternetDataState();
-
-        if (dataNetwork.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_IMS)) {
-            logl("IMS data state changed from "
-                    + TelephonyUtils.dataStateToString(mImsDataNetworkState) + " to CONNECTED.");
-            mImsDataNetworkState = TelephonyManager.DATA_CONNECTED;
-        }
-    }
-
-    /**
-     * Called when needed to retry data setup.
-     *
-     * @param dataSetupRetryEntry The data setup retry entry scheduled by {@link DataRetryManager}.
-     */
-    private void onDataNetworkSetupRetry(@NonNull DataSetupRetryEntry dataSetupRetryEntry) {
-        // The request might be already removed before retry happens. Remove them from the list
-        // if that's the case. Copy the list first. We don't want to remove the requests from
-        // the retry entry. They can be later used to determine what kind of retry it is.
-        NetworkRequestList requestList = new NetworkRequestList(
-                dataSetupRetryEntry.networkRequestList);
-        requestList.removeIf(request -> !mAllNetworkRequestList.contains(request));
-        if (requestList.isEmpty()) {
-            loge("onDataNetworkSetupRetry: Request list is empty. Abort retry.");
-            dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
-            return;
-        }
-        TelephonyNetworkRequest telephonyNetworkRequest = requestList.get(0);
-
-        int networkCapability = telephonyNetworkRequest.getApnTypeNetworkCapability();
-        int preferredTransport = mAccessNetworksManager.getPreferredTransportByNetworkCapability(
-                networkCapability);
-        if (preferredTransport != dataSetupRetryEntry.transport) {
-            log("Cannot re-satisfy " + telephonyNetworkRequest + " on "
-                    + AccessNetworkConstants.transportTypeToString(dataSetupRetryEntry.transport)
-                    + ". The preferred transport has switched to "
-                    + AccessNetworkConstants.transportTypeToString(preferredTransport)
-                    + ". " + dataSetupRetryEntry);
-            // Cancel the retry since the preferred transport has already changed, but then
-            // re-evaluate the unsatisfied network requests again so the new network can be brought
-            // up on the new target transport later.
-            dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
-            sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
-                    DataEvaluationReason.PREFERRED_TRANSPORT_CHANGED));
-            return;
-        }
-
-        DataEvaluation evaluation = evaluateNetworkRequest(
-                telephonyNetworkRequest, DataEvaluationReason.DATA_RETRY);
-        if (!evaluation.containsDisallowedReasons()) {
-            DataProfile dataProfile = dataSetupRetryEntry.dataProfile;
-            if (dataProfile == null) {
-                dataProfile = evaluation.getCandidateDataProfile();
-            }
-            if (dataProfile != null) {
-                setupDataNetwork(dataProfile, dataSetupRetryEntry,
-                        evaluation.getDataAllowedReason());
-            } else {
-                loge("onDataNetworkSetupRetry: Not able to find a suitable data profile to retry.");
-                dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_FAILED);
-            }
-        } else {
-            dataSetupRetryEntry.setState(DataRetryEntry.RETRY_STATE_FAILED);
-        }
-    }
-
-    /**
-     * Called when needed to retry data network handover.
-     *
-     * @param dataHandoverRetryEntry The handover entry.
-     */
-    private void onDataNetworkHandoverRetry(
-            @NonNull DataHandoverRetryEntry dataHandoverRetryEntry) {
-        DataNetwork dataNetwork = dataHandoverRetryEntry.dataNetwork;
-        if (!mDataNetworkList.contains(dataNetwork)) {
-            log("onDataNetworkHandoverRetry: " + dataNetwork + " no longer exists.");
-            dataHandoverRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
-            return;
-        }
-
-        if (!dataNetwork.isConnected()) {
-            log("onDataNetworkHandoverRetry: " + dataNetwork + " is not in the right state.");
-            dataHandoverRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
-            return;
-        }
-
-        int preferredTransport = mAccessNetworksManager.getPreferredTransportByNetworkCapability(
-                dataNetwork.getApnTypeNetworkCapability());
-        if (dataNetwork.getTransport() == preferredTransport) {
-            log("onDataNetworkHandoverRetry: " + dataNetwork + " is already on the preferred "
-                    + "transport " + AccessNetworkConstants.transportTypeToString(
-                            preferredTransport) + ".");
-            dataHandoverRetryEntry.setState(DataRetryEntry.RETRY_STATE_CANCELLED);
-            return;
-        }
-
-        logl("Start handover " + dataNetwork + " to "
-                + AccessNetworkConstants.transportTypeToString(preferredTransport)
-                + ", " + dataHandoverRetryEntry);
-        dataNetwork.startHandover(preferredTransport, dataHandoverRetryEntry);
-    }
-
-    /**
-     * Called when data network validation status changed.
-     *
-     * @param status one of {@link NetworkAgent#VALIDATION_STATUS_VALID} or
-     * {@link NetworkAgent#VALIDATION_STATUS_NOT_VALID}.
-     * @param redirectUri 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}.
-     *
-     * @param dataNetwork The data network.
-     */
-    private void onDataNetworkValidationStatusChanged(@NonNull DataNetwork dataNetwork,
-            @ValidationStatus int status, @Nullable Uri redirectUri) {
-        log("onDataNetworkValidationStatusChanged: " + dataNetwork + ", validation status="
-                + DataUtils.validationStatusToString(status)
-                + (redirectUri != null ? ", " + redirectUri : ""));
-        if (!TextUtils.isEmpty(redirectUri.toString())) {
-            Intent intent = new Intent(TelephonyManager.ACTION_CARRIER_SIGNAL_REDIRECTED);
-            intent.putExtra(TelephonyManager.EXTRA_REDIRECTION_URL, redirectUri);
-            mPhone.getCarrierSignalAgent().notifyCarrierSignalReceivers(intent);
-            log("Notify carrier signal receivers with redirectUri: " + redirectUri);
-        }
-
-        if (status != NetworkAgent.VALIDATION_STATUS_VALID
-                && status != NetworkAgent.VALIDATION_STATUS_NOT_VALID) {
-            loge("Invalid validation status " + status + " received.");
-            return;
-        }
-
-        if (!mDataSettingsManager.isRecoveryOnBadNetworkEnabled()) {
-            log("Ignore data network validation status changed because "
-                    + "data stall recovery is disabled.");
-            return;
-        }
-
-        if (dataNetwork.isInternetSupported()) {
-            if (status == NetworkAgent.VALIDATION_STATUS_NOT_VALID
-                    && (dataNetwork.getCurrentState() == null || dataNetwork.isDisconnected())) {
-                log("Ignoring invalid validation status for disconnected DataNetwork");
-                return;
-            }
-            mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                    () -> callback.onInternetDataNetworkValidationStatusChanged(status)));
-        }
-    }
-
-    /**
-     * Called when data network suspended state changed.
-     *
-     * @param dataNetwork The data network.
-     * @param suspended {@code true} if data is suspended.
-     */
-    private void onDataNetworkSuspendedStateChanged(@NonNull DataNetwork dataNetwork,
-            boolean suspended) {
-        updateOverallInternetDataState();
-
-        if (dataNetwork.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_IMS)) {
-            logl("IMS data state changed from "
-                    + TelephonyUtils.dataStateToString(mImsDataNetworkState) + " to "
-                    + (suspended ? "SUSPENDED" : "CONNECTED"));
-            mImsDataNetworkState = suspended
-                    ? TelephonyManager.DATA_SUSPENDED : TelephonyManager.DATA_CONNECTED;
-        }
-    }
-
-    /**
-     * Called when data network disconnected.
-     *
-     * @param dataNetwork The data network.
-     * @param cause The disconnect cause.
-     */
-    private void onDataNetworkDisconnected(@NonNull DataNetwork dataNetwork,
-            @DataFailureCause int cause) {
-        logl("onDataNetworkDisconnected: " + dataNetwork + ", cause="
-                + DataFailCause.toString(cause) + "(" + cause + ")");
-        mDataNetworkList.remove(dataNetwork);
-        mPendingImsDeregDataNetworks.remove(dataNetwork);
-        mDataRetryManager.cancelPendingHandoverRetry(dataNetwork);
-        updateOverallInternetDataState();
-
-        if (dataNetwork.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_IMS)) {
-            logl("IMS data state changed from "
-                    + TelephonyUtils.dataStateToString(mImsDataNetworkState) + " to DISCONNECTED.");
-            mImsDataNetworkState = TelephonyManager.DATA_DISCONNECTED;
-        }
-
-        if (mAnyDataNetworkExisting && mDataNetworkList.isEmpty()) {
-            log("All data networks disconnected now.");
-            mPendingTearDownAllNetworks = false;
-            mAnyDataNetworkExisting = false;
-            mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                    () -> callback.onAnyDataNetworkExistingChanged(mAnyDataNetworkExisting)));
-        }
-
-        // Sometimes network was unsolicitedly reported lost for reasons. We should re-evaluate
-        // and see if data network can be re-established again.
-        sendMessageDelayed(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
-                DataEvaluationReason.RETRY_AFTER_DISCONNECTED),
-                mDataConfigManager.getRetrySetupAfterDisconnectMillis());
-    }
-
-    /**
-     * Called when handover between IWLAN and cellular network succeeded.
-     *
-     * @param dataNetwork The data network.
-     */
-    private void onDataNetworkHandoverSucceeded(@NonNull DataNetwork dataNetwork) {
-        logl("Handover successfully. " + dataNetwork + " to " + AccessNetworkConstants
-                .transportTypeToString(dataNetwork.getTransport()));
-        // The preferred transport might be changed when handover was in progress. We need to
-        // evaluate again to make sure we are not out-of-sync with the input from access network
-        // manager.
-        sendMessage(obtainMessage(EVENT_EVALUATE_PREFERRED_TRANSPORT,
-                dataNetwork.getApnTypeNetworkCapability(), 0));
-
-        // There might be network we didn't tear down in the last evaluation due to handover in
-        // progress. We should evaluate again.
-        sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
-                DataEvaluationReason.DATA_HANDOVER));
-    }
-
-    /**
-     * Called when data network handover between IWLAN and cellular network failed.
-     *
-     * @param dataNetwork The data network.
-     * @param cause The fail cause.
-     * @param retryDelayMillis Network suggested retry time in milliseconds.
-     * {@link Long#MAX_VALUE} indicates data retry should not occur.
-     * {@link DataCallResponse#RETRY_DURATION_UNDEFINED} indicates network did not suggest any
-     * retry duration.
-     * @param handoverFailureMode The handover failure mode that determine the behavior of
-     * how frameworks should handle the handover failure.
-     */
-    private void onDataNetworkHandoverFailed(@NonNull DataNetwork dataNetwork,
-            @DataFailureCause int cause, long retryDelayMillis,
-            @HandoverFailureMode int handoverFailureMode) {
-        logl("Handover failed. " + dataNetwork + ", cause=" + DataFailCause.toString(cause)
-                + ", retryDelayMillis=" + retryDelayMillis + "ms, handoverFailureMode="
-                + DataCallResponse.failureModeToString(handoverFailureMode));
-        // There might be network we didn't tear down in the last evaluation due to handover in
-        // progress. We should evaluate again.
-        sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
-                DataEvaluationReason.DATA_HANDOVER));
-
-        if (dataNetwork.getAttachedNetworkRequestList().isEmpty()) {
-            log("onDataNetworkHandoverFailed: No network requests attached to " + dataNetwork
-                    + ". No need to retry since the network will be torn down soon.");
-            return;
-        }
-
-        if (handoverFailureMode == DataCallResponse.HANDOVER_FAILURE_MODE_DO_FALLBACK
-                || (handoverFailureMode == DataCallResponse.HANDOVER_FAILURE_MODE_LEGACY
-                && cause == DataFailCause.HANDOFF_PREFERENCE_CHANGED)) {
-            // Don't retry handover anymore. Give QNS some time to switch the preferred transport
-            // to the original one, but we should re-evaluate the preferred transport again to
-            // make sure QNS does change it back, if not, we still need to perform handover at that
-            // time.
-            sendMessageDelayed(obtainMessage(EVENT_EVALUATE_PREFERRED_TRANSPORT,
-                    dataNetwork.getApnTypeNetworkCapability(), 0),
-                    REEVALUATE_PREFERRED_TRANSPORT_DELAY_MILLIS);
-        } else if (handoverFailureMode == DataCallResponse
-                .HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_SETUP_NORMAL || handoverFailureMode
-                == DataCallResponse.HANDOVER_FAILURE_MODE_LEGACY) {
-            int targetTransport = DataUtils.getTargetTransport(dataNetwork.getTransport());
-            mDataRetryManager.evaluateDataSetupRetry(dataNetwork.getDataProfile(), targetTransport,
-                    dataNetwork.getAttachedNetworkRequestList(), cause, retryDelayMillis);
-            // Tear down the data network on source transport. Retry manager will schedule
-            // setup a new data network on the target transport.
-            tearDownGracefully(dataNetwork, DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED);
-        } else {
-            mDataRetryManager.evaluateDataHandoverRetry(dataNetwork, cause, retryDelayMillis);
-        }
-    }
-
-    /**
-     * Called when network requests failed to attach to the data network.
-     *
-     * @param dataNetwork The data network that can't be attached.
-     * @param requestList The requests failed to attach to the network.
-     */
-    private void onAttachNetworkRequestsFailed(@NonNull DataNetwork dataNetwork,
-            @NonNull NetworkRequestList requestList) {
-        log("Failed to attach " + requestList + " to " + dataNetwork);
-    }
-
-    /**
-     * Called when data stall occurs and needed to tear down / setup a new data network for
-     * internet. This event is from {@link DataStallRecoveryManager}.
-     */
-    private void onDataStallReestablishInternet() {
-        log("onDataStallReestablishInternet: Tear down data networks that support internet.");
-        // Tear down all data networks that support internet. After data disconnected, unsatisfied
-        // network requests will be re-evaluate again and data network controller will attempt to
-        // setup data networks to satisfy them.
-        mDataNetworkList.stream()
-                .filter(DataNetwork::isInternetSupported)
-                .forEach(dataNetwork -> dataNetwork.tearDown(
-                        DataNetwork.TEAR_DOWN_REASON_DATA_STALL));
-    }
-
-    /**
-     * Called when data service binding changed.
-     *
-     * @param transport The transport of the changed data service.
-     * @param bound {@code true} if data service is bound.
-     */
-    private void onDataServiceBindingChanged(@TransportType int transport, boolean bound) {
-        log("onDataServiceBindingChanged: " + AccessNetworkConstants
-                .transportTypeToString(transport) + " data service is "
-                + (bound ? "bound." : "unbound."));
-        if (bound) {
-            mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                    () -> callback.onDataServiceBound(transport)));
-        }
-        mDataServiceBound.put(transport, bound);
-    }
-
-    /**
-     * Called when SIM is absent.
-     */
-    private void onSimAbsent() {
-        log("onSimAbsent");
-        sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
-                DataEvaluationReason.SIM_REMOVAL));
-    }
-
-    /**
-     * Called when SIM state changes.
-     *
-     * @param simState SIM state. (Note this is mixed with card state and application state.)
-     */
-    private void onSimStateChanged(@SimState int simState) {
-        log("onSimStateChanged: state=" + SubscriptionInfoUpdater.simStateString(simState));
-        if (mSimState != simState) {
-            mSimState = simState;
-            if (simState == TelephonyManager.SIM_STATE_ABSENT) {
-                onSimAbsent();
-            } else if (simState == TelephonyManager.SIM_STATE_LOADED) {
-                sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
-                        DataEvaluationReason.SIM_LOADED));
-            }
-        }
-    }
-
-    /**
-     * Called when needed to evaluate the preferred transport for certain capability.
-     *
-     * @param capability The network capability to evaluate.
-     */
-    private void onEvaluatePreferredTransport(@NetCapability int capability) {
-        int preferredTransport = mAccessNetworksManager
-                .getPreferredTransportByNetworkCapability(capability);
-        log("onEvaluatePreferredTransport: " + DataUtils.networkCapabilityToString(capability)
-                + " preferred on "
-                + AccessNetworkConstants.transportTypeToString(preferredTransport));
-        for (DataNetwork dataNetwork : mDataNetworkList) {
-            if (dataNetwork.getApnTypeNetworkCapability() == capability) {
-                // Check if the data network's current transport is different than from the
-                // preferred transport. If it's different, then handover is needed.
-                if (dataNetwork.getTransport() == preferredTransport) {
-                    log("onEvaluatePreferredTransport:" + dataNetwork + " already on "
-                            + AccessNetworkConstants.transportTypeToString(preferredTransport));
-                    continue;
-                }
-
-                // If handover is ongoing, ignore the preference change for now. After handover
-                // succeeds or fails, preferred transport will be re-evaluate again. Handover will
-                // be performed at that time if needed.
-                if (dataNetwork.isHandoverInProgress()) {
-                    log("onEvaluatePreferredTransport: " + dataNetwork + " handover in progress.");
-                    continue;
-                }
-
-                DataEvaluation dataEvaluation = evaluateDataNetworkHandover(dataNetwork);
-                log("onEvaluatePreferredTransport: " + dataEvaluation + ", " + dataNetwork);
-                if (!dataEvaluation.containsDisallowedReasons()) {
-                    logl("Start handover " + dataNetwork + " to "
-                            + AccessNetworkConstants.transportTypeToString(preferredTransport));
-                    dataNetwork.startHandover(preferredTransport, null);
-                } else if (dataEvaluation.containsAny(DataDisallowedReason.NOT_ALLOWED_BY_POLICY,
-                        DataDisallowedReason.NOT_IN_SERVICE,
-                        DataDisallowedReason.VOPS_NOT_SUPPORTED)) {
-                    logl("onEvaluatePreferredTransport: Handover not allowed. Tear "
-                            + "down " + dataNetwork + " so a new network can be setup on "
-                            + AccessNetworkConstants.transportTypeToString(preferredTransport)
-                            + ".");
-                    tearDownGracefully(dataNetwork,
-                            DataNetwork.TEAR_DOWN_REASON_HANDOVER_NOT_ALLOWED);
-                } else if (dataEvaluation.containsAny(DataDisallowedReason.ILLEGAL_STATE,
-                        DataDisallowedReason.RETRY_SCHEDULED)) {
-                    logl("onEvaluatePreferredTransport: Handover not allowed. " + dataNetwork
-                            + " will remain on " + AccessNetworkConstants.transportTypeToString(
-                                    dataNetwork.getTransport()));
-                } else {
-                    loge("onEvaluatePreferredTransport: Unexpected handover evaluation result.");
-                }
-            }
-        }
-    }
-
-    /**
-     * Update {@link SubscriptionPlan}s from {@link NetworkPolicyManager}.
-     */
-    private void updateSubscriptionPlans() {
-        SubscriptionPlan[] plans = mNetworkPolicyManager.getSubscriptionPlans(
-                mSubId, mPhone.getContext().getOpPackageName());
-        mSubscriptionPlans.clear();
-        mSubscriptionPlans.addAll(plans != null ? Arrays.asList(plans) : Collections.emptyList());
-        mCongestedOverrideNetworkTypes.clear();
-        mUnmeteredOverrideNetworkTypes.clear();
-        log("Subscription plans initialized: " + mSubscriptionPlans);
-    }
-
-    /**
-     * Called when data network's link status changed.
-     *
-     * @param dataNetwork The data network that has link status changed.
-     * @param linkStatus The link status (i.e. RRC state).
-     */
-    private void onLinkStatusChanged(@NonNull DataNetwork dataNetwork, @LinkStatus int linkStatus) {
-        // TODO: Since this is only used for 5G icon display logic, so we only use internet data
-        //   data network's link status. Consider expanding to all data networks if needed, and
-        //   should use CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL
-        //   to determine if using all data networks or only internet data networks.
-        int status = DataCallResponse.LINK_STATUS_INACTIVE;
-        boolean anyInternet = mDataNetworkList.stream()
-                .anyMatch(network -> network.isInternetSupported() && network.isConnected());
-        if (anyInternet) {
-            status = mDataNetworkList.stream()
-                    .anyMatch(network -> network.isInternetSupported()
-                            && network.isConnected() && network.getLinkStatus()
-                            == DataCallResponse.LINK_STATUS_ACTIVE)
-                    ? DataCallResponse.LINK_STATUS_ACTIVE
-                    : DataCallResponse.LINK_STATUS_DORMANT;
-        }
-
-        if (mInternetLinkStatus != status) {
-            log("Internet link status changed to " + DataUtils.linkStatusToString(status));
-            mInternetLinkStatus = status;
-            mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                    () -> callback.onPhysicalLinkStatusChanged(mInternetLinkStatus)));
-        }
-
-        updateDataActivity();
-    }
-
-    /**
-     * Called when PCO data changed.
-     *
-     * @param dataNetwork The data network.
-     */
-    private void onPcoDataChanged(@NonNull DataNetwork dataNetwork) {
-        // Check if any data network is using NR advanced bands.
-        int nrAdvancedPcoId = mDataConfigManager.getNrAdvancedCapablePcoId();
-        if (nrAdvancedPcoId != 0) {
-            boolean nrAdvancedCapableByPco = false;
-            for (DataNetwork network : mDataNetworkList) {
-                PcoData pcoData = network.getPcoData().get(nrAdvancedPcoId);
-                if (pcoData != null && pcoData.contents.length > 0
-                        && pcoData.contents[pcoData.contents.length - 1] == 1) {
-                    nrAdvancedCapableByPco = true;
-                    break;
-                }
-            }
-
-            if (nrAdvancedCapableByPco != mNrAdvancedCapableByPco) {
-                log("onPcoDataChanged: mNrAdvancedCapableByPco = " + mNrAdvancedCapableByPco);
-                mNrAdvancedCapableByPco = nrAdvancedCapableByPco;
-                mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                        () -> callback.onNrAdvancedCapableByPcoChanged(mNrAdvancedCapableByPco)));
-            }
-        }
-    }
-
-    /**
-     * Called when network capabilities changed.
-     *
-     * @param dataNetwork The data network.
-     */
-    private void onNetworkCapabilitiesChanged(@NonNull DataNetwork dataNetwork) {
-        // The network capabilities changed. See if there are unsatisfied network requests that
-        // become satisfiable.
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-        for (TelephonyNetworkRequest networkRequest : mAllNetworkRequestList) {
-            if (networkRequest.getState() == TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED) {
-                if (networkRequest.canBeSatisfiedBy(dataNetwork.getNetworkCapabilities())) {
-                    networkRequestList.add(networkRequest);
-                }
-            }
-        }
-
-        if (!networkRequestList.isEmpty()) {
-            log("Found more network requests that can be satisfied. " + networkRequestList);
-            dataNetwork.attachNetworkRequests(networkRequestList);
-        }
-    }
-
-    /**
-     * Check if needed to re-evaluate the existing data networks.
-     *
-     * @param oldNri Previous network registration info.
-     * @param newNri Current network registration info.
-     * @return {@code true} if needed to re-evaluate the existing data networks.
-     */
-    private boolean shouldReevaluateDataNetworks(@Nullable NetworkRegistrationInfo oldNri,
-            @Nullable NetworkRegistrationInfo newNri) {
-        if (oldNri == null || newNri == null) return false;
-        if (newNri.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_UNKNOWN) {
-            // Sometimes devices temporarily lose signal and RAT becomes unknown. We don't tear
-            // down data network in this case.
-            return false;
-        }
-
-        if (oldNri.getAccessNetworkTechnology() != newNri.getAccessNetworkTechnology()
-                || (!oldNri.isRoaming() && newNri.isRoaming())) {
-            return true;
-        }
-
-        DataSpecificRegistrationInfo oldDsri = oldNri.getDataSpecificInfo();
-        DataSpecificRegistrationInfo newDsri = newNri.getDataSpecificInfo();
-
-        if (newDsri == null) return false;
-        if ((oldDsri == null || oldDsri.getVopsSupportInfo() == null
-                || oldDsri.getVopsSupportInfo().isVopsSupported())
-                && (newDsri.getVopsSupportInfo() != null && !newDsri.getVopsSupportInfo()
-                .isVopsSupported())) {
-            // If previously VoPS was supported (or does not exist), and now the network reports
-            // VoPS not supported, we should evaluate existing data networks to see if they need
-            // to be torn down.
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Check if needed to re-evaluate the unsatisfied network requests.
-     *
-     * @param oldNri Previous network registration info.
-     * @param newNri Current network registration info.
-     * @return {@code true} if needed to re-evaluate the unsatisfied network requests.
-     */
-    private boolean shouldReevaluateNetworkRequests(@Nullable NetworkRegistrationInfo oldNri,
-            @Nullable NetworkRegistrationInfo newNri) {
-        if (newNri == null) return false;
-        if (newNri.getAccessNetworkTechnology() == TelephonyManager.NETWORK_TYPE_UNKNOWN) {
-            // Sometimes devices temporarily lose signal and RAT becomes unknown. We don't setup
-            // data in this case.
-            return false;
-        }
-
-        if (oldNri == null
-                || oldNri.getAccessNetworkTechnology() != newNri.getAccessNetworkTechnology()
-                || (!oldNri.isInService() && newNri.isInService())) {
-            return true;
-        }
-
-        DataSpecificRegistrationInfo oldDsri = oldNri.getDataSpecificInfo();
-        DataSpecificRegistrationInfo newDsri = newNri.getDataSpecificInfo();
-
-        if (oldDsri == null) return false;
-        if ((newDsri == null || newDsri.getVopsSupportInfo() == null
-                || newDsri.getVopsSupportInfo().isVopsSupported())
-                && (oldDsri.getVopsSupportInfo() != null && !oldDsri.getVopsSupportInfo()
-                .isVopsSupported())) {
-            // If previously VoPS was not supported, and now the network reports
-            // VoPS supported (or does not report), we should evaluate the unsatisfied network
-            // request to see if the can be satisfied again.
-            return true;
-        }
-
-        return false;
-    }
-
-    /**
-     * Called when service state changed.
-     */
-    // Note that this is only called when data RAT or data registration changed. If we need to know
-    // more "changed" events other than data RAT and data registration state, we should add
-    // a new listening ServiceStateTracker.registerForServiceStateChanged().
-    private void onServiceStateChanged() {
-        // Use the raw service state instead of the mPhone.getServiceState().
-        ServiceState newServiceState = mPhone.getServiceStateTracker().getServiceState();
-        StringBuilder debugMessage = new StringBuilder("onServiceStateChanged: ");
-        boolean evaluateNetworkRequests = false, evaluateDataNetworks = false;
-
-        if (!mServiceState.equals(newServiceState)) {
-            log("onServiceStateChanged: changed to " + newServiceState);
-            for (int transport : mAccessNetworksManager.getAvailableTransports()) {
-                NetworkRegistrationInfo oldNri = mServiceState.getNetworkRegistrationInfo(
-                        NetworkRegistrationInfo.DOMAIN_PS, transport);
-                NetworkRegistrationInfo newNri = newServiceState.getNetworkRegistrationInfo(
-                        NetworkRegistrationInfo.DOMAIN_PS, transport);
-                debugMessage.append("[").append(
-                        AccessNetworkConstants.transportTypeToString(transport)).append(": ");
-                debugMessage.append(oldNri != null ? TelephonyManager.getNetworkTypeName(
-                        oldNri.getAccessNetworkTechnology()) : null);
-                debugMessage.append("->").append(
-                        newNri != null ? TelephonyManager.getNetworkTypeName(
-                                newNri.getAccessNetworkTechnology()) : null).append(", ");
-                debugMessage.append(
-                        oldNri != null ? NetworkRegistrationInfo.registrationStateToString(
-                                oldNri.getRegistrationState()) : null);
-                debugMessage.append("->").append(newNri != null
-                        ? NetworkRegistrationInfo.registrationStateToString(
-                        newNri.getRegistrationState()) : null).append("] ");
-                if (shouldReevaluateDataNetworks(oldNri, newNri)) {
-                    if (!hasMessages(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS)) {
-                        sendMessage(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
-                                DataEvaluationReason.DATA_SERVICE_STATE_CHANGED));
-                        evaluateDataNetworks = true;
-                    }
-                }
-                if (shouldReevaluateNetworkRequests(oldNri, newNri)) {
-                    if (!hasMessages(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS)) {
-                        sendMessage(obtainMessage(EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS,
-                                DataEvaluationReason.DATA_SERVICE_STATE_CHANGED));
-                        evaluateNetworkRequests = true;
-                    }
-                }
-            }
-            mServiceState = newServiceState;
-        } else {
-            debugMessage.append("not changed");
-        }
-        debugMessage.append(". Evaluating network requests is ").append(
-                evaluateNetworkRequests ? "" : "not ").append(
-                "needed, evaluating existing data networks is ").append(
-                evaluateDataNetworks ? "" : "not ").append("needed.");
-        log(debugMessage.toString());
-    }
-
-    /**
-     * Update the internet data network state. For now only {@link TelephonyManager#DATA_CONNECTED}
-     * , {@link TelephonyManager#DATA_SUSPENDED}, and
-     * {@link TelephonyManager#DATA_DISCONNECTED} are supported.
-     */
-    private void updateOverallInternetDataState() {
-        boolean anyInternetConnected = mDataNetworkList.stream()
-                .anyMatch(dataNetwork -> dataNetwork.isInternetSupported()
-                        && (dataNetwork.isConnected() || dataNetwork.isHandoverInProgress()));
-        // If any one is not suspended, then the overall is not suspended.
-        List<DataNetwork> allConnectedInternetDataNetworks = mDataNetworkList.stream()
-                .filter(DataNetwork::isInternetSupported)
-                .filter(dataNetwork -> dataNetwork.isConnected()
-                        || dataNetwork.isHandoverInProgress())
-                .collect(Collectors.toList());
-        boolean isSuspended = !allConnectedInternetDataNetworks.isEmpty()
-                && allConnectedInternetDataNetworks.stream().allMatch(DataNetwork::isSuspended);
-        logv("isSuspended=" + isSuspended + ", anyInternetConnected=" + anyInternetConnected
-                + ", mDataNetworkList=" + mDataNetworkList);
-
-        int dataNetworkState = TelephonyManager.DATA_DISCONNECTED;
-        if (isSuspended) {
-            dataNetworkState = TelephonyManager.DATA_SUSPENDED;
-        } else if (anyInternetConnected) {
-            dataNetworkState = TelephonyManager.DATA_CONNECTED;
-        }
-
-        if (mInternetDataNetworkState != dataNetworkState) {
-            logl("Internet data state changed from "
-                    + TelephonyUtils.dataStateToString(mInternetDataNetworkState) + " to "
-                    + TelephonyUtils.dataStateToString(dataNetworkState) + ".");
-            // TODO: Create a new route to notify TelephonyRegistry.
-            if (dataNetworkState == TelephonyManager.DATA_CONNECTED
-                    && mInternetDataNetworkState == TelephonyManager.DATA_DISCONNECTED) {
-                mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                        () -> callback.onInternetDataNetworkConnected(
-                                allConnectedInternetDataNetworks.stream()
-                                        .map(DataNetwork::getDataProfile)
-                                        .collect(Collectors.toList()))));
-            } else if (dataNetworkState == TelephonyManager.DATA_DISCONNECTED
-                    && mInternetDataNetworkState == TelephonyManager.DATA_CONNECTED) {
-                mDataNetworkControllerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                        callback::onInternetDataNetworkDisconnected));
-            } // TODO: Add suspended callback if needed.
-            mInternetDataNetworkState = dataNetworkState;
-        }
-    }
-
-    /**
-     * @return Data config manager instance.
-     */
-    public @NonNull DataConfigManager getDataConfigManager() {
-        return mDataConfigManager;
-    }
-
-    /**
-     * @return Data profile manager instance.
-     */
-    public @NonNull DataProfileManager getDataProfileManager() {
-        return mDataProfileManager;
-    }
-
-    /**
-     * @return Data settings manager instance.
-     */
-    public @NonNull DataSettingsManager getDataSettingsManager() {
-        return mDataSettingsManager;
-    }
-
-    /**
-     * @return Data retry manager instance.
-     */
-    public @NonNull DataRetryManager getDataRetryManager() {
-        return mDataRetryManager;
-    }
-
-    /**
-     * @return The list of SubscriptionPlans
-     */
-    @VisibleForTesting
-    public @NonNull List<SubscriptionPlan> getSubscriptionPlans() {
-        return mSubscriptionPlans;
-    }
-
-    /**
-     * @return The set of network types an unmetered override applies to
-     */
-    @VisibleForTesting
-    public @NonNull @NetworkType Set<Integer> getUnmeteredOverrideNetworkTypes() {
-        return mUnmeteredOverrideNetworkTypes;
-    }
-
-    /**
-     * @return The set of network types a congested override applies to
-     */
-    @VisibleForTesting
-    public @NonNull @NetworkType Set<Integer> getCongestedOverrideNetworkTypes() {
-        return mCongestedOverrideNetworkTypes;
-    }
-
-    /**
-     * Get data network type based on transport.
-     *
-     * @param transport The transport.
-     * @return The current network type.
-     */
-    private @NetworkType int getDataNetworkType(@TransportType int transport) {
-        NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
-                NetworkRegistrationInfo.DOMAIN_PS, transport);
-        if (nri != null) {
-            return nri.getAccessNetworkTechnology();
-        }
-        return TelephonyManager.NETWORK_TYPE_UNKNOWN;
-    }
-
-    /**
-     * Get data registration state based on transport.
-     *
-     * @param transport The transport.
-     * @return The registration state.
-     */
-    private @RegistrationState int getDataRegistrationState(@TransportType int transport) {
-        NetworkRegistrationInfo nri = mServiceState.getNetworkRegistrationInfo(
-                NetworkRegistrationInfo.DOMAIN_PS, transport);
-        if (nri != null) {
-            return nri.getRegistrationState();
-        }
-        return NetworkRegistrationInfo.REGISTRATION_STATE_UNKNOWN;
-    }
-
-    /**
-     * @return The data activity. Note this is only updated when screen is on.
-     */
-    public @DataActivityType int getDataActivity() {
-        return mDataActivity;
-    }
-
-    /**
-     * Register data network controller callback.
-     *
-     * @param callback The callback.
-     */
-    public void registerDataNetworkControllerCallback(
-            @NonNull DataNetworkControllerCallback callback) {
-        sendMessage(obtainMessage(EVENT_REGISTER_DATA_NETWORK_CONTROLLER_CALLBACK, callback));
-    }
-
-    /**
-     * Unregister data network controller callback.
-     *
-     * @param callback The callback.
-     */
-    public void unregisterDataNetworkControllerCallback(
-            @NonNull DataNetworkControllerCallback callback) {
-        sendMessage(obtainMessage(EVENT_UNREGISTER_DATA_NETWORK_CONTROLLER_CALLBACK, callback));
-    }
-
-    /**
-     * Tear down all data networks.
-     *
-     * @param reason The reason to tear down.
-     */
-    public void tearDownAllDataNetworks(@TearDownReason int reason) {
-        sendMessage(obtainMessage(EVENT_TEAR_DOWN_ALL_DATA_NETWORKS, reason, 0));
-    }
-
-    /**
-     * Called when needed to tear down all data networks.
-     *
-     * @param reason The reason to tear down.
-     */
-    public void onTearDownAllDataNetworks(@TearDownReason int reason) {
-        log("onTearDownAllDataNetworks: reason=" + DataNetwork.tearDownReasonToString(reason));
-        if (mDataNetworkList.isEmpty()) {
-            log("tearDownAllDataNetworks: No pending networks. All disconnected now.");
-            return;
-        }
-
-        mPendingTearDownAllNetworks = true;
-        for (DataNetwork dataNetwork : mDataNetworkList) {
-            if (!dataNetwork.isDisconnecting()) {
-                tearDownGracefully(dataNetwork, reason);
-            }
-        }
-    }
-
-    /**
-     * Evaluate the pending IMS de-registration networks and tear it down if it is safe to do that.
-     */
-    private void evaluatePendingImsDeregDataNetworks() {
-        Iterator<Map.Entry<DataNetwork, Runnable>> it =
-                mPendingImsDeregDataNetworks.entrySet().iterator();
-        while (it.hasNext()) {
-            Map.Entry<DataNetwork, Runnable> entry = it.next();
-            if (isSafeToTearDown(entry.getKey())) {
-                // Now tear down the network.
-                log("evaluatePendingImsDeregDataNetworks: Safe to tear down data network "
-                        + entry.getKey() + " now.");
-                entry.getValue().run();
-                it.remove();
-            } else {
-                log("Still not safe to tear down " + entry.getKey() + ".");
-            }
-        }
-    }
-
-    /**
-     * Check if the data network is safe to tear down at this moment.
-     *
-     * @param dataNetwork The data network.
-     * @return {@code true} if the data network is safe to tear down. {@code false} indicates this
-     * data network has requests originated from the IMS/RCS service and IMS/RCS is not
-     * de-registered yet.
-     */
-    private boolean isSafeToTearDown(@NonNull DataNetwork dataNetwork) {
-        for (int imsFeature : SUPPORTED_IMS_FEATURES) {
-            String imsFeaturePackage = mImsFeaturePackageName.get(imsFeature);
-            if (imsFeaturePackage != null) {
-                if (dataNetwork.getAttachedNetworkRequestList()
-                        .hasNetworkRequestsFromPackage(imsFeaturePackage)) {
-                    if (mRegisteredImsFeatures.contains(imsFeature)) {
-                        return false;
-                    }
-                }
-            }
-        }
-        // All IMS features are de-registered (or this data network has no requests from IMS feature
-        // packages.
-        return true;
-    }
-
-    /**
-     * @return {@code true} if IMS graceful tear down is supported by frameworks.
-     */
-    private boolean isImsGracefulTearDownSupported() {
-        return mDataConfigManager.getImsDeregistrationDelay() > 0;
-    }
-
-    /**
-     * Tear down the data network gracefully.
-     *
-     * @param dataNetwork The data network.
-     */
-    private void tearDownGracefully(@NonNull DataNetwork dataNetwork, @TearDownReason int reason) {
-        long deregDelay = mDataConfigManager.getImsDeregistrationDelay();
-        if (isImsGracefulTearDownSupported() && !isSafeToTearDown(dataNetwork)) {
-            log("tearDownGracefully: Not safe to tear down " + dataNetwork
-                    + " at this point. Wait for IMS de-registration or timeout. MMTEL="
-                    + (mRegisteredImsFeatures.contains(ImsFeature.FEATURE_MMTEL)
-                    ? "registered" : "not registered")
-                    + ", RCS="
-                    + (mRegisteredImsFeatures.contains(ImsFeature.FEATURE_RCS)
-                    ? "registered" : "not registered")
-            );
-            Runnable runnable = dataNetwork.tearDownWhenConditionMet(reason, deregDelay);
-            if (runnable != null) {
-                mPendingImsDeregDataNetworks.put(dataNetwork, runnable);
-            } else {
-                log(dataNetwork + " is being torn down already.");
-            }
-        } else {
-            // Graceful tear down is not turned on. Tear down the network immediately.
-            log("tearDownGracefully: Safe to tear down " + dataNetwork);
-            dataNetwork.tearDown(reason);
-        }
-    }
-
-    /**
-     * Get the internet data network state. Note that this is the best effort if more than one
-     * data network supports internet. For now only {@link TelephonyManager#DATA_CONNECTED}
-     * , {@link TelephonyManager#DATA_SUSPENDED}, and {@link TelephonyManager#DATA_DISCONNECTED}
-     * are supported.
-     *
-     * @return The data network state.
-     */
-    public @DataState int getInternetDataNetworkState() {
-        return mInternetDataNetworkState;
-    }
-
-    /**
-     * @return List of bound data service packages name on WWAN and WLAN.
-     */
-    public @NonNull List<String> getDataServicePackages() {
-        List<String> packages = new ArrayList<>();
-        for (int i = 0; i < mDataServiceManagers.size(); i++) {
-            packages.add(mDataServiceManagers.valueAt(i).getDataServicePackageName());
-        }
-        return packages;
-    }
-
-    /**
-     * Log debug messages.
-     * @param s debug messages
-     */
-    private void log(@NonNull String s) {
-        Rlog.d(mLogTag, s);
-    }
-
-    /**
-     * Log error messages.
-     * @param s error messages
-     */
-    private void loge(@NonNull String s) {
-        Rlog.e(mLogTag, s);
-    }
-
-    /**
-     * Log verbose messages.
-     * @param s debug messages.
-     */
-    private void logv(@NonNull String s) {
-        if (VDBG) Rlog.v(mLogTag, s);
-    }
-
-    /**
-     * Log debug messages and also log into the local log.
-     * @param s debug messages
-     */
-    private void logl(@NonNull String s) {
-        log(s);
-        mLocalLog.log(s);
-    }
-
-    /**
-     * Dump the state of DataNetworkController
-     *
-     * @param fd File descriptor
-     * @param printWriter Print writer
-     * @param args Arguments
-     */
-    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
-        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
-        pw.println(DataNetworkController.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":");
-        pw.increaseIndent();
-        pw.println("Current data networks:");
-        pw.increaseIndent();
-        for (DataNetwork dn : mDataNetworkList) {
-            dn.dump(fd, pw, args);
-        }
-        pw.decreaseIndent();
-
-        pw.println("Pending tear down data networks:");
-        pw.increaseIndent();
-        for (DataNetwork dn : mPendingImsDeregDataNetworks.keySet()) {
-            dn.dump(fd, pw, args);
-        }
-        pw.decreaseIndent();
-
-        pw.println("Previously connected data networks: (up to "
-                + MAX_HISTORICAL_CONNECTED_DATA_NETWORKS + ")");
-        pw.increaseIndent();
-        for (DataNetwork dn: mPreviousConnectedDataNetworkList) {
-            // Do not print networks which is already in current network list.
-            if (!mDataNetworkList.contains(dn)) {
-                dn.dump(fd, pw, args);
-            }
-        }
-        pw.decreaseIndent();
-
-        pw.println("All telephony network requests:");
-        pw.increaseIndent();
-        for (TelephonyNetworkRequest networkRequest : mAllNetworkRequestList) {
-            pw.println(networkRequest);
-        }
-        pw.decreaseIndent();
-
-        pw.println("IMS features registration state: MMTEL="
-                + (mRegisteredImsFeatures.contains(ImsFeature.FEATURE_MMTEL)
-                ? "registered" : "not registered")
-                + ", RCS="
-                + (mRegisteredImsFeatures.contains(ImsFeature.FEATURE_RCS)
-                ? "registered" : "not registered"));
-        pw.println("mServiceState=" + mServiceState);
-        pw.println("mPsRestricted=" + mPsRestricted);
-        pw.println("mAnyDataNetworkExisting=" + mAnyDataNetworkExisting);
-        pw.println("mInternetDataNetworkState="
-                + TelephonyUtils.dataStateToString(mInternetDataNetworkState));
-        pw.println("mImsDataNetworkState="
-                + TelephonyUtils.dataStateToString(mImsDataNetworkState));
-        pw.println("mDataServiceBound=" + mDataServiceBound);
-        pw.println("mSimState=" + SubscriptionInfoUpdater.simStateString(mSimState));
-        pw.println("mDataNetworkControllerCallbacks=" + mDataNetworkControllerCallbacks);
-        pw.println("Subscription plans:");
-        pw.increaseIndent();
-        mSubscriptionPlans.forEach(pw::println);
-        pw.decreaseIndent();
-        pw.println("Unmetered override network types=" + mUnmeteredOverrideNetworkTypes.stream()
-                .map(TelephonyManager::getNetworkTypeName).collect(Collectors.joining(",")));
-        pw.println("Congested override network types=" + mCongestedOverrideNetworkTypes.stream()
-                .map(TelephonyManager::getNetworkTypeName).collect(Collectors.joining(",")));
-        pw.println("mImsThrottleCounter=" + mImsThrottleCounter);
-        pw.println("mNetworkUnwantedCounter=" + mNetworkUnwantedCounter);
-        pw.println("Local logs:");
-        pw.increaseIndent();
-        mLocalLog.dump(fd, pw, args);
-        pw.decreaseIndent();
-
-        pw.println("-------------------------------------");
-        mDataProfileManager.dump(fd, pw, args);
-        pw.println("-------------------------------------");
-        mDataRetryManager.dump(fd, pw, args);
-        pw.println("-------------------------------------");
-        mDataSettingsManager.dump(fd, pw, args);
-        pw.println("-------------------------------------");
-        mDataStallRecoveryManager.dump(fd, pw, args);
-        pw.println("-------------------------------------");
-        mDataConfigManager.dump(fd, pw, args);
-
-        pw.decreaseIndent();
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/DataProfileManager.java b/src/java/com/android/internal/telephony/data/DataProfileManager.java
deleted file mode 100644
index 1ec345c..0000000
--- a/src/java/com/android/internal/telephony/data/DataProfileManager.java
+++ /dev/null
@@ -1,958 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.ContentObserver;
-import android.database.Cursor;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Telephony;
-import android.telephony.Annotation;
-import android.telephony.Annotation.NetworkType;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataProfile;
-import android.telephony.data.TrafficDescriptor;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.IndentingPrintWriter;
-import android.util.LocalLog;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.stream.Collectors;
-
-/**
- * DataProfileManager manages the all {@link DataProfile}s for the current
- * subscription.
- */
-public class DataProfileManager extends Handler {
-    private static final boolean VDBG = true;
-
-    /** Event for data config updated. */
-    private static final int EVENT_DATA_CONFIG_UPDATED = 1;
-
-    /** Event for APN database changed. */
-    private static final int EVENT_APN_DATABASE_CHANGED = 2;
-
-    /** Event for SIM refresh. */
-    private static final int EVENT_SIM_REFRESH = 3;
-
-    private final Phone mPhone;
-    private final String mLogTag;
-    private final LocalLog mLocalLog = new LocalLog(128);
-
-    /** Data network controller. */
-    private final @NonNull DataNetworkController mDataNetworkController;
-
-    /** Data config manager. */
-    private final @NonNull DataConfigManager mDataConfigManager;
-
-    /** Cellular data service. */
-    private final @NonNull DataServiceManager mWwanDataServiceManager;
-
-    /** All data profiles for the current carrier. */
-    private final @NonNull List<DataProfile> mAllDataProfiles = new ArrayList<>();
-
-    /** The data profile used for initial attach. */
-    private @Nullable DataProfile mInitialAttachDataProfile = null;
-
-    /** The preferred data profile used for internet. */
-    private @Nullable DataProfile mPreferredDataProfile = null;
-
-    /** Preferred data profile set id. */
-    private int mPreferredDataProfileSetId = Telephony.Carriers.NO_APN_SET_ID;
-
-    /** Data profile manager callbacks. */
-    private final @NonNull Set<DataProfileManagerCallback> mDataProfileManagerCallbacks =
-            new ArraySet<>();
-
-    /**
-     * Data profile manager callback. This should be only used by {@link DataNetworkController}.
-     */
-    public abstract static class DataProfileManagerCallback extends DataCallback {
-        /**
-         * Constructor
-         *
-         * @param executor The executor of the callback.
-         */
-        public DataProfileManagerCallback(@NonNull @CallbackExecutor Executor executor) {
-            super(executor);
-        }
-
-        /**
-         * Called when data profiles changed.
-         */
-        public abstract void onDataProfilesChanged();
-    }
-
-    /**
-     * Constructor
-     *
-     * @param phone The phone instance.
-     * @param dataNetworkController Data network controller.
-     * @param dataServiceManager WWAN data service manager.
-     * @param looper The looper to be used by the handler. Currently the handler thread is the
-     * phone process's main thread.
-     * @param callback Data profile manager callback.
-     */
-    public DataProfileManager(@NonNull Phone phone,
-            @NonNull DataNetworkController dataNetworkController,
-            @NonNull DataServiceManager dataServiceManager, @NonNull Looper looper,
-            @NonNull DataProfileManagerCallback callback) {
-        super(looper);
-        mPhone = phone;
-        mLogTag = "DPM-" + mPhone.getPhoneId();
-        mDataNetworkController = dataNetworkController;
-        mWwanDataServiceManager = dataServiceManager;
-        mDataConfigManager = dataNetworkController.getDataConfigManager();
-        mDataProfileManagerCallbacks.add(callback);
-        registerAllEvents();
-    }
-
-    /**
-     * Register for all events that data network controller is interested.
-     */
-    private void registerAllEvents() {
-        mDataNetworkController.registerDataNetworkControllerCallback(
-                new DataNetworkControllerCallback(this::post) {
-                    @Override
-                    public void onInternetDataNetworkConnected(
-                            @NonNull List<DataProfile> dataProfiles) {
-                        DataProfileManager.this.onInternetDataNetworkConnected(dataProfiles);
-                    }});
-        mDataConfigManager.registerForConfigUpdate(this, EVENT_DATA_CONFIG_UPDATED);
-        mPhone.getContext().getContentResolver().registerContentObserver(
-                Telephony.Carriers.CONTENT_URI, true, new ContentObserver(this) {
-                    @Override
-                    public void onChange(boolean selfChange) {
-                        super.onChange(selfChange);
-                        sendEmptyMessage(EVENT_APN_DATABASE_CHANGED);
-                    }
-                });
-        mPhone.mCi.registerForIccRefresh(this, EVENT_SIM_REFRESH, null);
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-            case EVENT_DATA_CONFIG_UPDATED:
-                onDataConfigUpdated();
-                break;
-            case EVENT_SIM_REFRESH:
-                log("Update data profiles due to SIM refresh.");
-                updateDataProfiles();
-                break;
-            case EVENT_APN_DATABASE_CHANGED:
-                log("Update data profiles due to APN db updated.");
-                updateDataProfiles();
-                break;
-            default:
-                loge("Unexpected event " + msg);
-                break;
-        }
-    }
-
-    /**
-     * Called when data config was updated.
-     */
-    private void onDataConfigUpdated() {
-        log("Update data profiles due to config updated.");
-        updateDataProfiles();
-
-        //TODO: more works needed to be done here.
-    }
-
-    /**
-     * Check if there are any Enterprise APN configured by DPC and return a data profile
-     * with the same.
-     * @return data profile with enterprise ApnSetting if available, else null
-     */
-    @Nullable private DataProfile getEnterpriseDataProfile() {
-        Cursor cursor = mPhone.getContext().getContentResolver().query(
-                Telephony.Carriers.DPC_URI, null, null, null, null);
-        if (cursor == null) {
-            loge("Cannot access APN database through telephony provider.");
-            return null;
-        }
-
-        DataProfile dataProfile = null;
-        while (cursor.moveToNext()) {
-            ApnSetting apn = ApnSetting.makeApnSetting(cursor);
-            if (apn != null) {
-                dataProfile = new DataProfile.Builder()
-                        .setApnSetting(apn)
-                        .setTrafficDescriptor(new TrafficDescriptor(apn.getApnName(), null))
-                        .setPreferred(false)
-                        .build();
-                if (dataProfile.canSatisfy(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)) {
-                    break;
-                }
-            }
-        }
-        cursor.close();
-        return dataProfile;
-    }
-    /**
-     * Update all data profiles, including preferred data profile, and initial attach data profile.
-     * Also send those profiles down to the modem if needed.
-     */
-    private void updateDataProfiles() {
-        List<DataProfile> profiles = new ArrayList<>();
-        if (mDataConfigManager.isConfigCarrierSpecific()) {
-            Cursor cursor = mPhone.getContext().getContentResolver().query(
-                    Uri.withAppendedPath(Telephony.Carriers.SIM_APN_URI, "filtered/subId/"
-                            + mPhone.getSubId()), null, null, null, Telephony.Carriers._ID);
-            if (cursor == null) {
-                loge("Cannot access APN database through telephony provider.");
-                return;
-            }
-
-            while (cursor.moveToNext()) {
-                ApnSetting apn = ApnSetting.makeApnSetting(cursor);
-                if (apn != null) {
-                    DataProfile dataProfile = new DataProfile.Builder()
-                            .setApnSetting(apn)
-                            .setTrafficDescriptor(new TrafficDescriptor(apn.getApnName(), null))
-                            .setPreferred(false)
-                            .build();
-                    profiles.add(dataProfile);
-                    log("Added " + dataProfile);
-                }
-            }
-            cursor.close();
-        }
-
-        // Check if any of the profile already supports ENTERPRISE, if not, check if DPC has
-        // configured one and retrieve the same.
-        DataProfile dataProfile = profiles.stream()
-                .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE))
-                .findFirst()
-                .orElse(null);
-        if (dataProfile == null) {
-            dataProfile = getEnterpriseDataProfile();
-            if (dataProfile != null) {
-                profiles.add(dataProfile);
-                log("Added enterprise profile " + dataProfile);
-            }
-        }
-
-        // Check if any of the profile already supports IMS, if not, add the default one.
-        dataProfile = profiles.stream()
-                .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS))
-                .findFirst()
-                .orElse(null);
-        if (dataProfile == null) {
-            profiles.add(new DataProfile.Builder()
-                    .setApnSetting(buildDefaultApnSetting("DEFAULT IMS", "ims",
-                            ApnSetting.TYPE_IMS))
-                    .setTrafficDescriptor(new TrafficDescriptor("ims", null))
-                    .build());
-            log("Added default IMS data profile.");
-        }
-
-        // Check if any of the profile already supports EIMS, if not, add the default one.
-        dataProfile = profiles.stream()
-                .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_EIMS))
-                .findFirst()
-                .orElse(null);
-        if (dataProfile == null) {
-            profiles.add(new DataProfile.Builder()
-                    .setApnSetting(buildDefaultApnSetting("DEFAULT EIMS", "sos",
-                            ApnSetting.TYPE_EMERGENCY))
-                    .setTrafficDescriptor(new TrafficDescriptor("sos", null))
-                    .build());
-            log("Added default EIMS data profile.");
-        }
-
-        dedupeDataProfiles(profiles);
-
-        log("Found " + profiles.size() + " data profiles. profiles = " + profiles);
-
-        boolean profilesChanged = false;
-        if (mAllDataProfiles.size() != profiles.size() || !mAllDataProfiles.containsAll(profiles)) {
-            log("Data profiles changed.");
-            mAllDataProfiles.clear();
-            mAllDataProfiles.addAll(profiles);
-            profilesChanged = true;
-        }
-
-        // Reload the latest preferred data profile from either database or config.
-        profilesChanged |= updatePreferredDataProfile();
-
-        int setId = getPreferredDataProfileSetId();
-        if (setId != mPreferredDataProfileSetId) {
-            logl("Changed preferred data profile set id to " + setId);
-            mPreferredDataProfileSetId = setId;
-            profilesChanged = true;
-        }
-
-        updateDataProfilesAtModem();
-        updateInitialAttachDataProfileAtModem();
-
-        if (profilesChanged) {
-            mDataProfileManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                    callback::onDataProfilesChanged));
-        }
-    }
-
-    /**
-     * @return The preferred data profile set id.
-     */
-    private int getPreferredDataProfileSetId() {
-        // Query the preferred APN set id. The set id is automatically set when we set by
-        // TelephonyProvider when setting preferred APN in setPreferredDataProfile().
-        Cursor cursor = mPhone.getContext().getContentResolver()
-                .query(Uri.withAppendedPath(Telephony.Carriers.PREFERRED_APN_SET_URI,
-                        String.valueOf(mPhone.getSubId())),
-                        new String[] {Telephony.Carriers.APN_SET_ID}, null, null, null);
-        // Returns all APNs for the current carrier which have an apn_set_id
-        // equal to the preferred APN (if no preferred APN, or if the preferred APN has no set id,
-        // the query will return null)
-        if (cursor == null) {
-            log("getPreferredDataProfileSetId: cursor is null");
-            return Telephony.Carriers.NO_APN_SET_ID;
-        }
-
-        int setId;
-        if (cursor.getCount() < 1) {
-            loge("getPreferredDataProfileSetId: no APNs found");
-            setId = Telephony.Carriers.NO_APN_SET_ID;
-        } else {
-            cursor.moveToFirst();
-            setId = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN_SET_ID));
-        }
-
-        cursor.close();
-        return setId;
-    }
-
-    /**
-     * Called when internet data is connected.
-     *
-     * @param dataProfiles The connected internet data networks' profiles.
-     */
-    private void onInternetDataNetworkConnected(@NonNull List<DataProfile> dataProfiles) {
-        // If there is already a preferred data profile set, then we don't need to do anything.
-        if (mPreferredDataProfile != null) return;
-
-        // If there is no preferred data profile, then we should use one of the data profiles,
-        // which is good for internet, as the preferred data profile.
-
-        // Most of the cases there should be only one, but in case there are multiple, choose the
-        // one which has longest life cycle.
-        DataProfile dataProfile = dataProfiles.stream()
-                .max(Comparator.comparingLong(DataProfile::getLastSetupTimestamp).reversed())
-                .orElse(null);
-        // Save the preferred data profile into database.
-        setPreferredDataProfile(dataProfile);
-        updateDataProfiles();
-    }
-
-    /**
-     * Get the preferred data profile for internet data.
-     *
-     * @return The preferred data profile.
-     */
-    private @Nullable DataProfile getPreferredDataProfileFromDb() {
-        Cursor cursor = mPhone.getContext().getContentResolver().query(
-                Uri.withAppendedPath(Telephony.Carriers.PREFERRED_APN_URI,
-                        String.valueOf(mPhone.getSubId())), null, null, null,
-                Telephony.Carriers.DEFAULT_SORT_ORDER);
-        DataProfile dataProfile = null;
-        if (cursor != null) {
-            if (cursor.getCount() > 0) {
-                cursor.moveToFirst();
-                int apnId = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
-                dataProfile = mAllDataProfiles.stream()
-                        .filter(dp -> dp.getApnSetting() != null
-                                && dp.getApnSetting().getId() == apnId)
-                        .findFirst()
-                        .orElse(null);
-            }
-            cursor.close();
-        }
-        log("getPreferredDataProfileFromDb: " + dataProfile);
-        return dataProfile;
-    }
-
-    /**
-     * @return The preferred data profile from carrier config.
-     */
-    private @Nullable DataProfile getPreferredDataProfileFromConfig() {
-        // Check if there is configured default preferred data profile.
-        String defaultPreferredApn = mDataConfigManager.getDefaultPreferredApn();
-        if (!TextUtils.isEmpty(defaultPreferredApn)) {
-            return mAllDataProfiles.stream()
-                    .filter(dp -> dp.getApnSetting() != null && defaultPreferredApn.equals(
-                                    dp.getApnSetting().getApnName()))
-                    .findFirst()
-                    .orElse(null);
-        }
-        return null;
-    }
-
-    /**
-     * Save the preferred data profile into the database.
-     *
-     * @param dataProfile The preferred data profile used for internet data. {@code null} to clear
-     * the preferred data profile from database.
-     */
-    private void setPreferredDataProfile(@Nullable DataProfile dataProfile) {
-        log("setPreferredDataProfile: " + dataProfile);
-
-        String subId = Long.toString(mPhone.getSubId());
-        Uri uri = Uri.withAppendedPath(Telephony.Carriers.PREFERRED_APN_URI, subId);
-        ContentResolver resolver = mPhone.getContext().getContentResolver();
-        resolver.delete(uri, null, null);
-
-        if (dataProfile != null && dataProfile.getApnSetting() != null) {
-            ContentValues values = new ContentValues();
-            // Fill only the id here. TelephonyProvider will pull the rest of key fields and write
-            // into the database.
-            values.put(Telephony.Carriers.APN_ID, dataProfile.getApnSetting().getId());
-            resolver.insert(uri, values);
-        }
-    }
-
-    /**
-     * Reload the latest preferred data profile from either database or the config. This is to
-     * make sure the cached {@link #mPreferredDataProfile} is in-sync.
-     *
-     * @return {@code true} if preferred data profile changed.
-     */
-    private boolean updatePreferredDataProfile() {
-        DataProfile preferredDataProfile;
-        if (SubscriptionManager.isValidSubscriptionId(mPhone.getSubId())) {
-            preferredDataProfile = getPreferredDataProfileFromDb();
-            if (preferredDataProfile == null) {
-                preferredDataProfile = getPreferredDataProfileFromConfig();
-                if (preferredDataProfile != null) {
-                    // Save the carrier specified preferred data profile into database
-                    setPreferredDataProfile(preferredDataProfile);
-                }
-            }
-        } else {
-            preferredDataProfile = null;
-        }
-
-        for (DataProfile dataProfile : mAllDataProfiles) {
-            dataProfile.setPreferred(dataProfile.equals(preferredDataProfile));
-        }
-
-        if (!Objects.equals(mPreferredDataProfile, preferredDataProfile)) {
-            mPreferredDataProfile = preferredDataProfile;
-
-            logl("Changed preferred data profile to " + mPreferredDataProfile);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Update the data profile used for initial attach.
-     *
-     * Note that starting from Android 13 only APNs that supports "IA" type will be used for
-     * initial attach. Please update APN configuration file if needed.
-     *
-     * Some carriers might explicitly require that using "user-added" APN for initial
-     * attach. In this case, exception can be configured through
-     * {@link CarrierConfigManager#KEY_ALLOWED_INITIAL_ATTACH_APN_TYPES_STRING_ARRAY}.
-     */
-    private void updateInitialAttachDataProfileAtModem() {
-        DataProfile initialAttachDataProfile = null;
-
-        // Sort the data profiles so the preferred data profile is at the beginning.
-        List<DataProfile> allDataProfiles = mAllDataProfiles.stream()
-                .sorted(Comparator.comparing((DataProfile dp) -> !dp.equals(mPreferredDataProfile)))
-                .collect(Collectors.toList());
-        // Search in the order. "IA" type should be the first from getAllowedInitialAttachApnTypes.
-        for (int apnType : mDataConfigManager.getAllowedInitialAttachApnTypes()) {
-            initialAttachDataProfile = allDataProfiles.stream()
-                    .filter(dp -> dp.canSatisfy(DataUtils.apnTypeToNetworkCapability(apnType)))
-                    .findFirst()
-                    .orElse(null);
-            if (initialAttachDataProfile != null) break;
-        }
-
-        if (!Objects.equals(mInitialAttachDataProfile, initialAttachDataProfile)) {
-            mInitialAttachDataProfile = initialAttachDataProfile;
-            logl("Initial attach data profile updated as " + mInitialAttachDataProfile);
-            // TODO: Push the null data profile to modem on new AIDL HAL. Modem should clear the IA
-            //  APN.
-            if (mInitialAttachDataProfile != null) {
-                mWwanDataServiceManager.setInitialAttachApn(mInitialAttachDataProfile,
-                        mPhone.getServiceState().getDataRoamingFromRegistration(), null);
-            }
-        }
-    }
-
-    /**
-     * Update the data profiles at modem.
-     */
-    private void updateDataProfilesAtModem() {
-        log("updateDataProfilesAtModem: set " + mAllDataProfiles.size() + " data profiles.");
-        mWwanDataServiceManager.setDataProfile(mAllDataProfiles,
-                mPhone.getServiceState().getDataRoamingFromRegistration(), null);
-    }
-
-    /**
-     * Create default apn settings for the apn type like emergency, and ims
-     *
-     * @param entry Entry name
-     * @param apn APN name
-     * @param apnTypeBitmask APN type
-     * @return The APN setting
-     */
-    private @NonNull ApnSetting buildDefaultApnSetting(@NonNull String entry,
-            @NonNull String apn, @Annotation.ApnType int apnTypeBitmask) {
-        return new ApnSetting.Builder()
-                .setEntryName(entry)
-                .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
-                .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
-                .setApnName(apn)
-                .setApnTypeBitmask(apnTypeBitmask)
-                .setCarrierEnabled(true)
-                .setApnSetId(Telephony.Carriers.MATCH_ALL_APN_SET_ID)
-                .build();
-    }
-
-    /**
-     * Get the data profile that can satisfy the network request.
-     *
-     * @param networkRequest The network request.
-     * @param networkType The current data network type.
-     * @return The data profile. {@code null} if can't find any satisfiable data profile.
-     */
-    public @Nullable DataProfile getDataProfileForNetworkRequest(
-            @NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType) {
-        ApnSetting apnSetting = null;
-        if (networkRequest.hasAttribute(TelephonyNetworkRequest
-                .CAPABILITY_ATTRIBUTE_APN_SETTING)) {
-            apnSetting = getApnSettingForNetworkRequest(networkRequest, networkType);
-        }
-
-        TrafficDescriptor.Builder trafficDescriptorBuilder = new TrafficDescriptor.Builder();
-        if (networkRequest.hasAttribute(TelephonyNetworkRequest
-                .CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN)) {
-            if (apnSetting != null) {
-                trafficDescriptorBuilder.setDataNetworkName(apnSetting.getApnName());
-            }
-        }
-
-        if (networkRequest.hasAttribute(
-                TelephonyNetworkRequest.CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID)) {
-            TrafficDescriptor.OsAppId osAppId = networkRequest.getOsAppId();
-            if (osAppId != null) {
-                trafficDescriptorBuilder.setOsAppId(osAppId.getBytes());
-            }
-        }
-
-        TrafficDescriptor trafficDescriptor;
-        try {
-            trafficDescriptor = trafficDescriptorBuilder.build();
-        } catch (IllegalArgumentException e) {
-            // We reach here when both ApnSetting and trafficDescriptor are null.
-            log("Unable to find a data profile for " + networkRequest);
-            return null;
-        }
-
-        // Instead of building the data profile from APN setting and traffic descriptor on-the-fly,
-        // find the existing one from mAllDataProfiles so the last-setup timestamp can be retained.
-        // Only create a new one when it can't be found.
-        for (DataProfile dataProfile : mAllDataProfiles) {
-            if (Objects.equals(apnSetting, dataProfile.getApnSetting())
-                    && trafficDescriptor.equals(dataProfile.getTrafficDescriptor())) {
-                return dataProfile;
-            }
-        }
-
-        // When reaching here, it means that we have a valid non-null traffic descriptor, but
-        // could not find it in mAllDataProfiles. This could happen on the traffic descriptor
-        // capable capabilities like ENTERPRISE.
-        DataProfile.Builder profileBuilder = new DataProfile.Builder();
-        if (apnSetting != null) {
-            profileBuilder.setApnSetting(apnSetting);
-        }
-
-        // trafficDescriptor is always non-null when we reach here.
-        profileBuilder.setTrafficDescriptor(trafficDescriptor);
-
-        DataProfile dataProfile = profileBuilder.build();
-        log("Created data profile " + dataProfile + " for " + networkRequest);
-        return dataProfile;
-    }
-
-    /**
-     * Get the APN setting for the network request.
-     *
-     * @param networkRequest The network request.
-     * @param networkType The current data network type.
-     * @return The APN setting. {@code null} if can't find any satisfiable data profile.
-     */
-    private @Nullable ApnSetting getApnSettingForNetworkRequest(
-            @NonNull TelephonyNetworkRequest networkRequest, @NetworkType int networkType) {
-        if (!networkRequest.hasAttribute(
-                TelephonyNetworkRequest.CAPABILITY_ATTRIBUTE_APN_SETTING)) {
-            loge("Network request does not have APN setting attribute.");
-            return null;
-        }
-
-        // Filter out the data profile that can't satisfy the request.
-        // Preferred data profile should be returned in the top of the list.
-        List<DataProfile> dataProfiles = mAllDataProfiles.stream()
-                .filter(networkRequest::canBeSatisfiedBy)
-                // Put the preferred data profile at the top of the list, then the longest time
-                // hasn't used data profile will be in the front so all the data profiles can be
-                // tried.
-                .sorted(Comparator.comparing((DataProfile dp) -> !dp.equals(mPreferredDataProfile))
-                        .thenComparingLong(DataProfile::getLastSetupTimestamp))
-                .collect(Collectors.toList());
-        for (DataProfile dataProfile : dataProfiles) {
-            logv("Satisfied profile: " + dataProfile + ", last setup="
-                    + DataUtils.elapsedTimeToString(dataProfile.getLastSetupTimestamp()));
-        }
-        if (dataProfiles.size() == 0) {
-            log("Can't find any data profile that can satisfy " + networkRequest);
-            return null;
-        }
-
-        // Check if the remaining data profiles can used in current data network type.
-        dataProfiles = dataProfiles.stream()
-                .filter(dp -> dp.getApnSetting() != null
-                        && dp.getApnSetting().canSupportNetworkType(networkType))
-                .collect(Collectors.toList());
-        if (dataProfiles.size() == 0) {
-            log("Can't find any data profile for network type "
-                    + TelephonyManager.getNetworkTypeName(networkType));
-            return null;
-        }
-
-        // Check if preferred data profile set id matches.
-        dataProfiles = dataProfiles.stream()
-                .filter(dp -> dp.getApnSetting() != null
-                        && (dp.getApnSetting().getApnSetId()
-                        == Telephony.Carriers.MATCH_ALL_APN_SET_ID
-                        || dp.getApnSetting().getApnSetId() == mPreferredDataProfileSetId))
-                .collect(Collectors.toList());
-        if (dataProfiles.size() == 0) {
-            log("Can't find any data profile has APN set id matched. mPreferredDataProfileSetId="
-                    + mPreferredDataProfileSetId);
-            return null;
-        }
-
-        return dataProfiles.get(0).getApnSetting();
-    }
-
-    /**
-     * Check if the data profile is the preferred data profile.
-     *
-     * @param dataProfile The data profile to check.
-     * @return {@code true} if the data profile is the preferred data profile.
-     */
-    public boolean isDataProfilePreferred(@NonNull DataProfile dataProfile) {
-        return dataProfile.equals(mPreferredDataProfile);
-    }
-
-    /**
-     * Check if there is tethering data profile for certain network type.
-     *
-     * @param networkType The network type
-     * @return {@code true} if tethering data profile is found. {@code false} if no specific profile
-     * should used for tethering. In this case, tethering service will use internet network for
-     * tethering.
-     */
-    public boolean isTetheringDataProfileExisting(@NetworkType int networkType) {
-        if (mDataConfigManager.isTetheringProfileDisabledForRoaming()
-                && mPhone.getServiceState().getDataRoaming()) {
-            // Use internet network for tethering.
-            return false;
-        }
-        TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
-                        .build(), mPhone);
-        return getDataProfileForNetworkRequest(networkRequest, networkType) != null;
-    }
-
-     /**
-     * Check if any preferred data profile exists.
-     *
-     * @return {@code true} if any preferred data profile exists
-     */
-    public boolean isAnyPreferredDataProfileExisting() {
-        for (DataProfile dataProfile : mAllDataProfiles) {
-            if (dataProfile.isPreferred()) return true;
-        }
-        return false;
-    }
-
-    /**
-     * Dedupe the similar data profiles.
-     */
-    private void dedupeDataProfiles(@NonNull List<DataProfile> dataProfiles) {
-        int i = 0;
-        while (i < dataProfiles.size() - 1) {
-            DataProfile first = dataProfiles.get(i);
-            int j = i + 1;
-            while (j < dataProfiles.size()) {
-                DataProfile second = dataProfiles.get(j);
-                DataProfile merged = mergeDataProfiles(first, second);
-                if (merged != null) {
-                    log("Created a merged profile " + merged + " from " + first + " and "
-                            + second);
-                    loge("Merging data profiles will not be supported anymore. Please "
-                            + "directly configure the merged profile " + merged + " in the APN "
-                            + "config.");
-                    dataProfiles.set(i, merged);
-                    dataProfiles.remove(j);
-                } else {
-                    j++;
-                }
-            }
-            i++;
-        }
-    }
-
-    /**
-     * Merge two data profiles if possible.
-     *
-     * @param dp1 Data profile 1 to be merged.
-     * @param dp2 Data profile 2 to be merged.
-     *
-     * @return The merged data profile. {@code null} if merging is not possible.
-     */
-    private static @Nullable DataProfile mergeDataProfiles(
-            @NonNull DataProfile dp1, @NonNull DataProfile dp2) {
-        Objects.requireNonNull(dp1);
-        Objects.requireNonNull(dp2);
-
-        // We don't merge data profiles that have different traffic descriptor.
-        if (!Objects.equals(dp1.getTrafficDescriptor(), dp2.getTrafficDescriptor())) return null;
-
-        // If one of the APN setting is null, we don't merge.
-        if (dp1.getApnSetting() == null || dp2.getApnSetting() == null) return null;
-
-        // If two APN settings are not similar, we don't merge.
-        if (!dp1.getApnSetting().similar(dp2.getApnSetting())) return null;
-
-        // Start to merge APN setting 1 and 2.
-        ApnSetting apn1 = dp1.getApnSetting();
-        ApnSetting apn2 = dp2.getApnSetting();
-        ApnSetting.Builder apnBuilder = new ApnSetting.Builder();
-
-        // Special handling id and entry name. We want to keep the default APN as it could be the
-        // preferred APN.
-        apnBuilder.setId(apn1.getId());
-        apnBuilder.setEntryName(apn1.getEntryName());
-        if (apn2.canHandleType(ApnSetting.TYPE_DEFAULT)
-                && !apn1.canHandleType(ApnSetting.TYPE_DEFAULT)) {
-            apnBuilder.setId(apn2.getId());
-            apnBuilder.setEntryName(apn2.getEntryName());
-        }
-
-        // Merge the following fields from apn1 and apn2.
-        apnBuilder.setProxyAddress(TextUtils.isEmpty(apn2.getProxyAddressAsString())
-                ? apn1.getProxyAddressAsString() : apn2.getProxyAddressAsString());
-        apnBuilder.setProxyPort(apn2.getProxyPort() == -1
-                ? apn1.getProxyPort() : apn2.getProxyPort());
-        apnBuilder.setMmsc(apn2.getMmsc() == null ? apn1.getMmsc() : apn2.getMmsc());
-        apnBuilder.setMmsProxyAddress(TextUtils.isEmpty(apn2.getMmsProxyAddressAsString())
-                ? apn1.getMmsProxyAddressAsString() : apn2.getMmsProxyAddressAsString());
-        apnBuilder.setMmsProxyPort(apn2.getMmsProxyPort() == -1
-                ? apn1.getMmsProxyPort() : apn2.getMmsProxyPort());
-        apnBuilder.setUser(TextUtils.isEmpty(apn2.getUser()) ? apn1.getUser() : apn2.getUser());
-        apnBuilder.setPassword(TextUtils.isEmpty(apn2.getPassword())
-                ? apn1.getPassword() : apn2.getPassword());
-        apnBuilder.setAuthType(apn2.getAuthType() == -1
-                ? apn1.getAuthType() : apn2.getAuthType());
-        apnBuilder.setApnTypeBitmask(apn1.getApnTypeBitmask() | apn2.getApnTypeBitmask());
-        apnBuilder.setMtuV4(apn2.getMtuV4() <= ApnSetting.UNSET_MTU
-                ? apn1.getMtuV4() : apn2.getMtuV4());
-        apnBuilder.setMtuV6(apn2.getMtuV6() <= ApnSetting.UNSET_MTU
-                ? apn1.getMtuV6() : apn2.getMtuV6());
-
-        // The following fields in apn1 and apn2 should be the same, otherwise ApnSetting.similar()
-        // should fail earlier.
-        apnBuilder.setApnName(apn1.getApnName());
-        apnBuilder.setProtocol(apn1.getProtocol());
-        apnBuilder.setRoamingProtocol(apn1.getRoamingProtocol());
-        apnBuilder.setCarrierEnabled(apn1.isEnabled());
-        apnBuilder.setNetworkTypeBitmask(apn1.getNetworkTypeBitmask());
-        apnBuilder.setLingeringNetworkTypeBitmask(apn1.getLingeringNetworkTypeBitmask());
-        apnBuilder.setProfileId(apn1.getProfileId());
-        apnBuilder.setPersistent(apn1.isPersistent());
-        apnBuilder.setMaxConns(apn1.getMaxConns());
-        apnBuilder.setWaitTime(apn1.getWaitTime());
-        apnBuilder.setMaxConnsTime(apn1.getMaxConnsTime());
-        apnBuilder.setMvnoType(apn1.getMvnoType());
-        apnBuilder.setMvnoMatchData(apn1.getMvnoMatchData());
-        apnBuilder.setApnSetId(apn1.getApnSetId());
-        apnBuilder.setCarrierId(apn1.getCarrierId());
-        apnBuilder.setSkip464Xlat(apn1.getSkip464Xlat());
-        apnBuilder.setAlwaysOn(apn1.isAlwaysOn());
-
-        return new DataProfile.Builder()
-                .setApnSetting(apnBuilder.build())
-                .setTrafficDescriptor(dp1.getTrafficDescriptor())
-                .build();
-    }
-
-    /**
-     * Get data profile by APN name and/or traffic descriptor.
-     *
-     * @param apnName APN name.
-     * @param trafficDescriptor Traffic descriptor.
-     *
-     * @return Data profile by APN name and/or traffic descriptor. Either one of APN name or
-     * traffic descriptor should be provided. {@code null} if data profile is not found.
-     */
-    public @Nullable DataProfile getDataProfile(@Nullable String apnName,
-            @Nullable TrafficDescriptor trafficDescriptor) {
-        if (apnName == null && trafficDescriptor == null) return null;
-
-        List<DataProfile> dataProfiles = mAllDataProfiles;
-
-        // Check if any existing data profile has the same traffic descriptor.
-        if (trafficDescriptor != null) {
-            dataProfiles = mAllDataProfiles.stream()
-                    .filter(dp -> trafficDescriptor.equals(dp.getTrafficDescriptor()))
-                    .collect(Collectors.toList());
-        }
-
-        // Check if any existing data profile has the same APN name.
-        if (apnName != null) {
-            dataProfiles = dataProfiles.stream()
-                    .filter(dp -> dp.getApnSetting() != null
-                            && (dp.getApnSetting().getApnSetId()
-                            == Telephony.Carriers.MATCH_ALL_APN_SET_ID
-                            || dp.getApnSetting().getApnSetId() == mPreferredDataProfileSetId))
-                    .filter(dp -> apnName.equals(dp.getApnSetting().getApnName()))
-                    .collect(Collectors.toList());
-        }
-
-        return dataProfiles.isEmpty() ? null : dataProfiles.get(0);
-    }
-
-    /**
-     * Register the callback for receiving information from {@link DataProfileManager}.
-     *
-     * @param callback The callback.
-     */
-    public void registerCallback(@NonNull DataProfileManagerCallback callback) {
-        mDataProfileManagerCallbacks.add(callback);
-    }
-
-    /**
-     * Unregister the previously registered {@link DataProfileManagerCallback}.
-     *
-     * @param callback The callback to unregister.
-     */
-    public void unregisterCallback(@NonNull DataProfileManagerCallback callback) {
-        mDataProfileManagerCallbacks.remove(callback);
-    }
-
-    /**
-     * Log debug messages.
-     * @param s debug messages
-     */
-    private void log(@NonNull String s) {
-        Rlog.d(mLogTag, s);
-    }
-
-    /**
-     * Log error messages.
-     * @param s error messages
-     */
-    private void loge(@NonNull String s) {
-        Rlog.e(mLogTag, s);
-    }
-
-    /**
-     * Log verbose messages.
-     * @param s debug messages.
-     */
-    private void logv(@NonNull String s) {
-        if (VDBG) Rlog.v(mLogTag, s);
-    }
-
-    /**
-     * Log debug messages and also log into the local log.
-     * @param s debug messages
-     */
-    private void logl(@NonNull String s) {
-        log(s);
-        mLocalLog.log(s);
-    }
-
-    /**
-     * Dump the state of DataProfileManager
-     *
-     * @param fd File descriptor
-     * @param printWriter Print writer
-     * @param args Arguments
-     */
-    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
-        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
-        pw.println(DataProfileManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":");
-        pw.increaseIndent();
-
-        pw.println("Data profiles for the current carrier:");
-        pw.increaseIndent();
-        for (DataProfile dp : mAllDataProfiles) {
-            pw.print(dp);
-            pw.println(", last setup time: " + DataUtils.elapsedTimeToString(
-                    dp.getLastSetupTimestamp()));
-        }
-        pw.decreaseIndent();
-
-        pw.println("Preferred data profile=" + mPreferredDataProfile);
-        pw.println("Preferred data profile from db=" + getPreferredDataProfileFromDb());
-        pw.println("Preferred data profile from config=" + getPreferredDataProfileFromConfig());
-        pw.println("Preferred data profile set id=" + mPreferredDataProfileSetId);
-        pw.println("Initial attach data profile=" + mInitialAttachDataProfile);
-        pw.println("isTetheringDataProfileExisting=" + isTetheringDataProfileExisting(
-                TelephonyManager.NETWORK_TYPE_LTE));
-
-        pw.println("Local logs:");
-        pw.increaseIndent();
-        mLocalLog.dump(fd, pw, args);
-        pw.decreaseIndent();
-        pw.decreaseIndent();
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/DataRetryManager.java b/src/java/com/android/internal/telephony/data/DataRetryManager.java
deleted file mode 100644
index da86cf4..0000000
--- a/src/java/com/android/internal/telephony/data/DataRetryManager.java
+++ /dev/null
@@ -1,1701 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.ElapsedRealtimeLong;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.NetworkCapabilities;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemClock;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.Annotation.DataFailureCause;
-import android.telephony.Annotation.NetCapability;
-import android.telephony.AnomalyReporter;
-import android.telephony.DataFailCause;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataProfile;
-import android.telephony.data.ThrottleStatus;
-import android.telephony.data.ThrottleStatus.RetryType;
-import android.text.TextUtils;
-import android.util.ArraySet;
-import android.util.IndentingPrintWriter;
-import android.util.LocalLog;
-import android.util.SparseArray;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
-import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
-import com.android.internal.telephony.data.DataProfileManager.DataProfileManagerCallback;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Locale;
-import java.util.Objects;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.Executor;
-import java.util.concurrent.TimeUnit;
-import java.util.stream.Collectors;
-
-/**
- * DataRetryManager manages data network setup retry and its configurations.
- */
-public class DataRetryManager extends Handler {
-    private static final boolean VDBG = false;
-
-    /** Event for data config updated. */
-    private static final int EVENT_DATA_CONFIG_UPDATED = 1;
-
-    /** Event for data setup retry. */
-    private static final int EVENT_DATA_SETUP_RETRY = 3;
-
-    /** Event for data handover retry. */
-    private static final int EVENT_DATA_HANDOVER_RETRY = 4;
-
-    /** Event for data profile/apn unthrottled. */
-    private static final int EVENT_DATA_PROFILE_UNTHROTTLED = 6;
-
-    /** Event for cancelling pending handover retry. */
-    private static final int EVENT_CANCEL_PENDING_HANDOVER_RETRY = 7;
-
-    /**
-     * Event for radio on. This can happen when airplane mode is turned off, or RIL crashes and came
-     * back online.
-     */
-    private static final int EVENT_RADIO_ON = 8;
-
-    /** Event for modem reset. */
-    private static final int EVENT_MODEM_RESET = 9;
-
-    /** Event for tracking area code change. */
-    private static final int EVENT_TAC_CHANGED = 10;
-
-    /** The maximum entries to preserve. */
-    private static final int MAXIMUM_HISTORICAL_ENTRIES = 100;
-
-    @IntDef(prefix = {"RESET_REASON_"},
-            value = {
-                    RESET_REASON_DATA_PROFILES_CHANGED,
-                    RESET_REASON_RADIO_ON,
-                    RESET_REASON_MODEM_RESTART,
-                    RESET_REASON_DATA_SERVICE_BOUND,
-                    RESET_REASON_DATA_CONFIG_CHANGED,
-                    RESET_REASON_TAC_CHANGED,
-            })
-    public @interface RetryResetReason {}
-
-    /** Reset due to data profiles changed. */
-    private static final int RESET_REASON_DATA_PROFILES_CHANGED = 1;
-
-    /** Reset due to radio on. This could happen after airplane mode off or RIL restarted. */
-    private static final int RESET_REASON_RADIO_ON = 2;
-
-    /** Reset due to modem restarted. */
-    private static final int RESET_REASON_MODEM_RESTART = 3;
-
-    /**
-     * Reset due to data service bound. This could happen when reboot or when data service crashed
-     * and rebound.
-     */
-    private static final int RESET_REASON_DATA_SERVICE_BOUND = 4;
-
-    /** Reset due to data config changed. */
-    private static final int RESET_REASON_DATA_CONFIG_CHANGED = 5;
-
-    /** Reset due to tracking area code changed. */
-    private static final int RESET_REASON_TAC_CHANGED = 6;
-
-    /** The phone instance. */
-    private final @NonNull Phone mPhone;
-
-    /** The RIL instance. */
-    private final @NonNull CommandsInterface mRil;
-
-    /** Logging tag. */
-    private final @NonNull String mLogTag;
-
-    /** Local log. */
-    private final @NonNull LocalLog mLocalLog = new LocalLog(128);
-
-    /**
-     * The data retry callback. This is only used to notify {@link DataNetworkController} to retry
-     * setup data network.
-     */
-    private @NonNull Set<DataRetryManagerCallback> mDataRetryManagerCallbacks = new ArraySet<>();
-
-    /** Data service managers. */
-    private @NonNull SparseArray<DataServiceManager> mDataServiceManagers;
-
-    /** Data config manager instance. */
-    private final @NonNull DataConfigManager mDataConfigManager;
-
-    /** Data profile manager. */
-    private final @NonNull DataProfileManager mDataProfileManager;
-
-    /** Data setup retry rule list. */
-    private @NonNull List<DataSetupRetryRule> mDataSetupRetryRuleList = new ArrayList<>();
-
-    /** Data handover retry rule list. */
-    private @NonNull List<DataHandoverRetryRule> mDataHandoverRetryRuleList = new ArrayList<>();
-
-    /** Data retry entries. */
-    private final @NonNull List<DataRetryEntry> mDataRetryEntries = new ArrayList<>();
-
-    /**
-     * Data throttling entries. Note this only stores throttling requested by networks. We intended
-     * not to store frameworks-initiated throttling because they are not explicit/strong throttling
-     * requests.
-     */
-    private final @NonNull List<DataThrottlingEntry> mDataThrottlingEntries = new ArrayList<>();
-
-    /**
-     * Represent a single data setup/handover throttling reported by networks.
-     */
-    public static class DataThrottlingEntry {
-        /**
-         * The data profile that is being throttled for setup/handover retry.
-         */
-        public final @NonNull DataProfile dataProfile;
-
-        /**
-         * The associated network request list when throttling happened. Should be {@code null} when
-         * retry type is {@link ThrottleStatus#RETRY_TYPE_HANDOVER}.
-         */
-        public final @Nullable NetworkRequestList networkRequestList;
-
-        /**
-         * @param dataNetwork The data network that is being throttled for handover retry. Should be
-         * {@code null} when retryType is {@link ThrottleStatus#RETRY_TYPE_NEW_CONNECTION}.
-         */
-        public final @Nullable DataNetwork dataNetwork;
-
-        /** The transport that the data profile has been throttled on. */
-        public final @TransportType int transport;
-
-        /** The retry type when throttling expires. */
-        public final @RetryType int retryType;
-
-        /**
-         * The expiration time of data throttling. This is the time retrieved from
-         * {@link SystemClock#elapsedRealtime()}.
-         */
-        public final @ElapsedRealtimeLong long expirationTimeMillis;
-
-        /**
-         * Constructor.
-         *
-         * @param dataProfile The data profile that is being throttled for setup/handover retry.
-         * @param networkRequestList The associated network request list when throttling happened.
-         * Should be {@code null} when retry type is {@link ThrottleStatus#RETRY_TYPE_HANDOVER}.
-         * @param dataNetwork The data network that is being throttled for handover retry.
-         * Should be {@code null} when retryType is
-         * {@link ThrottleStatus#RETRY_TYPE_NEW_CONNECTION}.
-         * @param transport The transport that the data profile has been throttled on.
-         * @param retryType The retry type when throttling expires.
-         * @param expirationTimeMillis The expiration elapsed time of data throttling.
-         */
-        public DataThrottlingEntry(@NonNull DataProfile dataProfile,
-                @Nullable NetworkRequestList networkRequestList,
-                @Nullable DataNetwork dataNetwork, @TransportType int transport,
-                @RetryType int retryType, @ElapsedRealtimeLong long expirationTimeMillis) {
-            this.dataProfile = dataProfile;
-            this.networkRequestList = networkRequestList;
-            this.dataNetwork = dataNetwork;
-            this.transport = transport;
-            this.retryType = retryType;
-            this.expirationTimeMillis = expirationTimeMillis;
-        }
-
-        @Override
-        public @NonNull String toString() {
-            return "[DataThrottlingEntry: dataProfile=" + dataProfile + ", request list="
-                    + networkRequestList + ", dataNetwork=" + dataNetwork + ", transport="
-                    + AccessNetworkConstants.transportTypeToString(transport) + ", expiration time="
-                    + DataUtils.elapsedTimeToString(expirationTimeMillis) + "]";
-        }
-    }
-
-    /**
-     * Represent a data retry rule. A rule consists a retry type (e.g. either by capabilities,
-     * fail cause, or both), and a retry interval.
-     */
-    public static class DataRetryRule {
-        private static final String RULE_TAG_FAIL_CAUSES = "fail_causes";
-        private static final String RULE_TAG_RETRY_INTERVAL = "retry_interval";
-        private static final String RULE_TAG_MAXIMUM_RETRIES = "maximum_retries";
-
-        /**
-         * The data network setup retry interval. Note that if this is empty, then
-         * {@link #getMaxRetries()} must return 0. Default retry interval is 5 seconds.
-         */
-        protected List<Long> mRetryIntervalsMillis = List.of(TimeUnit.SECONDS.toMillis(5));
-
-        /**
-         * The maximum retry times. After reaching the retry times, data retry will not be scheduled
-         * with timer. Only environment changes (e.g. Airplane mode, SIM state, RAT, registration
-         * state changes, etc..) can trigger the retry.
-         */
-        protected int mMaxRetries = 10;
-
-        /**
-         * The network capabilities. Each data setup must be
-         * associated with at least one network request. If that network request contains network
-         * capabilities specified here, then retry will happen. Empty set indicates the retry rule
-         * is not using network capabilities.
-         */
-        protected @NonNull @NetCapability Set<Integer> mNetworkCapabilities = new ArraySet<>();
-
-        /**
-         * The fail causes. If data setup failed with certain fail causes, then retry will happen.
-         * Empty set indicates the retry rule is not using the fail causes.
-         */
-        protected @NonNull @DataFailureCause Set<Integer> mFailCauses = new ArraySet<>();
-
-        public DataRetryRule(@NonNull String ruleString) {
-            if (TextUtils.isEmpty(ruleString)) {
-                throw new IllegalArgumentException("illegal rule " + ruleString);
-            }
-            ruleString = ruleString.trim().toLowerCase(Locale.ROOT);
-            String[] expressions = ruleString.split("\\s*,\\s*");
-            for (String expression : expressions) {
-                String[] tokens = expression.trim().split("\\s*=\\s*");
-                if (tokens.length != 2) {
-                    throw new IllegalArgumentException("illegal rule " + ruleString);
-                }
-                String key = tokens[0].trim();
-                String value = tokens[1].trim();
-                try {
-                    switch (key) {
-                        case RULE_TAG_FAIL_CAUSES:
-                            mFailCauses = Arrays.stream(value.split("\\s*\\|\\s*"))
-                                    .map(String::trim)
-                                    .map(Integer::valueOf)
-                                    .collect(Collectors.toSet());
-                            break;
-                        case RULE_TAG_RETRY_INTERVAL:
-                            mRetryIntervalsMillis = Arrays.stream(value.split("\\s*\\|\\s*"))
-                                    .map(String::trim)
-                                    .map(Long::valueOf)
-                                    .collect(Collectors.toList());
-                            break;
-                        case RULE_TAG_MAXIMUM_RETRIES:
-                            mMaxRetries = Integer.parseInt(value);
-                            break;
-                    }
-                } catch (Exception e) {
-                    e.printStackTrace();
-                    throw new IllegalArgumentException("illegal rule " + ruleString + ", e=" + e);
-                }
-            }
-
-            if (mMaxRetries == 0) {
-                mRetryIntervalsMillis = Collections.emptyList();
-            }
-
-            if (mMaxRetries < 0) {
-                throw new IllegalArgumentException("Max retries should not be less than 0. "
-                        + "mMaxRetries=" + mMaxRetries);
-            }
-
-            if (mRetryIntervalsMillis.stream().anyMatch(i -> i <= 0)) {
-                throw new IllegalArgumentException("Retry interval should not be less than 0. "
-                        + "mRetryIntervalsMillis=" + mRetryIntervalsMillis);
-            }
-        }
-
-        /**
-         * @return The data network setup retry intervals in milliseconds. If this is empty, then
-         * {@link #getMaxRetries()} must return 0.
-         */
-        public @NonNull List<Long> getRetryIntervalsMillis() {
-            return mRetryIntervalsMillis;
-        }
-
-        /**
-         * @return The maximum retry times. After reaching the retry times, data retry will not be
-         * scheduled with timer. Only environment changes (e.g. Airplane mode, SIM state, RAT,
-         * registration state changes, etc..) can trigger the retry. Note that if max retries
-         * is 0, then {@link #getRetryIntervalsMillis()} must be {@code null}.
-         */
-        public int getMaxRetries() {
-            return mMaxRetries;
-        }
-
-        /**
-         * @return The fail causes. If data setup failed with certain fail causes, then retry will
-         * happen. Empty set indicates the retry rule is not using the fail causes.
-         */
-        @VisibleForTesting
-        public @NonNull @DataFailureCause Set<Integer> getFailCauses() {
-            return mFailCauses;
-        }
-    }
-
-    /**
-     * Represent a setup data network retry rule.
-     *
-     * The syntax of the retry rule:
-     * 1. Retry based on {@link NetworkCapabilities}. Note that only APN-type network
-     * capabilities are supported.
-     * "capabilities=[netCaps1|netCaps2|...], [retry_interval=n1|n2|n3|n4...],
-     * [maximum_retries=n]"
-     *
-     * 2. Retry based on {@link DataFailCause}
-     * "fail_causes=[cause1|cause2|cause3|..], [retry_interval=n1|n2|n3|n4...],
-     * [maximum_retries=n]"
-     *
-     * 3. Retry based on {@link NetworkCapabilities} and {@link DataFailCause}. Note that only
-     *    APN-type network capabilities are supported.
-     * "capabilities=[netCaps1|netCaps2|...], fail_causes=[cause1|cause2|cause3|...],
-     *     [retry_interval=n1|n2|n3|n4...], [maximum_retries=n]"
-     *
-     * For example,
-     * "capabilities=eims, retry_interval=1000, maximum_retries=20" means if the attached
-     * network request is emergency, then retry data network setup every 1 second for up to 20
-     * times.
-     *
-     * "fail_causes=8|27|28|29|30|32|33|35|50|51|111|-5|-6|65537|65538|-3|2253|2254
-     * , maximum_retries=0" means for those fail causes, never retry with timers. Note that
-     * when environment changes, retry can still happen.
-     *
-     * "capabilities=internet|enterprise|dun|ims|fota, retry_interval=2500|3000|"
-     * "5000|10000|15000|20000|40000|60000|120000|240000|600000|1200000|1800000"
-     * "1800000, maximum_retries=20" means for those capabilities, retry happens in 2.5s, 3s,
-     * 5s, 10s, 15s, 20s, 40s, 1m, 2m, 4m, 10m, 20m, 30m, 30m, 30m, until reaching 20 retries.
-     */
-    public static class DataSetupRetryRule extends DataRetryRule {
-        private static final String RULE_TAG_CAPABILITIES = "capabilities";
-        /**
-         * Constructor
-         *
-         * @param ruleString The retry rule in string format.
-         * @throws IllegalArgumentException if the string can't be parsed to a retry rule.
-         */
-        public DataSetupRetryRule(@NonNull String ruleString) {
-            super(ruleString);
-
-            ruleString = ruleString.trim().toLowerCase(Locale.ROOT);
-            String[] expressions = ruleString.split("\\s*,\\s*");
-            for (String expression : expressions) {
-                String[] tokens = expression.trim().split("\\s*=\\s*");
-                if (tokens.length != 2) {
-                    throw new IllegalArgumentException("illegal rule " + ruleString);
-                }
-                String key = tokens[0].trim();
-                String value = tokens[1].trim();
-                if (key.equals(RULE_TAG_CAPABILITIES)) {
-                    mNetworkCapabilities = DataUtils.getNetworkCapabilitiesFromString(value);
-                }
-            }
-
-            if (mFailCauses.isEmpty() && (mNetworkCapabilities.isEmpty()
-                    || mNetworkCapabilities.contains(-1))) {
-                throw new IllegalArgumentException("illegal rule " + ruleString
-                            + ". Should have either valid network capabilities or fail causes.");
-            }
-        }
-
-        /**
-         * @return The network capabilities. Each data setup must be associated with at least one
-         * network request. If that network request contains network capabilities specified here,
-         * then retry will happen. Empty set indicates the retry rule is not using network
-         * capabilities.
-         */
-        @VisibleForTesting
-        public @NonNull @NetCapability Set<Integer> getNetworkCapabilities() {
-            return mNetworkCapabilities;
-        }
-
-        /**
-         * Check if this rule can be matched.
-         *
-         * @param networkCapability The network capability for matching.
-         * @param cause Fail cause from previous setup data request.
-         * @return {@code true} if the retry rule can be matched.
-         */
-        public boolean canBeMatched(@NonNull @NetCapability int networkCapability,
-                @DataFailureCause int cause) {
-            if (!mFailCauses.isEmpty() && !mFailCauses.contains(cause)) {
-                return false;
-            }
-
-            return mNetworkCapabilities.isEmpty()
-                    || mNetworkCapabilities.contains(networkCapability);
-        }
-
-        @Override
-        public String toString() {
-            return "[DataSetupRetryRule: Network capabilities:"
-                    + DataUtils.networkCapabilitiesToString(mNetworkCapabilities.stream()
-                    .mapToInt(Number::intValue).toArray())
-                    + ", Fail causes=" + mFailCauses
-                    + ", Retry intervals=" + mRetryIntervalsMillis + ", Maximum retries="
-                    + mMaxRetries + "]";
-        }
-    }
-
-    /**
-     * Represent a handover data network retry rule.
-     *
-     * The syntax of the retry rule:
-     * 1. Retry when handover fails.
-     * "retry_interval=[n1|n2|n3|...], [maximum_retries=n]"
-     *
-     * For example,
-     * "retry_interval=1000|3000|5000, maximum_retries=10" means handover retry will happen in 1s,
-     * 3s, 5s, 5s, 5s....up to 10 times.
-     *
-     * 2. Retry when handover fails with certain fail causes.
-     * "retry_interval=[n1|n2|n3|...], fail_causes=[cause1|cause2|cause3|...], [maximum_retries=n]
-     *
-     * For example,
-     * "retry_interval=1000, maximum_retries=3, fail_causes=5" means handover retry every 1 second
-     * for up to 3 times when handover fails with the cause 5.
-     *
-     * "maximum_retries=0, fail_causes=6|10|67" means handover retry should not happen for those
-     * causes.
-     */
-    public static class DataHandoverRetryRule extends DataRetryRule {
-        /**
-         * Constructor
-         *
-         * @param ruleString The retry rule in string format.
-         * @throws IllegalArgumentException if the string can't be parsed to a retry rule.
-         */
-        public DataHandoverRetryRule(@NonNull String ruleString) {
-            super(ruleString);
-        }
-
-        @Override
-        public String toString() {
-            return "[DataHandoverRetryRule: Retry intervals=" + mRetryIntervalsMillis
-                    + ", Fail causes=" + mFailCauses + ", Maximum retries=" + mMaxRetries + "]";
-        }
-    }
-
-    /**
-     * Represent a data retry entry.
-     */
-    public static class DataRetryEntry {
-        /** Indicates the retry is not happened yet. */
-        public static final int RETRY_STATE_NOT_RETRIED = 1;
-
-        /** Indicates the retry happened, but still failed to setup/handover the data network. */
-        public static final int RETRY_STATE_FAILED = 2;
-
-        /** Indicates the retry happened and succeeded. */
-        public static final int RETRY_STATE_SUCCEEDED = 3;
-
-        /** Indicates the retry was cancelled. */
-        public static final int RETRY_STATE_CANCELLED = 4;
-
-        @IntDef(prefix = {"RETRY_STATE_"},
-                value = {
-                        RETRY_STATE_NOT_RETRIED,
-                        RETRY_STATE_FAILED,
-                        RETRY_STATE_SUCCEEDED,
-                        RETRY_STATE_CANCELLED
-                })
-        public @interface DataRetryState {}
-
-        /** The rule used for this data retry. {@code null} if the retry is requested by network. */
-        public final @Nullable DataRetryRule appliedDataRetryRule;
-
-        /** The retry delay in milliseconds. */
-        public final long retryDelayMillis;
-
-        /**
-         * Retry elapsed time. This is the system elapsed time retrieved from
-         * {@link SystemClock#elapsedRealtime()}.
-         */
-        public final @ElapsedRealtimeLong long retryElapsedTime;
-
-        /** The retry state. */
-        protected int mRetryState = RETRY_STATE_NOT_RETRIED;
-
-        /** Timestamp when a state is set. For debugging purposes only. */
-        protected @ElapsedRealtimeLong long mRetryStateTimestamp = 0;
-
-        /**
-         * Constructor
-         *
-         * @param appliedDataRetryRule The applied data retry rule.
-         * @param retryDelayMillis The retry delay in milliseconds.
-         */
-        public DataRetryEntry(@Nullable DataRetryRule appliedDataRetryRule, long retryDelayMillis) {
-            this.appliedDataRetryRule = appliedDataRetryRule;
-            this.retryDelayMillis = retryDelayMillis;
-
-            mRetryStateTimestamp = SystemClock.elapsedRealtime();
-            retryElapsedTime =  mRetryStateTimestamp + retryDelayMillis;
-        }
-
-        /**
-         * Set the state of a data retry.
-         *
-         * @param state The retry state.
-         */
-        public void setState(@DataRetryState int state) {
-            mRetryState = state;
-            mRetryStateTimestamp = SystemClock.elapsedRealtime();
-        }
-
-        /**
-         * @return Get the retry state.
-         */
-        public @DataRetryState int getState() {
-            return mRetryState;
-        }
-
-        /**
-         * Convert retry state to string.
-         *
-         * @param retryState Retry state.
-         * @return Retry state in string format.
-         */
-        public static String retryStateToString(@DataRetryState int retryState) {
-            switch (retryState) {
-                case RETRY_STATE_NOT_RETRIED: return "NOT_RETRIED";
-                case RETRY_STATE_FAILED: return "FAILED";
-                case RETRY_STATE_SUCCEEDED: return "SUCCEEDED";
-                case RETRY_STATE_CANCELLED: return "CANCELLED";
-                default: return "Unknown(" + retryState + ")";
-            }
-        }
-
-        /**
-         * The generic builder for retry entry.
-         *
-         * @param <T> The type of extended retry entry builder.
-         */
-        public static class Builder<T extends Builder<T>> {
-            /**
-             * The retry delay in milliseconds. Default is 5 seconds.
-             */
-            protected long mRetryDelayMillis = TimeUnit.SECONDS.toMillis(5);
-
-            /** The applied data retry rule. */
-            protected @Nullable DataRetryRule mAppliedDataRetryRule;
-
-            /**
-             * Set the data retry delay.
-             *
-             * @param retryDelayMillis The retry delay in milliseconds.
-             * @return This builder.
-             */
-            public @NonNull T setRetryDelay(long retryDelayMillis) {
-                mRetryDelayMillis = retryDelayMillis;
-                return (T) this;
-            }
-
-            /**
-             * Set the applied retry rule.
-             *
-             * @param dataRetryRule The rule that used for this data retry.
-             * @return This builder.
-             */
-            public @NonNull T setAppliedRetryRule(@NonNull DataRetryRule dataRetryRule) {
-                mAppliedDataRetryRule = dataRetryRule;
-                return (T) this;
-            }
-        }
-    }
-
-    /**
-     * Represent a setup data retry entry.
-     */
-    public static class DataSetupRetryEntry extends DataRetryEntry {
-        /**
-         * Retry type is unknown. This should be only used for initialized value.
-         */
-        public static final int RETRY_TYPE_UNKNOWN = 0;
-        /**
-         * To retry setup data with the same data profile.
-         */
-        public static final int RETRY_TYPE_DATA_PROFILE = 1;
-
-        /**
-         * To retry satisfying the network request(s). Could be using a
-         * different data profile.
-         */
-        public static final int RETRY_TYPE_NETWORK_REQUESTS = 2;
-
-        @IntDef(prefix = {"RETRY_TYPE_"},
-                value = {
-                        RETRY_TYPE_UNKNOWN,
-                        RETRY_TYPE_DATA_PROFILE,
-                        RETRY_TYPE_NETWORK_REQUESTS,
-                })
-        public @interface SetupRetryType {}
-
-        /** Setup retry type. Could be retry by same data profile or same capability. */
-        public final @SetupRetryType int setupRetryType;
-
-        /** The network requests to satisfy when retry happens. */
-        public final @NonNull NetworkRequestList networkRequestList;
-
-        /** The data profile that will be used for retry. */
-        public final @Nullable DataProfile dataProfile;
-
-        /** The transport to retry data setup. */
-        public final @TransportType int transport;
-
-        /**
-         * Constructor
-         *
-         * @param setupRetryType Data retry type. Could be retry by same data profile or same
-         * capabilities.
-         * @param networkRequestList The network requests to satisfy when retry happens.
-         * @param dataProfile The data profile that will be used for retry.
-         * @param transport The transport to retry data setup.
-         * @param appliedDataSetupRetryRule The applied data setup retry rule.
-         * @param retryDelayMillis The retry delay in milliseconds.
-         */
-        private DataSetupRetryEntry(@SetupRetryType int setupRetryType,
-                @Nullable NetworkRequestList networkRequestList, @NonNull DataProfile dataProfile,
-                @TransportType int transport,
-                @Nullable DataSetupRetryRule appliedDataSetupRetryRule, long retryDelayMillis) {
-            super(appliedDataSetupRetryRule, retryDelayMillis);
-            this.setupRetryType = setupRetryType;
-            this.networkRequestList = networkRequestList;
-            this.dataProfile = dataProfile;
-            this.transport = transport;
-        }
-
-        /**
-         * Convert retry type to string.
-         *
-         * @param setupRetryType Data setup retry type.
-         * @return Retry type in string format.
-         */
-        private static String retryTypeToString(@SetupRetryType int setupRetryType) {
-            switch (setupRetryType) {
-                case RETRY_TYPE_DATA_PROFILE: return "BY_PROFILE";
-                case RETRY_TYPE_NETWORK_REQUESTS: return "BY_NETWORK_REQUESTS";
-                default: return "Unknown(" + setupRetryType + ")";
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "[DataSetupRetryEntry: delay=" + retryDelayMillis + "ms, retry time:"
-                    + DataUtils.elapsedTimeToString(retryElapsedTime) + ", " + dataProfile
-                    + ", transport=" + AccessNetworkConstants.transportTypeToString(transport)
-                    + ", retry type=" + retryTypeToString(setupRetryType) + ", retry requests="
-                    + networkRequestList + ", applied rule=" + appliedDataRetryRule + ", state="
-                    + retryStateToString(mRetryState) + ", timestamp="
-                    + DataUtils.elapsedTimeToString(mRetryStateTimestamp) + "]";
-        }
-
-        /**
-         * The builder of {@link DataSetupRetryEntry}.
-         *
-         * @param <T> Type of the builder.
-         */
-        public static class Builder<T extends Builder<T>> extends DataRetryEntry.Builder<T> {
-            /** Data setup retry type. Could be retry by same data profile or same capabilities. */
-            private @SetupRetryType int mSetupRetryType = RETRY_TYPE_UNKNOWN;
-
-            /** The network requests to satisfy when retry happens. */
-            private @NonNull NetworkRequestList mNetworkRequestList;
-
-            /** The data profile that will be used for retry. */
-            private @Nullable DataProfile mDataProfile;
-
-            /** The transport to retry data setup. */
-            private @TransportType int mTransport = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
-
-            /**
-             * Set the data retry type.
-             *
-             * @param setupRetryType Data retry type. Could be retry by same data profile or same
-             * capabilities.
-             * @return This builder.
-             */
-            public @NonNull Builder<T> setSetupRetryType(@SetupRetryType int setupRetryType) {
-                mSetupRetryType = setupRetryType;
-                return this;
-            }
-
-            /**
-             * Set the network capability to satisfy when retry happens.
-             *
-             * @param networkRequestList The network requests to satisfy when retry happens.
-             * @return This builder.
-             */
-            public @NonNull Builder<T> setNetworkRequestList(
-                    @NonNull NetworkRequestList networkRequestList) {
-                mNetworkRequestList = networkRequestList;
-                return this;
-            }
-
-            /**
-             * Set the data profile that will be used for retry.
-             *
-             * @param dataProfile The data profile that will be used for retry.
-             * @return This builder.
-             */
-            public @NonNull Builder<T> setDataProfile(@NonNull DataProfile dataProfile) {
-                mDataProfile = dataProfile;
-                return this;
-            }
-
-            /**
-             * Set the transport of the data setup retry.
-             *
-             * @param transport The transport to retry data setup.
-             * @return This builder.
-             */
-            public @NonNull Builder<T> setTransport(@TransportType int transport) {
-                mTransport = transport;
-                return this;
-            }
-
-            /**
-             * Build the instance of {@link DataSetupRetryEntry}.
-             *
-             * @return The instance of {@link DataSetupRetryEntry}.
-             */
-            public @NonNull DataSetupRetryEntry build() {
-                if (mNetworkRequestList == null) {
-                    throw new IllegalArgumentException("network request list is not specified.");
-                }
-                if (mTransport != AccessNetworkConstants.TRANSPORT_TYPE_WWAN
-                        && mTransport != AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
-                    throw new IllegalArgumentException("Invalid transport type " + mTransport);
-                }
-                if (mSetupRetryType != RETRY_TYPE_DATA_PROFILE
-                        && mSetupRetryType != RETRY_TYPE_NETWORK_REQUESTS) {
-                    throw new IllegalArgumentException("Invalid setup retry type "
-                            + mSetupRetryType);
-                }
-                return new DataSetupRetryEntry(mSetupRetryType, mNetworkRequestList, mDataProfile,
-                        mTransport, (DataSetupRetryRule) mAppliedDataRetryRule, mRetryDelayMillis);
-            }
-        }
-    }
-
-    /**
-     * Represent a data handover retry entry.
-     */
-    public static class DataHandoverRetryEntry extends DataRetryEntry {
-        /** The data network to be retried for handover. */
-        public final @NonNull DataNetwork dataNetwork;
-
-        /**
-         * Constructor.
-         *
-         * @param dataNetwork The data network to be retried for handover.
-         * @param appliedDataHandoverRetryRule The applied data retry rule.
-         * @param retryDelayMillis The retry delay in milliseconds.
-         */
-        public DataHandoverRetryEntry(@NonNull DataNetwork dataNetwork,
-                @Nullable DataHandoverRetryRule appliedDataHandoverRetryRule,
-                long retryDelayMillis) {
-            super(appliedDataHandoverRetryRule, retryDelayMillis);
-            this.dataNetwork = dataNetwork;
-        }
-
-        @Override
-        public String toString() {
-            return "[DataHandoverRetryEntry: delay=" + retryDelayMillis + "ms, retry time:"
-                    + DataUtils.elapsedTimeToString(retryElapsedTime) + ", " + dataNetwork
-                     + ", applied rule=" + appliedDataRetryRule + ", state="
-                    + retryStateToString(mRetryState) + ", timestamp="
-                    + DataUtils.elapsedTimeToString(mRetryStateTimestamp) + "]";
-        }
-
-        /**
-         * The builder of {@link DataHandoverRetryEntry}.
-         *
-         * @param <T> Type of the builder.
-         */
-        public static class Builder<T extends Builder<T>> extends DataRetryEntry.Builder<T> {
-            /** The data network to be retried for handover. */
-            public @NonNull DataNetwork mDataNetwork;
-
-            /**
-             * Set the data retry type.
-             *
-             * @param dataNetwork The data network to be retried for handover.
-             *
-             * @return This builder.
-             */
-            public @NonNull Builder<T> setDataNetwork(@NonNull DataNetwork dataNetwork) {
-                mDataNetwork = dataNetwork;
-                return this;
-            }
-
-            /**
-             * Build the instance of {@link DataHandoverRetryEntry}.
-             *
-             * @return The instance of {@link DataHandoverRetryEntry}.
-             */
-            public @NonNull DataHandoverRetryEntry build() {
-                return new DataHandoverRetryEntry(mDataNetwork,
-                        (DataHandoverRetryRule) mAppliedDataRetryRule, mRetryDelayMillis);
-            }
-        }
-    }
-
-    /** Data retry callback. */
-    public static class DataRetryManagerCallback extends DataCallback {
-        /**
-         * Constructor
-         *
-         * @param executor The executor of the callback.
-         */
-        public DataRetryManagerCallback(@NonNull @CallbackExecutor Executor executor) {
-            super(executor);
-        }
-
-        /**
-         * Called when data setup retry occurs.
-         *
-         * @param dataSetupRetryEntry The data setup retry entry.
-         */
-        public void onDataNetworkSetupRetry(@NonNull DataSetupRetryEntry dataSetupRetryEntry) {}
-
-        /**
-         * Called when data handover retry occurs.
-         *
-         * @param dataHandoverRetryEntry The data handover retry entry.
-         */
-        public void onDataNetworkHandoverRetry(
-                @NonNull DataHandoverRetryEntry dataHandoverRetryEntry) {}
-
-        /**
-         * Called when retry manager determines that the retry will no longer be performed on
-         * this data network.
-         *
-         * @param dataNetwork The data network that will never be retried handover.
-         */
-        public void onDataNetworkHandoverRetryStopped(@NonNull DataNetwork dataNetwork) {}
-
-        /**
-         * Called when throttle status changed reported from network.
-         *
-         * @param throttleStatusList List of throttle status.
-         */
-        public void onThrottleStatusChanged(@NonNull List<ThrottleStatus> throttleStatusList) {}
-    }
-
-    /**
-     * Constructor
-     *
-     * @param phone The phone instance.
-     * @param dataNetworkController Data network controller.
-     * @param looper The looper to be used by the handler. Currently the handler thread is the
-     * phone process's main thread.
-     * @param dataRetryManagerCallback Data retry callback.
-     */
-    public DataRetryManager(@NonNull Phone phone,
-            @NonNull DataNetworkController dataNetworkController,
-            @NonNull SparseArray<DataServiceManager> dataServiceManagers,
-            @NonNull Looper looper, @NonNull DataRetryManagerCallback dataRetryManagerCallback) {
-        super(looper);
-        mPhone = phone;
-        mRil = phone.mCi;
-        mLogTag = "DRM-" + mPhone.getPhoneId();
-        mDataRetryManagerCallbacks.add(dataRetryManagerCallback);
-
-        mDataServiceManagers = dataServiceManagers;
-        mDataConfigManager = dataNetworkController.getDataConfigManager();
-        mDataProfileManager = dataNetworkController.getDataProfileManager();
-        mDataConfigManager.registerForConfigUpdate(this, EVENT_DATA_CONFIG_UPDATED);
-
-        mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .registerForApnUnthrottled(this, EVENT_DATA_PROFILE_UNTHROTTLED);
-        if (!mPhone.getAccessNetworksManager().isInLegacyMode()) {
-            mDataServiceManagers.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
-                    .registerForApnUnthrottled(this, EVENT_DATA_PROFILE_UNTHROTTLED);
-        }
-        mDataProfileManager.registerCallback(new DataProfileManagerCallback(this::post) {
-            @Override
-            public void onDataProfilesChanged() {
-                onReset(RESET_REASON_DATA_PROFILES_CHANGED);
-            }
-        });
-        dataNetworkController.registerDataNetworkControllerCallback(
-                new DataNetworkControllerCallback(this::post) {
-                    @Override
-                    public void onDataServiceBound(@TransportType int transport) {
-                        onReset(RESET_REASON_DATA_SERVICE_BOUND);
-                    }
-                });
-        mRil.registerForOn(this, EVENT_RADIO_ON, null);
-        mRil.registerForModemReset(this, EVENT_MODEM_RESET, null);
-
-        if (mDataConfigManager.shouldResetDataThrottlingWhenTacChanges()) {
-            mPhone.getServiceStateTracker().registerForAreaCodeChanged(this, EVENT_TAC_CHANGED,
-                    null);
-        }
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        AsyncResult ar;
-        switch (msg.what) {
-            case EVENT_DATA_CONFIG_UPDATED:
-                onDataConfigUpdated();
-                break;
-            case EVENT_DATA_SETUP_RETRY:
-                DataSetupRetryEntry dataSetupRetryEntry = (DataSetupRetryEntry) msg.obj;
-                Objects.requireNonNull(dataSetupRetryEntry);
-                mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                        () -> callback.onDataNetworkSetupRetry(dataSetupRetryEntry)));
-                break;
-            case EVENT_DATA_HANDOVER_RETRY:
-                DataHandoverRetryEntry dataHandoverRetryEntry = (DataHandoverRetryEntry) msg.obj;
-                Objects.requireNonNull(dataHandoverRetryEntry);
-                if (mDataRetryEntries.contains(dataHandoverRetryEntry)) {
-                    mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                            () -> callback.onDataNetworkHandoverRetry(dataHandoverRetryEntry)));
-                } else {
-                    log("Handover was cancelled earlier. " + dataHandoverRetryEntry);
-                }
-                break;
-            case EVENT_RADIO_ON:
-                onReset(RESET_REASON_RADIO_ON);
-                break;
-            case EVENT_MODEM_RESET:
-                onReset(RESET_REASON_MODEM_RESTART);
-                break;
-            case EVENT_TAC_CHANGED:
-                onReset(RESET_REASON_TAC_CHANGED);
-                break;
-            case EVENT_DATA_PROFILE_UNTHROTTLED:
-                ar = (AsyncResult) msg.obj;
-                int transport = (int) ar.userObj;
-                String apn = null;
-                DataProfile dataProfile = null;
-                // 1.6 or older HAL
-                if (ar.result instanceof String) {
-                    apn = (String) ar.result;
-                } else if (ar.result instanceof DataProfile) {
-                    dataProfile = (DataProfile) ar.result;
-                }
-                onDataProfileUnthrottled(dataProfile, apn, transport, true);
-                break;
-            case EVENT_CANCEL_PENDING_HANDOVER_RETRY:
-                onCancelPendingHandoverRetry((DataNetwork) msg.obj);
-                break;
-            default:
-                loge("Unexpected message " + msg.what);
-        }
-    }
-
-    /**
-     * Called when data config is updated.
-     */
-    private void onDataConfigUpdated() {
-        onReset(RESET_REASON_DATA_CONFIG_CHANGED);
-        mDataSetupRetryRuleList = mDataConfigManager.getDataSetupRetryRules();
-        mDataHandoverRetryRuleList = mDataConfigManager.getDataHandoverRetryRules();
-        log("onDataConfigUpdated: mDataSetupRetryRuleList=" + mDataSetupRetryRuleList
-                + ", mDataHandoverRetryRuleList=" + mDataHandoverRetryRuleList);
-    }
-
-    /**
-     * Evaluate if data setup retry is needed or not. If needed, retry will be scheduled
-     * automatically after evaluation.
-     *
-     * @param dataProfile The data profile that has been used in the previous data network setup.
-     * @param transport The transport to retry data setup.
-     * @param requestList The network requests attached to the previous data network setup.
-     * @param cause The fail cause of previous data network setup.
-     * @param retryDelayMillis The retry delay in milliseconds suggested by the network/data
-     * service. {@link android.telephony.data.DataCallResponse#RETRY_DURATION_UNDEFINED}
-     * indicates network/data service did not suggest retry or not. Telephony frameworks would use
-     * its logic to perform data retry.
-     */
-    public void evaluateDataSetupRetry(@NonNull DataProfile dataProfile,
-            @TransportType int transport, @NonNull NetworkRequestList requestList,
-            @DataFailureCause int cause, long retryDelayMillis) {
-        post(() -> onEvaluateDataSetupRetry(dataProfile, transport, requestList, cause,
-                retryDelayMillis));
-    }
-
-    private void onEvaluateDataSetupRetry(@NonNull DataProfile dataProfile,
-            @TransportType int transport, @NonNull NetworkRequestList requestList,
-            @DataFailureCause int cause, long retryDelayMillis) {
-        logl("onEvaluateDataSetupRetry: " + dataProfile + ", transport="
-                + AccessNetworkConstants.transportTypeToString(transport) + ", cause="
-                + DataFailCause.toString(cause) + ", retryDelayMillis=" + retryDelayMillis + "ms"
-                + ", " + requestList);
-        // Check if network suggested never retry for this data profile. Note that for HAL 1.5
-        // and older, Integer.MAX_VALUE indicates never retry. For 1.6 or above, Long.MAX_VALUE
-        // indicates never retry.
-        if (retryDelayMillis == Long.MAX_VALUE || retryDelayMillis == Integer.MAX_VALUE) {
-            logl("Network suggested never retry for " + dataProfile);
-            // Note that RETRY_TYPE_NEW_CONNECTION is intended here because
-            // when unthrottling happens, we still want to retry and we'll need
-            // a type there so we know what to retry. Using RETRY_TYPE_NONE
-            // ThrottleStatus is just for API backwards compatibility reason.
-            updateThrottleStatus(dataProfile, requestList, null,
-                    ThrottleStatus.RETRY_TYPE_NEW_CONNECTION, transport, Long.MAX_VALUE);
-        } else if (retryDelayMillis != DataCallResponse.RETRY_DURATION_UNDEFINED) {
-            // Network specifically asks retry the previous data profile again.
-            DataSetupRetryEntry dataSetupRetryEntry = new DataSetupRetryEntry.Builder<>()
-                    .setRetryDelay(retryDelayMillis)
-                    .setSetupRetryType(DataSetupRetryEntry.RETRY_TYPE_DATA_PROFILE)
-                    .setNetworkRequestList(requestList)
-                    .setDataProfile(dataProfile)
-                    .setTransport(transport)
-                    .build();
-            updateThrottleStatus(dataProfile, requestList, null,
-                    ThrottleStatus.RETRY_TYPE_NEW_CONNECTION, transport,
-                    dataSetupRetryEntry.retryElapsedTime);
-            schedule(dataSetupRetryEntry);
-        } else {
-            // Network did not suggest any retry. Use the configured rules to perform retry.
-            logv("mDataSetupRetryRuleList=" + mDataSetupRetryRuleList);
-
-            // Support the legacy permanent failure configuration
-            if (DataFailCause.isPermanentFailure(mPhone.getContext(), cause, mPhone.getSubId())) {
-                log("Stopped timer-based retry. cause=" + DataFailCause.toString(cause));
-                return;
-            }
-
-            boolean retryScheduled = false;
-            List<NetworkRequestList> groupedNetworkRequestLists =
-                    DataUtils.getGroupedNetworkRequestList(requestList);
-            for (NetworkRequestList networkRequestList : groupedNetworkRequestLists) {
-                int capability = networkRequestList.get(0).getApnTypeNetworkCapability();
-
-                for (DataSetupRetryRule retryRule : mDataSetupRetryRuleList) {
-                    if (retryRule.canBeMatched(capability, cause)) {
-                        // Check if there is already a similar network request retry scheduled.
-                        if (isSimilarNetworkRequestRetryScheduled(
-                                networkRequestList.get(0), transport)) {
-                            log(networkRequestList.get(0) + " already had similar retry "
-                                    + "scheduled.");
-                            return;
-                        }
-
-                        int failedCount = getRetryFailedCount(capability, retryRule);
-                        log("For capability " + DataUtils.networkCapabilityToString(capability)
-                                + ", found matching rule " + retryRule + ", failed count="
-                                + failedCount);
-                        if (failedCount == retryRule.getMaxRetries()) {
-                            log("Data retry failed for " + failedCount + " times. Stopped "
-                                    + "timer-based data retry for "
-                                    + DataUtils.networkCapabilityToString(capability)
-                                    + ". Condition-based retry will still happen when condition "
-                                    + "changes.");
-                            return;
-                        }
-
-                        retryDelayMillis = retryRule.getRetryIntervalsMillis().get(
-                                Math.min(failedCount, retryRule
-                                        .getRetryIntervalsMillis().size() - 1));
-
-                        // Schedule a data retry.
-                        schedule(new DataSetupRetryEntry.Builder<>()
-                                .setRetryDelay(retryDelayMillis)
-                                .setAppliedRetryRule(retryRule)
-                                .setSetupRetryType(DataSetupRetryEntry.RETRY_TYPE_NETWORK_REQUESTS)
-                                .setTransport(transport)
-                                .setNetworkRequestList(networkRequestList)
-                                .build());
-                        retryScheduled = true;
-                        break;
-                    }
-                }
-            }
-
-            if (!retryScheduled) {
-                log("onEvaluateDataSetupRetry: Did not match any retry rule. Stop timer-based "
-                        + "retry.");
-            }
-        }
-    }
-
-    /**
-     * Evaluate if data handover retry is needed or not. If needed, retry will be scheduled
-     * automatically after evaluation.
-     *
-     * @param dataNetwork The data network to be retried for handover.
-     * @param cause The fail cause of previous data network handover.
-     * @param retryDelayMillis The retry delay in milliseconds suggested by the network/data
-     * service. {@link android.telephony.data.DataCallResponse#RETRY_DURATION_UNDEFINED}
-     * indicates network/data service did not suggest retry or not. Telephony frameworks would use
-     * its logic to perform handover retry.
-     */
-    public void evaluateDataHandoverRetry(@NonNull DataNetwork dataNetwork,
-            @DataFailureCause int cause, long retryDelayMillis) {
-        post(() -> onEvaluateDataHandoverRetry(dataNetwork, cause, retryDelayMillis));
-    }
-
-    private void onEvaluateDataHandoverRetry(@NonNull DataNetwork dataNetwork,
-            @DataFailureCause int cause, long retryDelayMillis) {
-        logl("onEvaluateDataHandoverRetry: " + dataNetwork + ", cause="
-                + DataFailCause.toString(cause) + ", retryDelayMillis=" + retryDelayMillis + "ms");
-        int targetTransport = DataUtils.getTargetTransport(dataNetwork.getTransport());
-        if (retryDelayMillis == Long.MAX_VALUE || retryDelayMillis == Integer.MAX_VALUE) {
-            logl("Network suggested never retry handover for " + dataNetwork);
-            // Note that RETRY_TYPE_HANDOVER is intended here because
-            // when unthrottling happens, we still want to retry and we'll need
-            // a type there so we know what to retry. Using RETRY_TYPE_NONE
-            // ThrottleStatus is just for API backwards compatibility reason.
-            updateThrottleStatus(dataNetwork.getDataProfile(),
-                    dataNetwork.getAttachedNetworkRequestList(), dataNetwork,
-                    ThrottleStatus.RETRY_TYPE_HANDOVER, targetTransport, Long.MAX_VALUE);
-        } else if (retryDelayMillis != DataCallResponse.RETRY_DURATION_UNDEFINED) {
-            // Network specifically asks retry the previous data profile again.
-            DataHandoverRetryEntry dataHandoverRetryEntry = new DataHandoverRetryEntry.Builder<>()
-                    .setRetryDelay(retryDelayMillis)
-                    .setDataNetwork(dataNetwork)
-                    .build();
-
-            updateThrottleStatus(dataNetwork.getDataProfile(),
-                    dataNetwork.getAttachedNetworkRequestList(), dataNetwork,
-                    ThrottleStatus.RETRY_TYPE_HANDOVER, targetTransport,
-                    dataHandoverRetryEntry.retryElapsedTime);
-            schedule(dataHandoverRetryEntry);
-        } else {
-            // Network did not suggest any retry. Use the configured rules to perform retry.
-
-            // Matching the rule in configured order.
-            for (DataHandoverRetryRule retryRule : mDataHandoverRetryRuleList) {
-                if (retryRule.getFailCauses().isEmpty()
-                        || retryRule.getFailCauses().contains(cause)) {
-                    int failedCount = getRetryFailedCount(dataNetwork, retryRule);
-                    log("Found matching rule " + retryRule + ", failed count=" + failedCount);
-                    if (failedCount == retryRule.getMaxRetries()) {
-                        log("Data handover retry failed for " + failedCount + " times. Stopped "
-                                + "handover retry.");
-                        mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                                () -> callback.onDataNetworkHandoverRetryStopped(dataNetwork)));
-                        return;
-                    }
-
-                    retryDelayMillis = retryRule.getRetryIntervalsMillis().get(
-                            Math.min(failedCount, retryRule
-                                    .getRetryIntervalsMillis().size() - 1));
-                    schedule(new DataHandoverRetryEntry.Builder<>()
-                            .setRetryDelay(retryDelayMillis)
-                            .setDataNetwork(dataNetwork)
-                            .setAppliedRetryRule(retryRule)
-                            .build());
-                }
-            }
-        }
-    }
-
-    /** Cancel all retries and throttling entries. */
-    private void onReset(@RetryResetReason int reason) {
-        logl("Remove all retry and throttling entries, reason=" + resetReasonToString(reason));
-        removeMessages(EVENT_DATA_SETUP_RETRY);
-        removeMessages(EVENT_DATA_HANDOVER_RETRY);
-        mDataRetryEntries.stream()
-                .filter(entry -> entry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED)
-                .forEach(entry -> entry.setState(DataRetryEntry.RETRY_STATE_CANCELLED));
-
-        for (DataThrottlingEntry dataThrottlingEntry : mDataThrottlingEntries) {
-            DataProfile dataProfile = dataThrottlingEntry.dataProfile;
-            String apn = dataProfile.getApnSetting() != null
-                    ? dataProfile.getApnSetting().getApnName() : null;
-            onDataProfileUnthrottled(dataProfile, apn, dataThrottlingEntry.transport, false);
-        }
-
-        mDataThrottlingEntries.clear();
-    }
-
-    /**
-     * Count how many times the same setup retry rule has been used for this data network but
-     * failed.
-     *
-     * @param dataNetwork The data network to check.
-     * @param dataRetryRule The data retry rule.
-     * @return The failed count since last successful data setup.
-     */
-    private int getRetryFailedCount(@NonNull DataNetwork dataNetwork,
-            @NonNull DataHandoverRetryRule dataRetryRule) {
-        int count = 0;
-        for (int i = mDataRetryEntries.size() - 1; i >= 0; i--) {
-            if (mDataRetryEntries.get(i) instanceof DataHandoverRetryEntry) {
-                DataHandoverRetryEntry entry = (DataHandoverRetryEntry) mDataRetryEntries.get(i);
-                if (entry.dataNetwork == dataNetwork
-                        && dataRetryRule.equals(entry.appliedDataRetryRule)) {
-                    if (entry.getState() == DataRetryEntry.RETRY_STATE_SUCCEEDED
-                            || entry.getState() == DataRetryEntry.RETRY_STATE_CANCELLED) {
-                        break;
-                    }
-                    count++;
-                }
-            }
-        }
-        return count;
-    }
-
-    /**
-     * Count how many times the same setup retry rule has been used for the capability since
-     * last success data setup.
-     *
-     * @param networkCapability The network capability to check.
-     * @param dataRetryRule The data retry rule.
-     * @return The failed count since last successful data setup.
-     */
-    private int getRetryFailedCount(@NetCapability int networkCapability,
-            @NonNull DataSetupRetryRule dataRetryRule) {
-        int count = 0;
-        for (int i = mDataRetryEntries.size() - 1; i >= 0; i--) {
-            if (mDataRetryEntries.get(i) instanceof DataSetupRetryEntry) {
-                DataSetupRetryEntry entry = (DataSetupRetryEntry) mDataRetryEntries.get(i);
-                // count towards the last succeeded data setup.
-                if (entry.setupRetryType == DataSetupRetryEntry.RETRY_TYPE_NETWORK_REQUESTS) {
-                    if (entry.networkRequestList.isEmpty()) {
-                        String msg = "Invalid data retry entry detected";
-                        logl(msg);
-                        loge("mDataRetryEntries=" + mDataRetryEntries);
-                        AnomalyReporter.reportAnomaly(
-                                UUID.fromString("afeab78c-c0b0-49fc-a51f-f766814d7aa6"),
-                                msg,
-                                mPhone.getCarrierId());
-                        continue;
-                    }
-                    if (entry.networkRequestList.get(0).getApnTypeNetworkCapability()
-                            == networkCapability
-                            && entry.appliedDataRetryRule.equals(dataRetryRule)) {
-                        if (entry.getState() == DataRetryEntry.RETRY_STATE_SUCCEEDED
-                                || entry.getState() == DataRetryEntry.RETRY_STATE_CANCELLED) {
-                            break;
-                        }
-                        count++;
-                    }
-                }
-            }
-        }
-        return count;
-    }
-
-    /**
-     * Schedule the data retry.
-     *
-     * @param dataRetryEntry The data retry entry.
-     */
-    private void schedule(@NonNull DataRetryEntry dataRetryEntry) {
-        logl("Scheduled data retry: " + dataRetryEntry);
-        mDataRetryEntries.add(dataRetryEntry);
-        if (mDataRetryEntries.size() >= MAXIMUM_HISTORICAL_ENTRIES) {
-            // Discard the oldest retry entry.
-            mDataRetryEntries.remove(0);
-        }
-
-        // Using delayed message instead of alarm manager to schedule data retry is intentional.
-        // When the device enters doze mode, the handler message might be extremely delayed than the
-        // original scheduled time. There is no need to wake up the device to perform data retry in
-        // that case.
-        sendMessageDelayed(obtainMessage(dataRetryEntry instanceof DataSetupRetryEntry
-                        ? EVENT_DATA_SETUP_RETRY : EVENT_DATA_HANDOVER_RETRY, dataRetryEntry),
-                dataRetryEntry.retryDelayMillis);
-    }
-
-    /**
-     * Add the latest throttling request and report it to the clients.
-     *
-     * @param dataProfile The data profile that is being throttled for setup/handover retry.
-     * @param networkRequestList The associated network request list when throttling happened.
-     * Can be {@code null} when retry type is {@link ThrottleStatus#RETRY_TYPE_HANDOVER}.
-     * @param dataNetwork The data network that is being throttled for handover retry.
-     * Must be {@code null} when retryType is
-     * {@link ThrottleStatus#RETRY_TYPE_NEW_CONNECTION}.
-     * @param retryType The retry type when throttling expires.
-     * @param transport The transport that the data profile has been throttled on.
-     * @param expirationTime The expiration time of data throttling. This is the time retrieved from
-     * {@link SystemClock#elapsedRealtime()}.
-     */
-    private void updateThrottleStatus(@NonNull DataProfile dataProfile,
-            @Nullable NetworkRequestList networkRequestList,
-            @Nullable DataNetwork dataNetwork, @RetryType int retryType,
-            @TransportType int transport, @ElapsedRealtimeLong long expirationTime) {
-        DataThrottlingEntry entry = new DataThrottlingEntry(dataProfile, networkRequestList,
-                dataNetwork, transport, retryType, expirationTime);
-        if (mDataThrottlingEntries.size() >= MAXIMUM_HISTORICAL_ENTRIES) {
-            mDataThrottlingEntries.remove(0);
-        }
-
-        // Remove previous entry that contains the same data profile.
-        mDataThrottlingEntries.removeIf(
-                throttlingEntry -> dataProfile.equals(throttlingEntry.dataProfile));
-
-
-        logl("Add throttling entry " + entry);
-        mDataThrottlingEntries.add(entry);
-
-        // For backwards compatibility, we use RETRY_TYPE_NONE if network suggests never retry.
-        final int dataRetryType = expirationTime == Long.MAX_VALUE
-                ? ThrottleStatus.RETRY_TYPE_NONE : retryType;
-
-        // Report to the clients.
-        final List<ThrottleStatus> throttleStatusList = new ArrayList<>();
-        if (dataProfile.getApnSetting() != null) {
-            throttleStatusList.addAll(dataProfile.getApnSetting().getApnTypes().stream()
-                    .map(apnType -> new ThrottleStatus.Builder()
-                            .setApnType(apnType)
-                            .setRetryType(dataRetryType)
-                            .setSlotIndex(mPhone.getPhoneId())
-                            .setThrottleExpiryTimeMillis(expirationTime)
-                            .setTransportType(transport)
-                            .build())
-                    .collect(Collectors.toList()));
-        }
-
-        mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                () -> callback.onThrottleStatusChanged(throttleStatusList)));
-    }
-
-    /**
-     * Called when network/modem informed to cancelling the previous throttling request.
-     *
-     * @param dataProfile The data profile to be unthrottled. Note this is only supported on HAL
-     * with AIDL interface. When this is set, {@code apn} must be {@code null}.
-     * @param apn The apn to be unthrottled. Note this should be only used for HIDL 1.6 or below.
-     * When this is set, {@code dataProfile} must be {@code null}.
-     * @param transport The transport that this unthrottling request is on.
-     * @param remove Whether to remove unthrottled entries from the list of entries.
-     */
-    private void onDataProfileUnthrottled(@Nullable DataProfile dataProfile, @Nullable String apn,
-            int transport, boolean remove) {
-        log("onDataProfileUnthrottled: data profile=" + dataProfile + ", apn=" + apn
-                + ", transport=" + AccessNetworkConstants.transportTypeToString(transport)
-                + ", remove=" + remove);
-
-        long now = SystemClock.elapsedRealtime();
-        List<DataThrottlingEntry> dataUnthrottlingEntries = new ArrayList<>();
-        if (dataProfile != null) {
-            // For AIDL-based HAL. There should be only one entry containing this data profile.
-            // Note that the data profile reconstructed from DataProfileInfo.aidl will not be
-            // equal to the data profiles kept in data profile manager (due to some fields missing
-            // in DataProfileInfo.aidl), so we need to get the equivalent data profile from data
-            // profile manager.
-            final DataProfile dp = mDataProfileManager.getDataProfile(
-                    dataProfile.getApnSetting() != null
-                            ? dataProfile.getApnSetting().getApnName() : null,
-                    dataProfile.getTrafficDescriptor());
-            log("onDataProfileUnthrottled: getDataProfile=" + dp);
-            if (dp != null) {
-                dataUnthrottlingEntries = mDataThrottlingEntries.stream()
-                        .filter(entry -> entry.expirationTimeMillis > now
-                                && entry.dataProfile.equals(dp)
-                                && entry.transport == transport)
-                        .collect(Collectors.toList());
-            }
-        } else if (apn != null) {
-            // For HIDL 1.6 or below
-            dataUnthrottlingEntries = mDataThrottlingEntries.stream()
-                    .filter(entry -> entry.expirationTimeMillis > now
-                            && entry.dataProfile.getApnSetting() != null
-                            && apn.equals(entry.dataProfile.getApnSetting().getApnName())
-                            && entry.transport == transport)
-                    .collect(Collectors.toList());
-        }
-
-        if (dataUnthrottlingEntries.isEmpty()) {
-            log("onDataProfileUnthrottled: Nothing to unthrottle.");
-            return;
-        }
-
-        // Report to the clients.
-        final List<ThrottleStatus> throttleStatusList = new ArrayList<>();
-        DataProfile unthrottledProfile = null;
-        int retryType = ThrottleStatus.RETRY_TYPE_NONE;
-        if (dataUnthrottlingEntries.get(0).retryType == ThrottleStatus.RETRY_TYPE_NEW_CONNECTION) {
-            unthrottledProfile = dataUnthrottlingEntries.get(0).dataProfile;
-            retryType = ThrottleStatus.RETRY_TYPE_NEW_CONNECTION;
-        } else if (dataUnthrottlingEntries.get(0).retryType == ThrottleStatus.RETRY_TYPE_HANDOVER) {
-            unthrottledProfile = dataUnthrottlingEntries.get(0).dataNetwork.getDataProfile();
-            retryType = ThrottleStatus.RETRY_TYPE_HANDOVER;
-        }
-
-        // Make it final so it can be used in the lambda function below.
-        final int dataRetryType = retryType;
-
-        if (unthrottledProfile != null && unthrottledProfile.getApnSetting() != null) {
-            throttleStatusList.addAll(unthrottledProfile.getApnSetting().getApnTypes().stream()
-                    .map(apnType -> new ThrottleStatus.Builder()
-                            .setApnType(apnType)
-                            .setSlotIndex(mPhone.getPhoneId())
-                            .setNoThrottle()
-                            .setRetryType(dataRetryType)
-                            .setTransportType(transport)
-                            .build())
-                    .collect(Collectors.toList()));
-        }
-
-        mDataRetryManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                () -> callback.onThrottleStatusChanged(throttleStatusList)));
-
-        logl("onDataProfileUnthrottled: Removing the following throttling entries. "
-                + dataUnthrottlingEntries);
-        for (DataThrottlingEntry entry : dataUnthrottlingEntries) {
-            if (entry.retryType == ThrottleStatus.RETRY_TYPE_NEW_CONNECTION) {
-                // Immediately retry after unthrottling.
-                schedule(new DataSetupRetryEntry.Builder<>()
-                        .setDataProfile(entry.dataProfile)
-                        .setTransport(entry.transport)
-                        .setSetupRetryType(DataSetupRetryEntry.RETRY_TYPE_DATA_PROFILE)
-                        .setNetworkRequestList(entry.networkRequestList)
-                        .setRetryDelay(0)
-                        .build());
-            } else if (entry.retryType == ThrottleStatus.RETRY_TYPE_HANDOVER) {
-                schedule(new DataHandoverRetryEntry.Builder<>()
-                        .setDataNetwork(entry.dataNetwork)
-                        .setRetryDelay(0)
-                        .build());
-            }
-        }
-        if (remove) {
-            mDataThrottlingEntries.removeAll(dataUnthrottlingEntries);
-        }
-    }
-
-    /**
-     * Check if there is any similar network request scheduled to retry. The definition of similar
-     * is that network requests have same APN capability and on the same transport.
-     *
-     * @param networkRequest The network request to check.
-     * @param transport The transport that this request is on.
-     * @return {@code true} if similar network request scheduled to retry.
-     */
-    public boolean isSimilarNetworkRequestRetryScheduled(
-            @NonNull TelephonyNetworkRequest networkRequest, @TransportType int transport) {
-        for (int i = mDataRetryEntries.size() - 1; i >= 0; i--) {
-            if (mDataRetryEntries.get(i) instanceof DataSetupRetryEntry) {
-                DataSetupRetryEntry entry = (DataSetupRetryEntry) mDataRetryEntries.get(i);
-                if (entry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED
-                        && entry.setupRetryType
-                        == DataSetupRetryEntry.RETRY_TYPE_NETWORK_REQUESTS) {
-                    if (entry.networkRequestList.isEmpty()) {
-                        String msg = "Invalid data retry entry detected";
-                        logl(msg);
-                        loge("mDataRetryEntries=" + mDataRetryEntries);
-                        AnomalyReporter.reportAnomaly(
-                                UUID.fromString("781af571-f55d-476d-b510-7a5381f633dc"),
-                                msg,
-                                mPhone.getCarrierId());
-                        continue;
-                    }
-                    if (entry.networkRequestList.get(0).getApnTypeNetworkCapability()
-                            == networkRequest.getApnTypeNetworkCapability()
-                            && entry.transport == transport) {
-                        return true;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Check if there is any data setup retry scheduled with specified data profile.
-     *
-     * @param dataProfile The data profile to retry.
-     * @param transport The transport that the request is on.
-     * @return {@code true} if there is retry scheduled for this data profile.
-     */
-    public boolean isAnySetupRetryScheduled(@NonNull DataProfile dataProfile,
-            @TransportType int transport) {
-        return mDataRetryEntries.stream()
-                .filter(DataSetupRetryEntry.class::isInstance)
-                .map(DataSetupRetryEntry.class::cast)
-                .anyMatch(entry -> entry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED
-                        && dataProfile.equals(entry.dataProfile)
-                        && entry.transport == transport);
-    }
-
-    /**
-     * Check if a specific data profile is explicitly throttled by the network.
-     *
-     * @param dataProfile The data profile to check.
-     * @param transport The transport that the request is on.
-     * @return {@code true} if the data profile is currently throttled.
-     */
-    public boolean isDataProfileThrottled(@NonNull DataProfile dataProfile,
-            @TransportType int transport) {
-        long now = SystemClock.elapsedRealtime();
-        return mDataThrottlingEntries.stream().anyMatch(
-                entry -> entry.dataProfile.equals(dataProfile) && entry.expirationTimeMillis > now
-                        && entry.transport == transport);
-    }
-
-    /**
-     * Cancel pending scheduled handover retry entries.
-     *
-     * @param dataNetwork The data network that was originally scheduled for handover retry.
-     */
-    public void cancelPendingHandoverRetry(@NonNull DataNetwork dataNetwork) {
-        sendMessage(obtainMessage(EVENT_CANCEL_PENDING_HANDOVER_RETRY, dataNetwork));
-    }
-
-    /**
-     * Called when cancelling pending scheduled handover retry entries.
-     *
-     * @param dataNetwork The data network that was originally scheduled for handover retry.
-     */
-    private void onCancelPendingHandoverRetry(@NonNull DataNetwork dataNetwork) {
-        mDataRetryEntries.removeIf(entry -> entry instanceof DataHandoverRetryEntry
-                && ((DataHandoverRetryEntry) entry).dataNetwork == dataNetwork);
-        mDataThrottlingEntries.removeIf(entry -> entry.dataNetwork == dataNetwork);
-    }
-
-    /**
-     * Check if there is any data handover retry scheduled.
-     *
-     * @param dataNetwork The network network to retry handover.
-     * @return {@code true} if there is retry scheduled for this network capability.
-     */
-    public boolean isAnyHandoverRetryScheduled(@NonNull DataNetwork dataNetwork) {
-        return mDataRetryEntries.stream()
-                .filter(DataHandoverRetryEntry.class::isInstance)
-                .map(DataHandoverRetryEntry.class::cast)
-                .anyMatch(entry -> entry.getState() == DataRetryEntry.RETRY_STATE_NOT_RETRIED
-                        && entry.dataNetwork == dataNetwork);
-    }
-
-    /**
-     * Register the callback for receiving information from {@link DataRetryManager}.
-     *
-     * @param callback The callback.
-     */
-    public void registerCallback(@NonNull DataRetryManagerCallback callback) {
-        mDataRetryManagerCallbacks.add(callback);
-    }
-
-    /**
-     * Unregister the previously registered {@link DataRetryManagerCallback}.
-     *
-     * @param callback The callback to unregister.
-     */
-    public void unregisterCallback(@NonNull DataRetryManagerCallback callback) {
-        mDataRetryManagerCallbacks.remove(callback);
-    }
-
-    /**
-     * Convert reset reason to string
-     *
-     * @param reason The reason
-     * @return The reason in string format.
-     */
-    private static @NonNull String resetReasonToString(int reason) {
-        switch (reason) {
-            case RESET_REASON_DATA_PROFILES_CHANGED:
-                return "DATA_PROFILES_CHANGED";
-            case RESET_REASON_RADIO_ON:
-                return "RADIO_ON";
-            case RESET_REASON_MODEM_RESTART:
-                return "MODEM_RESTART";
-            case RESET_REASON_DATA_SERVICE_BOUND:
-                return "DATA_SERVICE_BOUND";
-            case RESET_REASON_DATA_CONFIG_CHANGED:
-                return "DATA_CONFIG_CHANGED";
-            case RESET_REASON_TAC_CHANGED:
-                return "TAC_CHANGED";
-            default:
-                return "UNKNOWN(" + reason + ")";
-        }
-    }
-
-    /**
-     * Log debug messages.
-     * @param s debug messages
-     */
-    private void log(@NonNull String s) {
-        Rlog.d(mLogTag, s);
-    }
-
-    /**
-     * Log error messages.
-     * @param s error messages
-     */
-    private void loge(@NonNull String s) {
-        Rlog.e(mLogTag, s);
-    }
-
-    /**
-     * Log verbose messages.
-     * @param s debug messages.
-     */
-    private void logv(@NonNull String s) {
-        if (VDBG) Rlog.v(mLogTag, s);
-    }
-
-    /**
-     * Log debug messages and also log into the local log.
-     * @param s debug messages
-     */
-    private void logl(@NonNull String s) {
-        log(s);
-        mLocalLog.log(s);
-    }
-
-    /**
-     * Dump the state of DataRetryManager.
-     *
-     * @param fd File descriptor
-     * @param printWriter Print writer
-     * @param args Arguments
-     */
-    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
-        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
-        pw.println(DataRetryManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":");
-        pw.increaseIndent();
-        pw.println("Data Setup Retry rules:");
-        pw.increaseIndent();
-        mDataSetupRetryRuleList.forEach(pw::println);
-        pw.decreaseIndent();
-        pw.println("Data Handover Retry rules:");
-        pw.increaseIndent();
-        mDataHandoverRetryRuleList.forEach(pw::println);
-        pw.decreaseIndent();
-
-        pw.println("Retry entries:");
-        pw.increaseIndent();
-        for (DataRetryEntry entry : mDataRetryEntries) {
-            pw.println(entry);
-        }
-        pw.decreaseIndent();
-
-        pw.println("Throttling entries:");
-        pw.increaseIndent();
-        for (DataThrottlingEntry entry : mDataThrottlingEntries) {
-            pw.println(entry);
-        }
-        pw.decreaseIndent();
-
-        pw.println("Local logs:");
-        pw.increaseIndent();
-        mLocalLog.dump(fd, pw, args);
-        pw.decreaseIndent();
-        pw.decreaseIndent();
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/DataServiceManager.java b/src/java/com/android/internal/telephony/data/DataServiceManager.java
deleted file mode 100644
index 41190bf..0000000
--- a/src/java/com/android/internal/telephony/data/DataServiceManager.java
+++ /dev/null
@@ -1,1006 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
-import static android.text.format.DateUtils.SECOND_IN_MILLIS;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.AppOpsManager;
-import android.content.BroadcastReceiver;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.ServiceConnection;
-import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
-import android.net.LinkProperties;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PersistableBundle;
-import android.os.Registrant;
-import android.os.RegistrantList;
-import android.os.RemoteException;
-import android.os.UserHandle;
-import android.permission.LegacyPermissionManager;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.AnomalyReporter;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionManager;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataProfile;
-import android.telephony.data.DataService;
-import android.telephony.data.DataServiceCallback;
-import android.telephony.data.IDataService;
-import android.telephony.data.IDataServiceCallback;
-import android.telephony.data.NetworkSliceInfo;
-import android.telephony.data.TrafficDescriptor;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConfigurationManager;
-import com.android.internal.telephony.util.TelephonyUtils;
-import com.android.telephony.Rlog;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CountDownLatch;
-import java.util.stream.Collectors;
-
-/**
- * Data service manager manages handling data requests and responses on data services (e.g.
- * Cellular data service, IWLAN data service).
- */
-public class DataServiceManager extends Handler {
-    private static final boolean DBG = true;
-
-    static final String DATA_CALL_RESPONSE = "data_call_response";
-
-    private static final int EVENT_BIND_DATA_SERVICE = 1;
-
-    private static final int EVENT_WATCHDOG_TIMEOUT = 2;
-
-    private static final long REQUEST_UNRESPONDED_TIMEOUT = 10 * MINUTE_IN_MILLIS; // 10 mins
-
-    private static final long CHANGE_PERMISSION_TIMEOUT_MS = 15 * SECOND_IN_MILLIS; // 15 secs
-
-    private final Phone mPhone;
-
-    private final String mTag;
-
-    private final CarrierConfigManager mCarrierConfigManager;
-    private final AppOpsManager mAppOps;
-    private final LegacyPermissionManager mPermissionManager;
-
-    private final int mTransportType;
-
-    private boolean mBound;
-
-    private IDataService mIDataService;
-
-    private DataServiceManagerDeathRecipient mDeathRecipient;
-
-    private final RegistrantList mServiceBindingChangedRegistrants = new RegistrantList();
-
-    private final Map<IBinder, Message> mMessageMap = new ConcurrentHashMap<>();
-
-    private final RegistrantList mDataCallListChangedRegistrants = new RegistrantList();
-
-    private final RegistrantList mApnUnthrottledRegistrants = new RegistrantList();
-
-    private String mTargetBindingPackageName;
-
-    private CellularDataServiceConnection mServiceConnection;
-
-    private String mLastBoundPackageName;
-
-    private List<DataCallResponse> mLastDataCallResponseList = Collections.EMPTY_LIST;
-
-    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            final String action = intent.getAction();
-            if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)
-                    && mPhone.getPhoneId() == intent.getIntExtra(
-                    CarrierConfigManager.EXTRA_SLOT_INDEX, 0)) {
-                // We should wait for carrier config changed event because the target binding
-                // package name can come from the carrier config. Note that we still get this event
-                // even when SIM is absent.
-                if (DBG) log("Carrier config changed. Try to bind data service.");
-                sendEmptyMessage(EVENT_BIND_DATA_SERVICE);
-            }
-        }
-    };
-
-    private class DataServiceManagerDeathRecipient implements IBinder.DeathRecipient {
-        @Override
-        public void binderDied() {
-            // TODO: try to rebind the service.
-            String message = "Data service " + mLastBoundPackageName +  " for transport type "
-                    + AccessNetworkConstants.transportTypeToString(mTransportType) + " died.";
-            loge(message);
-            AnomalyReporter.reportAnomaly(UUID.fromString("fc1956de-c080-45de-8431-a1faab687110"),
-                    message, mPhone.getCarrierId());
-
-            // Cancel all pending requests
-            for (Message m : mMessageMap.values()) {
-                sendCompleteMessage(m, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-            }
-            mMessageMap.clear();
-
-            // Tear down all connections
-            mLastDataCallResponseList = Collections.EMPTY_LIST;
-            mDataCallListChangedRegistrants.notifyRegistrants(
-                    new AsyncResult(null, Collections.EMPTY_LIST, null));
-        }
-    }
-
-    private void grantPermissionsToService(String packageName) {
-        final String[] pkgToGrant = {packageName};
-        CountDownLatch latch = new CountDownLatch(1);
-        try {
-            mPermissionManager.grantDefaultPermissionsToEnabledTelephonyDataServices(
-                    pkgToGrant, UserHandle.of(UserHandle.myUserId()), Runnable::run,
-                    isSuccess -> {
-                        if (isSuccess) {
-                            latch.countDown();
-                        } else {
-                            loge("Failed to grant permissions to service.");
-                        }
-                    });
-            TelephonyUtils.waitUntilReady(latch, CHANGE_PERMISSION_TIMEOUT_MS);
-            mAppOps.setMode(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS,
-                    UserHandle.myUserId(), pkgToGrant[0], AppOpsManager.MODE_ALLOWED);
-            mAppOps.setMode(AppOpsManager.OPSTR_FINE_LOCATION,
-                    UserHandle.myUserId(), pkgToGrant[0], AppOpsManager.MODE_ALLOWED);
-        } catch (RuntimeException e) {
-            loge("Binder to package manager died, permission grant for DataService failed.");
-            throw e;
-        }
-    }
-
-    /**
-     * Loop through all DataServices installed on the system and revoke permissions from any that
-     * are not currently the WWAN or WLAN data service.
-     */
-    private void revokePermissionsFromUnusedDataServices() {
-        // Except the current data services from having their permissions removed.
-        Set<String> dataServices = getAllDataServicePackageNames();
-        for (int transportType : mPhone.getAccessNetworksManager().getAvailableTransports()) {
-            dataServices.remove(getDataServicePackageName(transportType));
-        }
-
-        CountDownLatch latch = new CountDownLatch(1);
-        try {
-            String[] dataServicesArray = new String[dataServices.size()];
-            dataServices.toArray(dataServicesArray);
-            mPermissionManager.revokeDefaultPermissionsFromDisabledTelephonyDataServices(
-                    dataServicesArray, UserHandle.of(UserHandle.myUserId()), Runnable::run,
-                    isSuccess -> {
-                        if (isSuccess) {
-                            latch.countDown();
-                        } else {
-                            loge("Failed to revoke permissions from data services.");
-                        }
-                    });
-            TelephonyUtils.waitUntilReady(latch, CHANGE_PERMISSION_TIMEOUT_MS);
-            for (String pkg : dataServices) {
-                mAppOps.setMode(AppOpsManager.OPSTR_MANAGE_IPSEC_TUNNELS, UserHandle.myUserId(),
-                        pkg, AppOpsManager.MODE_ERRORED);
-                mAppOps.setMode(AppOpsManager.OPSTR_FINE_LOCATION, UserHandle.myUserId(),
-                        pkg, AppOpsManager.MODE_ERRORED);
-            }
-        } catch (RuntimeException e) {
-            loge("Binder to package manager died; failed to revoke DataService permissions.");
-            throw e;
-        }
-    }
-
-    private final class CellularDataServiceConnection implements ServiceConnection {
-        @Override
-        public void onServiceConnected(ComponentName name, IBinder service) {
-            if (DBG) log("onServiceConnected: " + name);
-            mIDataService = IDataService.Stub.asInterface(service);
-            mDeathRecipient = new DataServiceManagerDeathRecipient();
-            mBound = true;
-            mLastBoundPackageName = getDataServicePackageName();
-            removeMessages(EVENT_WATCHDOG_TIMEOUT);
-
-            try {
-                service.linkToDeath(mDeathRecipient, 0);
-                mIDataService.createDataServiceProvider(mPhone.getPhoneId());
-                mIDataService.registerForDataCallListChanged(mPhone.getPhoneId(),
-                        new DataServiceCallbackWrapper("dataCallListChanged"));
-                mIDataService.registerForUnthrottleApn(mPhone.getPhoneId(),
-                        new DataServiceCallbackWrapper("unthrottleApn"));
-            } catch (RemoteException e) {
-                loge("Remote exception. " + e);
-                return;
-            }
-            mServiceBindingChangedRegistrants.notifyResult(true);
-        }
-        @Override
-        public void onServiceDisconnected(ComponentName name) {
-            if (DBG) log("onServiceDisconnected");
-            removeMessages(EVENT_WATCHDOG_TIMEOUT);
-            mIDataService = null;
-            mBound = false;
-            mServiceBindingChangedRegistrants.notifyResult(false);
-            mTargetBindingPackageName = null;
-        }
-    }
-
-    private final class DataServiceCallbackWrapper extends IDataServiceCallback.Stub {
-
-        private final String mTag;
-
-        DataServiceCallbackWrapper(String tag) {
-            mTag = tag;
-        }
-
-        public String getTag() {
-            return mTag;
-        }
-
-        @Override
-        public void onSetupDataCallComplete(@DataServiceCallback.ResultCode int resultCode,
-                DataCallResponse response) {
-            if (DBG) {
-                log("onSetupDataCallComplete. resultCode = " + resultCode + ", response = "
-                        + response);
-            }
-            removeMessages(EVENT_WATCHDOG_TIMEOUT, DataServiceCallbackWrapper.this);
-            Message msg = mMessageMap.remove(asBinder());
-            if (msg != null) {
-                msg.getData().putParcelable(DATA_CALL_RESPONSE, response);
-                sendCompleteMessage(msg, resultCode);
-            } else {
-                loge("Unable to find the message for setup call response.");
-            }
-        }
-
-        @Override
-        public void onDeactivateDataCallComplete(@DataServiceCallback.ResultCode int resultCode) {
-            if (DBG) log("onDeactivateDataCallComplete. resultCode = " + resultCode);
-            removeMessages(EVENT_WATCHDOG_TIMEOUT, DataServiceCallbackWrapper.this);
-            Message msg = mMessageMap.remove(asBinder());
-            sendCompleteMessage(msg, resultCode);
-        }
-
-        @Override
-        public void onSetInitialAttachApnComplete(@DataServiceCallback.ResultCode int resultCode) {
-            if (DBG) log("onSetInitialAttachApnComplete. resultCode = " + resultCode);
-            Message msg = mMessageMap.remove(asBinder());
-            sendCompleteMessage(msg, resultCode);
-        }
-
-        @Override
-        public void onSetDataProfileComplete(@DataServiceCallback.ResultCode int resultCode) {
-            if (DBG) log("onSetDataProfileComplete. resultCode = " + resultCode);
-            Message msg = mMessageMap.remove(asBinder());
-            sendCompleteMessage(msg, resultCode);
-        }
-
-        @Override
-        public void onRequestDataCallListComplete(@DataServiceCallback.ResultCode int resultCode,
-                List<DataCallResponse> dataCallList) {
-            if (DBG) {
-                log("onRequestDataCallListComplete. resultCode = "
-                        + DataServiceCallback.resultCodeToString(resultCode));
-            }
-            Message msg = mMessageMap.remove(asBinder());
-            if (msg != null) {
-                msg.getData().putParcelableList(DATA_CALL_RESPONSE, dataCallList);
-            }
-            sendCompleteMessage(msg, resultCode);
-
-            // Handle data stall case on WWAN transport
-            if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
-                if (mLastDataCallResponseList.size() != dataCallList.size()
-                        || !mLastDataCallResponseList.containsAll(dataCallList)) {
-                    String message = "RIL reported mismatched data call response list for WWAN: "
-                            + "mLastDataCallResponseList=" + mLastDataCallResponseList
-                            + ", dataCallList=" + dataCallList;
-                    loge(message);
-                    if (!dataCallList.stream().map(DataCallResponse::getId)
-                            .collect(Collectors.toSet()).equals(mLastDataCallResponseList.stream()
-                                    .map(DataCallResponse::getId).collect(Collectors.toSet()))) {
-                        AnomalyReporter.reportAnomaly(
-                                UUID.fromString("150323b2-360a-446b-a158-3ce6425821f6"),
-                                message,
-                                mPhone.getCarrierId());
-                    }
-                }
-                onDataCallListChanged(dataCallList);
-            }
-        }
-
-        @Override
-        public void onDataCallListChanged(List<DataCallResponse> dataCallList) {
-            mLastDataCallResponseList =
-                    dataCallList != null ? dataCallList : Collections.EMPTY_LIST;
-            mDataCallListChangedRegistrants.notifyRegistrants(
-                    new AsyncResult(null, dataCallList, null));
-        }
-
-        @Override
-        public void onHandoverStarted(@DataServiceCallback.ResultCode int resultCode) {
-            if (DBG) log("onHandoverStarted. resultCode = " + resultCode);
-            removeMessages(EVENT_WATCHDOG_TIMEOUT, DataServiceCallbackWrapper.this);
-            Message msg = mMessageMap.remove(asBinder());
-            sendCompleteMessage(msg, resultCode);
-        }
-
-        @Override
-        public void onHandoverCancelled(@DataServiceCallback.ResultCode int resultCode) {
-            if (DBG) log("onHandoverCancelled. resultCode = " + resultCode);
-            removeMessages(EVENT_WATCHDOG_TIMEOUT, DataServiceCallbackWrapper.this);
-            Message msg = mMessageMap.remove(asBinder());
-            sendCompleteMessage(msg, resultCode);
-        }
-
-        @Override
-        public void onApnUnthrottled(String apn) {
-            if (apn != null) {
-                mApnUnthrottledRegistrants.notifyRegistrants(
-                        new AsyncResult(null, apn, null));
-            } else {
-                loge("onApnUnthrottled: apn is null");
-            }
-        }
-
-        @Override
-        public void onDataProfileUnthrottled(DataProfile dataProfile) {
-            if (dataProfile != null) {
-                mApnUnthrottledRegistrants.notifyRegistrants(
-                        new AsyncResult(null, dataProfile, null));
-            } else {
-                loge("onDataProfileUnthrottled: dataProfile is null");
-            }
-        }
-    }
-
-    /**
-     * Constructor
-     *
-     * @param phone The phone instance
-     * @param looper Looper for the handler
-     * @param transportType The transport type
-     */
-    public DataServiceManager(@NonNull Phone phone, @NonNull Looper looper,
-            @TransportType int transportType) {
-        super(looper);
-        mPhone = phone;
-        mTransportType = transportType;
-        mTag = "DSM-" + (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WWAN ? "C-"
-                : "I-") + mPhone.getPhoneId();
-        mBound = false;
-        mCarrierConfigManager = (CarrierConfigManager) phone.getContext().getSystemService(
-                Context.CARRIER_CONFIG_SERVICE);
-        // NOTE: Do NOT use AppGlobals to retrieve the permission manager; AppGlobals
-        // caches the service instance, but we need to explicitly request a new service
-        // so it can be mocked out for tests
-        mPermissionManager = (LegacyPermissionManager) phone.getContext().getSystemService(
-                Context.LEGACY_PERMISSION_SERVICE);
-        mAppOps = (AppOpsManager) phone.getContext().getSystemService(Context.APP_OPS_SERVICE);
-
-        IntentFilter intentFilter = new IntentFilter();
-        intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        try {
-            Context contextAsUser = phone.getContext().createPackageContextAsUser(
-                    phone.getContext().getPackageName(), 0, UserHandle.ALL);
-            contextAsUser.registerReceiver(mBroadcastReceiver, intentFilter,
-                    null /* broadcastPermission */, null);
-        } catch (PackageManager.NameNotFoundException e) {
-            loge("Package name not found: " + e.getMessage());
-        }
-        PhoneConfigurationManager.registerForMultiSimConfigChange(
-                this, EVENT_BIND_DATA_SERVICE, null);
-
-        rebindDataService();
-    }
-
-    /**
-     * Handle message events
-     *
-     * @param msg The message to handle
-     */
-    @Override
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-            case EVENT_BIND_DATA_SERVICE:
-                rebindDataService();
-                break;
-            case EVENT_WATCHDOG_TIMEOUT:
-                handleRequestUnresponded((DataServiceCallbackWrapper) msg.obj);
-                break;
-            default:
-                loge("Unhandled event " + msg.what);
-        }
-    }
-
-    private void handleRequestUnresponded(DataServiceCallbackWrapper callback) {
-        String message = "Request " + callback.getTag() + " unresponded on transport "
-                + AccessNetworkConstants.transportTypeToString(mTransportType) + " in "
-                + REQUEST_UNRESPONDED_TIMEOUT / 1000 + " seconds.";
-        log(message);
-        // Using fixed UUID to avoid duplicate bugreport notification
-        AnomalyReporter.reportAnomaly(
-                UUID.fromString("f5d5cbe6-9bd6-4009-b764-42b1b649b1de"),
-                message, mPhone.getCarrierId());
-    }
-
-    private void unbindDataService() {
-        // Start by cleaning up all packages that *shouldn't* have permissions.
-        revokePermissionsFromUnusedDataServices();
-        if (mIDataService != null && mIDataService.asBinder().isBinderAlive()) {
-            log("unbinding service");
-            // Remove the network availability updater and then unbind the service.
-            try {
-                mIDataService.removeDataServiceProvider(mPhone.getPhoneId());
-            } catch (RemoteException e) {
-                loge("Cannot remove data service provider. " + e);
-            }
-        }
-
-        if (mServiceConnection != null) {
-            mPhone.getContext().unbindService(mServiceConnection);
-        }
-        mIDataService = null;
-        mServiceConnection = null;
-        mTargetBindingPackageName = null;
-        mBound = false;
-    }
-
-    private void bindDataService(String packageName) {
-        if (mPhone == null || !SubscriptionManager.isValidPhoneId(mPhone.getPhoneId())) {
-            loge("can't bindDataService with invalid phone or phoneId.");
-            return;
-        }
-
-        if (TextUtils.isEmpty(packageName)) {
-            loge("Can't find the binding package");
-            return;
-        }
-
-        Intent intent = null;
-        String className = getDataServiceClassName();
-        if (TextUtils.isEmpty(className)) {
-            intent = new Intent(DataService.SERVICE_INTERFACE);
-            intent.setPackage(packageName);
-        } else {
-            ComponentName cm = new ComponentName(packageName, className);
-            intent = new Intent(DataService.SERVICE_INTERFACE).setComponent(cm);
-        }
-
-        // Then pre-emptively grant the permissions to the package we will bind.
-        grantPermissionsToService(packageName);
-
-        try {
-            mServiceConnection = new CellularDataServiceConnection();
-            if (!mPhone.getContext().bindService(
-                    intent, mServiceConnection, Context.BIND_AUTO_CREATE)) {
-                loge("Cannot bind to the data service.");
-                return;
-            }
-            mTargetBindingPackageName = packageName;
-        } catch (Exception e) {
-            loge("Cannot bind to the data service. Exception: " + e);
-        }
-    }
-
-    private void rebindDataService() {
-        String packageName = getDataServicePackageName();
-        // Do nothing if no need to rebind.
-        if (SubscriptionManager.isValidPhoneId(mPhone.getPhoneId())
-                && TextUtils.equals(packageName, mTargetBindingPackageName)) {
-            if (DBG) log("Service " + packageName + " already bound or being bound.");
-            return;
-        }
-
-        unbindDataService();
-        bindDataService(packageName);
-    }
-
-    private @NonNull Set<String> getAllDataServicePackageNames() {
-        // Cowardly using the public PackageManager interface here.
-        // Note: This matches only packages that were installed on the system image. If we ever
-        // expand the permissions model to allow CarrierPrivileged packages, then this will need
-        // to be updated.
-        List<ResolveInfo> dataPackages =
-                mPhone.getContext().getPackageManager().queryIntentServices(
-                        new Intent(DataService.SERVICE_INTERFACE),
-                                PackageManager.MATCH_SYSTEM_ONLY);
-        HashSet<String> packageNames = new HashSet<>();
-        for (ResolveInfo info : dataPackages) {
-            if (info.serviceInfo == null) continue;
-            packageNames.add(info.serviceInfo.packageName);
-        }
-        return packageNames;
-    }
-
-    /**
-     * Get the data service package name for our current transport type.
-     *
-     * @return package name of the data service package for the current transportType.
-     */
-    public String getDataServicePackageName() {
-        return getDataServicePackageName(mTransportType);
-    }
-
-    /**
-     * Get the data service package by transport type.
-     *
-     * When we bind to a DataService package, we need to revoke permissions from stale
-     * packages; we need to exclude data packages for all transport types, so we need to
-     * to be able to query by transport type.
-     *
-     * @param transportType The transport type
-     * @return package name of the data service package for the specified transportType.
-     */
-    private String getDataServicePackageName(@TransportType int transportType) {
-        String packageName;
-        int resourceId;
-        String carrierConfig;
-
-        switch (transportType) {
-            case AccessNetworkConstants.TRANSPORT_TYPE_WWAN:
-                resourceId = com.android.internal.R.string.config_wwan_data_service_package;
-                carrierConfig = CarrierConfigManager
-                        .KEY_CARRIER_DATA_SERVICE_WWAN_PACKAGE_OVERRIDE_STRING;
-                break;
-            case AccessNetworkConstants.TRANSPORT_TYPE_WLAN:
-                resourceId = com.android.internal.R.string.config_wlan_data_service_package;
-                carrierConfig = CarrierConfigManager
-                        .KEY_CARRIER_DATA_SERVICE_WLAN_PACKAGE_OVERRIDE_STRING;
-                break;
-            default:
-                throw new IllegalStateException("Transport type not WWAN or WLAN. type="
-                        + AccessNetworkConstants.transportTypeToString(mTransportType));
-        }
-
-        // Read package name from resource overlay
-        packageName = mPhone.getContext().getResources().getString(resourceId);
-
-        PersistableBundle b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId());
-
-        if (b != null && !TextUtils.isEmpty(b.getString(carrierConfig))) {
-            // If carrier config overrides it, use the one from carrier config
-            packageName = b.getString(carrierConfig, packageName);
-        }
-
-        return packageName;
-    }
-
-    /**
-     * Get the data service class name for our current transport type.
-     *
-     * @return class name of the data service package for the current transportType.
-     */
-    private String getDataServiceClassName() {
-        return getDataServiceClassName(mTransportType);
-    }
-
-
-    /**
-     * Get the data service class by transport type.
-     *
-     * @param transportType either WWAN or WLAN
-     * @return class name of the data service package for the specified transportType.
-     */
-    private String getDataServiceClassName(int transportType) {
-        String className;
-        int resourceId;
-        String carrierConfig;
-        switch (transportType) {
-            case AccessNetworkConstants.TRANSPORT_TYPE_WWAN:
-                resourceId = com.android.internal.R.string.config_wwan_data_service_class;
-                carrierConfig = CarrierConfigManager
-                        .KEY_CARRIER_DATA_SERVICE_WWAN_CLASS_OVERRIDE_STRING;
-                break;
-            case AccessNetworkConstants.TRANSPORT_TYPE_WLAN:
-                resourceId = com.android.internal.R.string.config_wlan_data_service_class;
-                carrierConfig = CarrierConfigManager
-                        .KEY_CARRIER_DATA_SERVICE_WLAN_CLASS_OVERRIDE_STRING;
-                break;
-            default:
-                throw new IllegalStateException("Transport type not WWAN or WLAN. type="
-                        + transportType);
-        }
-
-        // Read package name from resource overlay
-        className = mPhone.getContext().getResources().getString(resourceId);
-
-        PersistableBundle b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId());
-
-        if (b != null && !TextUtils.isEmpty(b.getString(carrierConfig))) {
-            // If carrier config overrides it, use the one from carrier config
-            className = b.getString(carrierConfig, className);
-        }
-
-        return className;
-    }
-
-    private void sendCompleteMessage(Message msg, @DataServiceCallback.ResultCode int code) {
-        if (msg != null) {
-            msg.arg1 = code;
-            msg.sendToTarget();
-        }
-    }
-
-    /**
-     * Setup a data connection. The data service provider must implement this method to support
-     * establishing a packet data connection. When completed or error, the service must invoke
-     * the provided callback to notify the platform.
-     *
-     * @param accessNetworkType Access network type that the data network will be established on.
-     * Must be one of {@link AccessNetworkConstants.AccessNetworkType}.
-     * @param dataProfile Data profile used for data network setup. See {@link DataProfile}
-     * @param isRoaming True if the device is data roaming.
-     * @param allowRoaming True if data roaming is allowed by the user.
-     * @param reason The reason for data setup. Must be {@link DataService#REQUEST_REASON_NORMAL} or
-     * {@link DataService#REQUEST_REASON_HANDOVER}.
-     * @param linkProperties If {@code reason} is {@link DataService#REQUEST_REASON_HANDOVER}, this
-     * is the link properties of the existing data connection, otherwise null.
-     * @param pduSessionId The pdu session id to be used for this data network.  A value of -1 means
-     * no pdu session id was attached to this call. Reference: 3GPP TS 24.007 Section 11.2.3.1b.
-     * @param sliceInfo The slice that represents S-NSSAI. Reference: 3GPP TS 24.501.
-     * @param trafficDescriptor The traffic descriptor for this data network, used for URSP
-     * matching. Reference: 3GPP TS TS 24.526 Section 5.2.
-     * @param matchAllRuleAllowed True if using the default match-all URSP rule for this request is
-     * allowed.
-     * @param onCompleteMessage The result message for this request. Null if the client does not
-     * care about the result.
-     */
-    public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming,
-            boolean allowRoaming, int reason, LinkProperties linkProperties, int pduSessionId,
-            @Nullable NetworkSliceInfo sliceInfo, @Nullable TrafficDescriptor trafficDescriptor,
-            boolean matchAllRuleAllowed, Message onCompleteMessage) {
-        if (DBG) log("setupDataCall");
-        if (!mBound) {
-            loge("setupDataCall: Data service not bound.");
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-            return;
-        }
-
-        DataServiceCallbackWrapper callback = new DataServiceCallbackWrapper("setupDataCall");
-        if (onCompleteMessage != null) {
-            mMessageMap.put(callback.asBinder(), onCompleteMessage);
-        }
-        try {
-            sendMessageDelayed(obtainMessage(EVENT_WATCHDOG_TIMEOUT, callback),
-                    REQUEST_UNRESPONDED_TIMEOUT);
-            mIDataService.setupDataCall(mPhone.getPhoneId(), accessNetworkType, dataProfile,
-                    isRoaming, allowRoaming, reason, linkProperties, pduSessionId, sliceInfo,
-                    trafficDescriptor, matchAllRuleAllowed, callback);
-        } catch (RemoteException e) {
-            loge("setupDataCall: Cannot invoke setupDataCall on data service.");
-            mMessageMap.remove(callback.asBinder());
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-        }
-    }
-
-    /**
-     * Deactivate a data connection. The data service provider must implement this method to
-     * support data connection tear down. When completed or error, the service must invoke the
-     * provided callback to notify the platform.
-     *
-     * @param cid Call id returned in the callback of {@link #setupDataCall(int, DataProfile,
-     * boolean, boolean, int, LinkProperties, int, NetworkSliceInfo, TrafficDescriptor, boolean,
-     * Message)}
-     * @param reason The reason for data deactivation. Must be
-     * {@link DataService#REQUEST_REASON_NORMAL}, {@link DataService#REQUEST_REASON_SHUTDOWN}
-     * or {@link DataService#REQUEST_REASON_HANDOVER}.
-     * @param onCompleteMessage The result message for this request. Null if the client does not
-     * care about the result.
-     */
-    public void deactivateDataCall(int cid, int reason, Message onCompleteMessage) {
-        if (DBG) log("deactivateDataCall");
-        if (!mBound) {
-            loge("Data service not bound.");
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-            return;
-        }
-
-        DataServiceCallbackWrapper callback =
-                new DataServiceCallbackWrapper("deactivateDataCall");
-        if (onCompleteMessage != null) {
-            mMessageMap.put(callback.asBinder(), onCompleteMessage);
-        }
-        try {
-            sendMessageDelayed(obtainMessage(EVENT_WATCHDOG_TIMEOUT, callback),
-                    REQUEST_UNRESPONDED_TIMEOUT);
-            mIDataService.deactivateDataCall(mPhone.getPhoneId(), cid, reason, callback);
-        } catch (RemoteException e) {
-            loge("Cannot invoke deactivateDataCall on data service.");
-            mMessageMap.remove(callback.asBinder());
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-        }
-    }
-
-    /**
-     * Indicates that a handover has begun.  This is called on the source transport.
-     *
-     * Any resources being transferred cannot be released while a
-     * handover is underway.
-     *
-     * If a handover was unsuccessful, then the framework calls DataServiceManager#cancelHandover.
-     * The target transport retains ownership over any of the resources being transferred.
-     *
-     * If a handover was successful, the framework calls DataServiceManager#deactivateDataCall with
-     * reason HANDOVER. The target transport now owns the transferred resources and is
-     * responsible for releasing them.
-     *
-     * @param cid The identifier of the data network which is provided in DataCallResponse
-     * @param onCompleteMessage The result callback for this request.
-     */
-    public void startHandover(int cid, @NonNull Message onCompleteMessage) {
-        DataServiceCallbackWrapper callback =
-                setupCallbackHelper("startHandover", onCompleteMessage);
-        if (callback == null) {
-            loge("startHandover: callback == null");
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-            return;
-        }
-
-        try {
-            sendMessageDelayed(obtainMessage(EVENT_WATCHDOG_TIMEOUT, callback),
-                    REQUEST_UNRESPONDED_TIMEOUT);
-            mIDataService.startHandover(mPhone.getPhoneId(), cid, callback);
-        } catch (RemoteException e) {
-            loge("Cannot invoke startHandover on data service.");
-            mMessageMap.remove(callback.asBinder());
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-        }
-    }
-
-    /**
-     * Indicates that a handover was cancelled after a call to DataServiceManager#startHandover.
-     * This is called on the source transport.
-     *
-     * Since the handover was unsuccessful, the source transport retains ownership over any of
-     * the resources being transferred and is still responsible for releasing them.
-     *
-     * @param cid The identifier of the data network which is provided in DataCallResponse
-     * @param onCompleteMessage The result callback for this request.
-     */
-    public void cancelHandover(int cid, @NonNull Message onCompleteMessage) {
-        DataServiceCallbackWrapper callback =
-                setupCallbackHelper("cancelHandover", onCompleteMessage);
-        if (callback == null) {
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-            return;
-        }
-
-        try {
-            sendMessageDelayed(obtainMessage(EVENT_WATCHDOG_TIMEOUT, callback),
-                    REQUEST_UNRESPONDED_TIMEOUT);
-            mIDataService.cancelHandover(mPhone.getPhoneId(), cid, callback);
-        } catch (RemoteException e) {
-            loge("Cannot invoke cancelHandover on data service.");
-            mMessageMap.remove(callback.asBinder());
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-        }
-    }
-
-    @Nullable
-    private DataServiceCallbackWrapper setupCallbackHelper(
-            @NonNull final String operationName, @NonNull final Message onCompleteMessage) {
-        if (DBG) log(operationName);
-        if (!mBound) {
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-            return null;
-        }
-
-        DataServiceCallbackWrapper callback =
-                new DataServiceCallbackWrapper(operationName);
-        if (onCompleteMessage != null) {
-            if (DBG) log(operationName + ": onCompleteMessage set");
-            mMessageMap.put(callback.asBinder(), onCompleteMessage);
-        } else {
-            if (DBG) log(operationName + ": onCompleteMessage not set");
-        }
-        return callback;
-    }
-
-    /**
-     * Set an APN to initial attach network.
-     *
-     * @param dataProfile Data profile used for data network setup. See {@link DataProfile}.
-     * @param isRoaming True if the device is data roaming.
-     * @param onCompleteMessage The result message for this request. Null if the client does not
-     * care about the result.
-     */
-    public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming,
-                                    Message onCompleteMessage) {
-        if (DBG) log("setInitialAttachApn");
-        if (!mBound) {
-            loge("Data service not bound.");
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-            return;
-        }
-
-        DataServiceCallbackWrapper callback =
-                new DataServiceCallbackWrapper("setInitialAttachApn");
-        if (onCompleteMessage != null) {
-            mMessageMap.put(callback.asBinder(), onCompleteMessage);
-        }
-        try {
-            mIDataService.setInitialAttachApn(mPhone.getPhoneId(), dataProfile, isRoaming,
-                    callback);
-        } catch (RemoteException e) {
-            loge("Cannot invoke setInitialAttachApn on data service.");
-            mMessageMap.remove(callback.asBinder());
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-        }
-    }
-
-    /**
-     * Send current carrier's data profiles to the data service for data network setup. This is
-     * only for CDMA carrier that can change the profile through OTA. The data service should
-     * always uses the latest data profile sent by the framework.
-     *
-     * @param dps A list of data profiles.
-     * @param isRoaming True if the device is data roaming.
-     * @param onCompleteMessage The result message for this request. Null if the client does not
-     * care about the result.
-     */
-    public void setDataProfile(List<DataProfile> dps, boolean isRoaming,
-            Message onCompleteMessage) {
-        if (DBG) log("setDataProfile");
-        if (!mBound) {
-            loge("Data service not bound.");
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-            return;
-        }
-
-        DataServiceCallbackWrapper callback = new DataServiceCallbackWrapper("setDataProfile");
-        if (onCompleteMessage != null) {
-            mMessageMap.put(callback.asBinder(), onCompleteMessage);
-        }
-        try {
-            mIDataService.setDataProfile(mPhone.getPhoneId(), dps, isRoaming, callback);
-        } catch (RemoteException e) {
-            loge("Cannot invoke setDataProfile on data service.");
-            mMessageMap.remove(callback.asBinder());
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-        }
-    }
-
-    /**
-     * Get the active data network list.
-     *
-     * @param onCompleteMessage The result message for this request. Null if the client does not
-     * care about the result.
-     */
-    public void requestDataCallList(Message onCompleteMessage) {
-        if (DBG) log("requestDataCallList");
-        if (!mBound) {
-            loge("Data service not bound.");
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-            return;
-        }
-
-        DataServiceCallbackWrapper callback =
-                new DataServiceCallbackWrapper("requestDataCallList");
-        if (onCompleteMessage != null) {
-            mMessageMap.put(callback.asBinder(), onCompleteMessage);
-        }
-        try {
-            mIDataService.requestDataCallList(mPhone.getPhoneId(), callback);
-        } catch (RemoteException e) {
-            loge("Cannot invoke requestDataCallList on data service.");
-            if (callback != null) {
-                mMessageMap.remove(callback.asBinder());
-            }
-            sendCompleteMessage(onCompleteMessage, DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE);
-        }
-    }
-
-    /**
-     * Register for data network list changed event.
-     *
-     * @param h The target to post the event message to.
-     * @param what The event.
-     */
-    public void registerForDataCallListChanged(Handler h, int what) {
-        if (h != null) {
-            mDataCallListChangedRegistrants.addUnique(h, what, mTransportType);
-        }
-    }
-
-    /**
-     * Unregister for data network list changed event.
-     *
-     * @param h The handler
-     */
-    public void unregisterForDataCallListChanged(Handler h) {
-        if (h != null) {
-            mDataCallListChangedRegistrants.remove(h);
-        }
-    }
-
-    /**
-     * Register apn unthrottled event
-     *
-     * @param h The target to post the event message to.
-     * @param what The event.
-     */
-    public void registerForApnUnthrottled(Handler h, int what) {
-        if (h != null) {
-            mApnUnthrottledRegistrants.addUnique(h, what, mTransportType);
-        }
-    }
-
-    /**
-     * Unregister for apn unthrottled event
-     *
-     * @param h The handler
-     */
-    public void unregisterForApnUnthrottled(Handler h) {
-        if (h != null) {
-            mApnUnthrottledRegistrants.remove(h);
-        }
-    }
-
-    /**
-     * Register for data service binding status changed event.
-     *
-     * @param h The target to post the event message to.
-     * @param what The event.
-     */
-    public void registerForServiceBindingChanged(Handler h, int what) {
-        if (h != null) {
-            mServiceBindingChangedRegistrants.remove(h);
-            Registrant r = new Registrant(h, what, mTransportType);
-            mServiceBindingChangedRegistrants.add(r);
-            if (mBound) {
-                r.notifyResult(true);
-            }
-        }
-    }
-
-    /**
-     * Unregister for data service binding status changed event.
-     *
-     * @param h The handler
-     */
-    public void unregisterForServiceBindingChanged(Handler h) {
-        if (h != null) {
-            mServiceBindingChangedRegistrants.remove(h);
-        }
-    }
-
-    private void log(String s) {
-        Rlog.d(mTag, s);
-    }
-
-    private void loge(String s) {
-        Rlog.e(mTag, s);
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/DataSettingsManager.java b/src/java/com/android/internal/telephony/data/DataSettingsManager.java
deleted file mode 100644
index e2c1aff..0000000
--- a/src/java/com/android/internal/telephony/data/DataSettingsManager.java
+++ /dev/null
@@ -1,766 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemProperties;
-import android.preference.PreferenceManager;
-import android.provider.Settings;
-import android.sysprop.TelephonyProperties;
-import android.telephony.CarrierConfigManager;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
-import android.telephony.TelephonyManager;
-import android.telephony.TelephonyRegistryManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.ApnSetting.ApnType;
-import android.util.ArrayMap;
-import android.util.ArraySet;
-import android.util.IndentingPrintWriter;
-import android.util.LocalLog;
-
-import com.android.internal.telephony.GlobalSettingsHelper;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.SettingsObserver;
-import com.android.internal.telephony.SubscriptionController;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.stream.Collectors;
-
-/**
- * DataSettingsManager maintains the data related settings, for example, data enabled settings,
- * data roaming settings, etc...
- */
-public class DataSettingsManager extends Handler {
-    /** Event for data config updated. */
-    private static final int EVENT_DATA_CONFIG_UPDATED = 1;
-    /** Event for call state changed. */
-    private static final int EVENT_CALL_STATE_CHANGED = 2;
-    /** Event for subscriptions updated. */
-    private static final int EVENT_SUBSCRIPTIONS_CHANGED = 4;
-    /** Event for set data enabled for reason. */
-    private static final int EVENT_SET_DATA_ENABLED_FOR_REASON = 5;
-    /** Event for set data roaming enabled. */
-    private static final int EVENT_SET_DATA_ROAMING_ENABLED = 6;
-    /** Event for set always allow MMS data. */
-    private static final int EVENT_SET_ALWAYS_ALLOW_MMS_DATA = 7;
-    /** Event for set allow data during voice call. */
-    private static final int EVENT_SET_ALLOW_DATA_DURING_VOICE_CALL = 8;
-    /** Event for device provisioned changed. */
-    private static final int EVENT_PROVISIONED_CHANGED = 9;
-    /** Event for provisioning data enabled setting changed. */
-    private static final int EVENT_PROVISIONING_DATA_ENABLED_CHANGED = 10;
-    /** Event for initializing DataSettingsManager. */
-    private static final int EVENT_INITIALIZE = 11;
-
-    private final Phone mPhone;
-    private final ContentResolver mResolver;
-    private final SettingsObserver mSettingsObserver;
-    private final String mLogTag;
-    private final LocalLog mLocalLog = new LocalLog(128);
-    private int mSubId;
-    private DataEnabledOverride mDataEnabledOverride;
-
-    /** Data config manager */
-    private final @NonNull DataConfigManager mDataConfigManager;
-
-    /** Data settings manager callbacks. */
-    private final @NonNull Set<DataSettingsManagerCallback> mDataSettingsManagerCallbacks =
-            new ArraySet<>();
-
-    /** Mapping of {@link TelephonyManager.DataEnabledReason} to data enabled values. */
-    private final Map<Integer, Boolean> mDataEnabledSettings = new ArrayMap<>();
-
-    /**
-     * Flag indicating whether data is allowed or not for the device.
-     * It can be disabled by user, carrier, policy or thermal.
-     */
-    private boolean mIsDataEnabled;
-
-    /**
-     * Used to indicate that the initial value for mIsDataEnabled was set.
-     * Prevent race condition where the initial value might be incorrect.
-     */
-    private boolean mInitialized = false;
-
-    /**
-     * Data settings manager callback. This should be only used by {@link DataNetworkController}.
-     */
-    public static class DataSettingsManagerCallback extends DataCallback {
-        /**
-         * Constructor
-         *
-         * @param executor The executor of the callback.
-         */
-        public DataSettingsManagerCallback(@NonNull @CallbackExecutor Executor executor) {
-            super(executor);
-        }
-
-        /**
-         * Called when overall data enabled state changed.
-         *
-         * @param enabled {@code true} indicates mobile data is enabled.
-         * @param reason {@link TelephonyManager.DataEnabledChangedReason} indicating the reason why
-         *               mobile data enabled changed.
-         * @param callingPackage The package that changed the data enabled state.
-         */
-        public void onDataEnabledChanged(boolean enabled,
-                @TelephonyManager.DataEnabledChangedReason int reason,
-                @NonNull String callingPackage) {}
-
-        /**
-         * Called when data enabled override changed.
-         *
-         * @param enabled {@code true} indicates data enabled override is enabled.
-         * @param policy {@link TelephonyManager.MobileDataPolicy} indicating the policy that was
-         *               enabled or disabled.
-         */
-        public void onDataEnabledOverrideChanged(boolean enabled,
-                @TelephonyManager.MobileDataPolicy int policy) {}
-
-        /**
-         * Called when data roaming enabled state changed.
-         *
-         * @param enabled {@code true} indicates data roaming is enabled.
-         */
-        public void onDataRoamingEnabledChanged(boolean enabled) {}
-    }
-
-    /**
-     * Constructor
-     *
-     * @param phone The phone instance.
-     * @param dataNetworkController Data network controller.
-     * @param looper The looper to be used by the handler. Currently the handler thread is the
-     * phone process's main thread.
-     * @param callback Data settings manager callback.
-     */
-    public DataSettingsManager(@NonNull Phone phone,
-            @NonNull DataNetworkController dataNetworkController, @NonNull Looper looper,
-            @NonNull DataSettingsManagerCallback callback) {
-        super(looper);
-        mPhone = phone;
-        mLogTag = "DSMGR-" + mPhone.getPhoneId();
-        log("DataSettingsManager created.");
-        mSubId = mPhone.getSubId();
-        mResolver = mPhone.getContext().getContentResolver();
-        registerCallback(callback);
-        mDataConfigManager = dataNetworkController.getDataConfigManager();
-        mDataEnabledOverride = getDataEnabledOverride();
-        mSettingsObserver = new SettingsObserver(mPhone.getContext(), this);
-        mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_POLICY, true);
-        mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_CARRIER, true);
-        mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_THERMAL, true);
-
-        // Instead of calling onInitialize directly from the constructor, send the event.
-        // The reason is that getImsPhone is null when we are still in the constructor here.
-        sendEmptyMessage(EVENT_INITIALIZE);
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        switch (msg.what) {
-            case EVENT_DATA_CONFIG_UPDATED: {
-                if (mDataConfigManager.isConfigCarrierSpecific()) {
-                    setDefaultDataRoamingEnabled();
-                }
-                break;
-            }
-            case EVENT_CALL_STATE_CHANGED: {
-                updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_OVERRIDE);
-                break;
-            }
-            case EVENT_SUBSCRIPTIONS_CHANGED: {
-                mSubId = (int) msg.obj;
-                mDataEnabledOverride = getDataEnabledOverride();
-                updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_USER);
-                mPhone.notifyUserMobileDataStateChanged(isUserDataEnabled());
-                break;
-            }
-            case EVENT_SET_DATA_ENABLED_FOR_REASON: {
-                String callingPackage = (String) msg.obj;
-                boolean enabled = msg.arg2 == 1;
-                switch (msg.arg1) {
-                    case TelephonyManager.DATA_ENABLED_REASON_USER:
-                        setUserDataEnabled(enabled, callingPackage);
-                        break;
-                    case TelephonyManager.DATA_ENABLED_REASON_CARRIER:
-                        setCarrierDataEnabled(enabled, callingPackage);
-                        break;
-                    case TelephonyManager.DATA_ENABLED_REASON_POLICY:
-                        setPolicyDataEnabled(enabled, callingPackage);
-                        break;
-                    case TelephonyManager.DATA_ENABLED_REASON_THERMAL:
-                        setThermalDataEnabled(enabled, callingPackage);
-                        break;
-                    default:
-                        log("Cannot set data enabled for reason: "
-                                + dataEnabledChangedReasonToString(msg.arg1));
-                        break;
-                }
-                break;
-            }
-            case EVENT_SET_DATA_ROAMING_ENABLED: {
-                boolean enabled = (boolean) msg.obj;
-                setDataRoamingEnabledInternal(enabled);
-                setDataRoamingFromUserAction();
-                break;
-            }
-            case EVENT_SET_ALWAYS_ALLOW_MMS_DATA: {
-                boolean alwaysAllow = (boolean) msg.obj;
-                if (alwaysAllow == isMmsAlwaysAllowed()) {
-                    break;
-                }
-                logl("AlwaysAllowMmsData changed to " + alwaysAllow);
-                mDataEnabledOverride.setAlwaysAllowMms(alwaysAllow);
-                if (SubscriptionController.getInstance()
-                        .setDataEnabledOverrideRules(mSubId, mDataEnabledOverride.getRules())) {
-                    updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_OVERRIDE);
-                    notifyDataEnabledOverrideChanged(alwaysAllow,
-                            TelephonyManager.MOBILE_DATA_POLICY_MMS_ALWAYS_ALLOWED);
-                }
-                break;
-            }
-            case EVENT_SET_ALLOW_DATA_DURING_VOICE_CALL: {
-                boolean allow = (boolean) msg.obj;
-                if (allow == isDataAllowedInVoiceCall()) {
-                    break;
-                }
-                logl("AllowDataDuringVoiceCall changed to " + allow);
-                mDataEnabledOverride.setDataAllowedInVoiceCall(allow);
-                if (SubscriptionController.getInstance()
-                        .setDataEnabledOverrideRules(mSubId, mDataEnabledOverride.getRules())) {
-                    updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_OVERRIDE);
-                    notifyDataEnabledOverrideChanged(allow, TelephonyManager
-                            .MOBILE_DATA_POLICY_DATA_ON_NON_DEFAULT_DURING_VOICE_CALL);
-                }
-                break;
-            }
-            case EVENT_PROVISIONED_CHANGED:
-            case EVENT_PROVISIONING_DATA_ENABLED_CHANGED: {
-                updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_UNKNOWN);
-                break;
-            }
-            case EVENT_INITIALIZE: {
-                onInitialize();
-                break;
-            }
-            default:
-                loge("Unknown msg.what: " + msg.what);
-        }
-    }
-
-    /**
-     * Called when needed to register for all events that data network controller is interested.
-     */
-    private void onInitialize() {
-        mDataConfigManager.registerForConfigUpdate(this, EVENT_DATA_CONFIG_UPDATED);
-        mSettingsObserver.observe(Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
-                EVENT_PROVISIONED_CHANGED);
-        mSettingsObserver.observe(
-                Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED),
-                EVENT_PROVISIONING_DATA_ENABLED_CHANGED);
-        mPhone.getCallTracker().registerForVoiceCallStarted(this, EVENT_CALL_STATE_CHANGED, null);
-        mPhone.getCallTracker().registerForVoiceCallEnded(this, EVENT_CALL_STATE_CHANGED, null);
-        if (mPhone.getImsPhone() != null) {
-            mPhone.getImsPhone().getCallTracker().registerForVoiceCallStarted(
-                    this, EVENT_CALL_STATE_CHANGED, null);
-            mPhone.getImsPhone().getCallTracker().registerForVoiceCallEnded(
-                    this, EVENT_CALL_STATE_CHANGED, null);
-        }
-        mPhone.getContext().getSystemService(TelephonyRegistryManager.class)
-                .addOnSubscriptionsChangedListener(new OnSubscriptionsChangedListener() {
-                    @Override
-                    public void onSubscriptionsChanged() {
-                        if (mSubId != mPhone.getSubId()) {
-                            log("onSubscriptionsChanged: " + mSubId + " to " + mPhone.getSubId());
-                            obtainMessage(EVENT_SUBSCRIPTIONS_CHANGED, mPhone.getSubId())
-                                    .sendToTarget();
-                        }
-                    }
-                }, this::post);
-        updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_UNKNOWN);
-    }
-
-    /**
-     * Enable or disable data for a specific {@link TelephonyManager.DataEnabledReason}.
-     * @param reason The reason the data enabled change is taking place.
-     * @param enabled {@code true} to enable data for the given reason and {@code false} to disable.
-     * @param callingPackage The package that changed the data enabled state.
-     */
-    public void setDataEnabled(@TelephonyManager.DataEnabledReason int reason, boolean enabled,
-            String callingPackage) {
-        obtainMessage(EVENT_SET_DATA_ENABLED_FOR_REASON, reason, enabled ? 1 : 0, callingPackage)
-                .sendToTarget();
-    }
-
-    /**
-     * Check whether the data is enabled for a specific {@link TelephonyManager.DataEnabledReason}.
-     * @return {@code true} if data is enabled for the given reason and {@code false} otherwise.
-     */
-    public boolean isDataEnabledForReason(@TelephonyManager.DataEnabledReason int reason) {
-        if (reason == TelephonyManager.DATA_ENABLED_REASON_USER) {
-            return isUserDataEnabled();
-        } else {
-            return mDataEnabledSettings.get(reason);
-        }
-    }
-
-    private void updateDataEnabledAndNotify(@TelephonyManager.DataEnabledChangedReason int reason) {
-        updateDataEnabledAndNotify(reason, mPhone.getContext().getOpPackageName());
-    }
-
-    private void updateDataEnabledAndNotify(@TelephonyManager.DataEnabledChangedReason int reason,
-            @NonNull String callingPackage) {
-        boolean prevDataEnabled = mIsDataEnabled;
-        mIsDataEnabled = isDataEnabled(ApnSetting.TYPE_ALL);
-        log("mIsDataEnabled=" + mIsDataEnabled + ", prevDataEnabled=" + prevDataEnabled);
-        if (!mInitialized || prevDataEnabled != mIsDataEnabled) {
-            if (!mInitialized) mInitialized = true;
-            notifyDataEnabledChanged(mIsDataEnabled, reason, callingPackage);
-        }
-    }
-
-    /**
-     * Check whether the user data is enabled when the device is in the provisioning stage.
-     * In provisioning, we might want to enable mobile data depending on the value of
-     * Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, which is set by setupwizard.
-     * @return {@code true} if user data is enabled when provisioning and {@code false} otherwise.
-     */
-    private boolean isProvisioningDataEnabled() {
-        final String prov_property = SystemProperties.get("ro.com.android.prov_mobiledata",
-                "false");
-        boolean retVal = "true".equalsIgnoreCase(prov_property);
-
-        final int prov_mobile_data = Settings.Global.getInt(mResolver,
-                Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED,
-                retVal ? 1 : 0);
-        retVal = prov_mobile_data != 0;
-        log("getDataEnabled during provisioning retVal=" + retVal + " - (" + prov_property
-                + ", " + prov_mobile_data + ")");
-
-        return retVal;
-    }
-
-    /**
-     * Check whether the overall data is enabled for the device. Note that this value will only
-     * be accurate if {@link #isDataInitialized} is {@code true}.
-     * @return {@code true} if the overall data is enabled and {@code false} otherwise.
-     */
-    public boolean isDataEnabled() {
-        return mIsDataEnabled;
-    }
-
-    /**
-     * Check whether data enabled value has been initialized. If this is {@code false}, then
-     * {@link #isDataEnabled} is not guaranteed to be accurate. Once data is initialized,
-     * {@link DataSettingsManagerCallback#onDataEnabledChanged} will be invoked with reason
-     * {@link TelephonyManager#DATA_ENABLED_REASON_UNKNOWN}.
-     * @return {@code true} if the data enabled value is initialized and {@code false} otherwise.
-     */
-    public boolean isDataInitialized() {
-        // TODO: Create a new DATA_ENABLED_REASON_INITIALIZED for initial value broadcast
-        return mInitialized;
-    }
-
-    /**
-     * Check whether the overall data is enabled for the device for the given APN type.
-     * @param apnType A single APN type to check data enabled for.
-     * @return {@code true} if the overall data is enabled for the APN and {@code false} otherwise.
-     */
-    public boolean isDataEnabled(@ApnType int apnType) {
-        if (Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
-            return isProvisioningDataEnabled();
-        } else {
-            boolean userDataEnabled = isUserDataEnabled();
-            // Check if we should temporarily enable data in certain conditions.
-            boolean isDataEnabledOverridden = mDataEnabledOverride
-                    .shouldOverrideDataEnabledSettings(mPhone, apnType);
-
-            return ((userDataEnabled || isDataEnabledOverridden)
-                    && mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_POLICY)
-                    && mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_CARRIER)
-                    && mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_THERMAL));
-        }
-    }
-
-    private static boolean isStandAloneOpportunistic(int subId, Context context) {
-        SubscriptionInfo info = SubscriptionController.getInstance().getActiveSubscriptionInfo(
-                subId, context.getOpPackageName(), context.getAttributionTag());
-        return (info != null) && info.isOpportunistic() && info.getGroupUuid() == null;
-    }
-
-    /**
-     * Enable or disable user data.
-     * @param enabled {@code true} to enable user data and {@code false} to disable.
-     * @param callingPackage The package that changed the data enabled state.
-     */
-    private void setUserDataEnabled(boolean enabled, String callingPackage) {
-        // Can't disable data for stand alone opportunistic subscription.
-        if (isStandAloneOpportunistic(mSubId, mPhone.getContext()) && !enabled) return;
-        boolean changed = GlobalSettingsHelper.setInt(mPhone.getContext(),
-                Settings.Global.MOBILE_DATA, mSubId, (enabled ? 1 : 0));
-        log("Set user data enabled to " + enabled + ", changed=" + changed + ", callingPackage="
-                + callingPackage);
-        if (changed) {
-            logl("UserDataEnabled changed to " + enabled);
-            mPhone.notifyUserMobileDataStateChanged(enabled);
-            updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_USER, callingPackage);
-        }
-    }
-
-    /**
-     * Check whether user data is enabled for the device.
-     * @return {@code true} if user data is enabled and {@code false} otherwise.
-     */
-    private boolean isUserDataEnabled() {
-        if (Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) {
-            return isProvisioningDataEnabled();
-        }
-
-        // User data should always be true for opportunistic subscription.
-        if (isStandAloneOpportunistic(mSubId, mPhone.getContext())) return true;
-
-        boolean defaultVal = TelephonyProperties.mobile_data().orElse(true);
-
-        return GlobalSettingsHelper.getBoolean(mPhone.getContext(),
-                Settings.Global.MOBILE_DATA, mSubId, defaultVal);
-    }
-
-    /**
-     * Enable or disable policy data.
-     * @param enabled {@code true} to enable policy data and {@code false} to disable.
-     * @param callingPackage The package that changed the data enabled state.
-     */
-    private void setPolicyDataEnabled(boolean enabled, String callingPackage) {
-        if (mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_POLICY) != enabled) {
-            logl("PolicyDataEnabled changed to " + enabled + ", callingPackage=" + callingPackage);
-            mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_POLICY, enabled);
-            updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_POLICY, callingPackage);
-        }
-    }
-
-    /**
-     * Enable or disable carrier data.
-     * @param enabled {@code true} to enable carrier data and {@code false} to disable.
-     * @param callingPackage The package that changed the data enabled state.
-     */
-    private void setCarrierDataEnabled(boolean enabled, String callingPackage) {
-        if (mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_CARRIER) != enabled) {
-            logl("CarrierDataEnabled changed to " + enabled + ", callingPackage=" + callingPackage);
-            mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_CARRIER, enabled);
-            updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_CARRIER,
-                    callingPackage);
-        }
-    }
-
-    /**
-     * Enable or disable thermal data.
-     * @param enabled {@code true} to enable thermal data and {@code false} to disable.
-     * @param callingPackage The package that changed the data enabled state.
-     */
-    private void setThermalDataEnabled(boolean enabled, String callingPackage) {
-        if (mDataEnabledSettings.get(TelephonyManager.DATA_ENABLED_REASON_THERMAL) != enabled) {
-            logl("ThermalDataEnabled changed to " + enabled + ", callingPackage=" + callingPackage);
-            mDataEnabledSettings.put(TelephonyManager.DATA_ENABLED_REASON_THERMAL, enabled);
-            updateDataEnabledAndNotify(TelephonyManager.DATA_ENABLED_REASON_THERMAL,
-                    callingPackage);
-        }
-    }
-
-    /**
-     * Enable or disable data roaming from user settings.
-     * @param enabled {@code true} to enable data roaming and {@code false} to disable.
-     */
-    public void setDataRoamingEnabled(boolean enabled) {
-        obtainMessage(EVENT_SET_DATA_ROAMING_ENABLED, enabled).sendToTarget();
-    }
-
-    /**
-     * Enable or disable data roaming.
-     * @param enabled {@code true} to enable data roaming and {@code false} to disable.
-     */
-    private void setDataRoamingEnabledInternal(boolean enabled) {
-        // Will trigger handleDataOnRoamingChange() through observer
-        boolean changed = GlobalSettingsHelper.setBoolean(mPhone.getContext(),
-                Settings.Global.DATA_ROAMING, mSubId, enabled);
-        if (changed) {
-            logl("DataRoamingEnabled changed to " + enabled);
-            mDataSettingsManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                    () -> callback.onDataRoamingEnabledChanged(enabled)));
-        }
-    }
-
-    /**
-     * Check whether data roaming is enabled for the device based on the current
-     * {@link Settings.Global#DATA_ROAMING} value.
-     * @return {@code true} if data roaming is enabled and {@code false} otherwise.
-     */
-    public boolean isDataRoamingEnabled() {
-        return GlobalSettingsHelper.getBoolean(mPhone.getContext(),
-                Settings.Global.DATA_ROAMING, mSubId, isDefaultDataRoamingEnabled());
-    }
-
-    /**
-     * Check whether data roaming is enabled by default.
-     * This is true if {@link CarrierConfigManager#KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL}
-     * or the system property "ro.com.android.dataroaming" are true.
-     * @return {@code true} if data roaming is enabled by default and {@code false} otherwise.
-     */
-    public boolean isDefaultDataRoamingEnabled() {
-        return "true".equalsIgnoreCase(SystemProperties.get("ro.com.android.dataroaming", "false"))
-                || mPhone.getDataNetworkController().getDataConfigManager()
-                        .isDataRoamingEnabledByDefault();
-    }
-
-    /**
-     * Set default value for {@link android.provider.Settings.Global#DATA_ROAMING} if the user
-     * has not manually set the value. The default value is {@link #isDefaultDataRoamingEnabled()}.
-     */
-    public void setDefaultDataRoamingEnabled() {
-        // For SSSS, this is a per-phone property from DATA_ROAMING_IS_USER_SETTING_KEY.
-        // For DSDS, this is a per-sub property from Settings.Global.DATA_ROAMING + subId.
-        // If the user has not manually set the value, use the default value.
-        boolean useCarrierSpecificDefault = false;
-        if (mPhone.getContext().getSystemService(TelephonyManager.class).getSimCount() != 1) {
-            String setting = Settings.Global.DATA_ROAMING + mPhone.getSubId();
-            try {
-                Settings.Global.getInt(mResolver, setting);
-            } catch (Settings.SettingNotFoundException ex) {
-                // For multi-SIM phones, use the default value if uninitialized.
-                useCarrierSpecificDefault = true;
-            }
-        } else if (!isDataRoamingFromUserAction()) {
-            // For single-SIM phones, use the default value if user action is not set.
-            useCarrierSpecificDefault = true;
-        }
-        log("setDefaultDataRoamingEnabled: useCarrierSpecificDefault=" + useCarrierSpecificDefault);
-        if (useCarrierSpecificDefault) {
-            boolean defaultVal = isDefaultDataRoamingEnabled();
-            setDataRoamingEnabledInternal(defaultVal);
-        }
-    }
-
-    /**
-     * Get whether the user has manually enabled or disabled data roaming from settings.
-     * @return {@code true} if the user has enabled data roaming and {@code false} if they have not.
-     */
-    private boolean isDataRoamingFromUserAction() {
-        final SharedPreferences sp = PreferenceManager
-                .getDefaultSharedPreferences(mPhone.getContext());
-        // Since we don't want to unset user preferences after a system update, default to true if
-        // the preference does not exist and set it to false explicitly from factory reset.
-        if (!sp.contains(Phone.DATA_ROAMING_IS_USER_SETTING_KEY)) {
-            sp.edit().putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, false).commit();
-        }
-        return sp.getBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, true);
-    }
-
-    /**
-     * Indicate that the user has manually enabled or disabled the data roaming value from settings.
-     * If the user has not manually set the data roaming value, the default value from
-     * {@link #isDefaultDataRoamingEnabled()} will continue to be used.
-     */
-    private void setDataRoamingFromUserAction() {
-        final SharedPreferences.Editor sp = PreferenceManager
-                .getDefaultSharedPreferences(mPhone.getContext()).edit();
-        sp.putBoolean(Phone.DATA_ROAMING_IS_USER_SETTING_KEY, true).commit();
-    }
-
-    private @NonNull DataEnabledOverride getDataEnabledOverride() {
-        return new DataEnabledOverride(SubscriptionController.getInstance()
-                .getDataEnabledOverrideRules(mSubId));
-    }
-
-    /**
-     * Set whether to always allow the MMS data connection.
-     * @param alwaysAllow {@code true} if MMS data is always allowed and {@code false} otherwise.
-     */
-    public void setAlwaysAllowMmsData(boolean alwaysAllow) {
-        obtainMessage(EVENT_SET_ALWAYS_ALLOW_MMS_DATA, alwaysAllow).sendToTarget();
-    }
-
-    /**
-     * Check whether MMS is always allowed.
-     * @return {@code true} if MMS is always allowed and {@code false} otherwise.
-     */
-    public boolean isMmsAlwaysAllowed() {
-        return mDataEnabledOverride.isMmsAlwaysAllowed();
-    }
-
-    /**
-     * Set whether to allow mobile data during voice call. This is used for allowing data on the
-     * non-default data SIM. When a voice call is placed on the non-default data SIM on DSDS
-     * devices, users will not be able to use mobile data. By calling this API, data will be
-     * temporarily enabled on the non-default data SIM during the life cycle of the voice call.
-     * @param allow {@code true} if data is allowed during a voice call and {@code false} otherwise.
-     */
-    public void setAllowDataDuringVoiceCall(boolean allow) {
-        obtainMessage(EVENT_SET_ALLOW_DATA_DURING_VOICE_CALL, allow).sendToTarget();
-    }
-
-    /**
-     * Check whether data is allowed during a voice call.
-     * @return {@code true} if data is allowed during voice call and {@code false} otherwise.
-     */
-    public boolean isDataAllowedInVoiceCall() {
-        return mDataEnabledOverride.isDataAllowedInVoiceCall();
-    }
-
-    /**
-     * Check whether data stall recovery on bad network is enabled.
-     * @return {@code true} if data stall recovery is enabled and {@code false} otherwise.
-     */
-    public boolean isRecoveryOnBadNetworkEnabled() {
-        return Settings.Global.getInt(mResolver,
-                Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 1) == 1;
-    }
-
-    private void notifyDataEnabledChanged(boolean enabled,
-            @TelephonyManager.DataEnabledChangedReason int reason, @NonNull String callingPackage) {
-        logl("notifyDataEnabledChanged: enabled=" + enabled + ", reason="
-                + dataEnabledChangedReasonToString(reason) + ", callingPackage=" + callingPackage);
-        mDataSettingsManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                () -> callback.onDataEnabledChanged(enabled, reason, callingPackage)));
-        mPhone.notifyDataEnabled(enabled, reason);
-    }
-
-    private void notifyDataEnabledOverrideChanged(boolean enabled,
-            @TelephonyManager.MobileDataPolicy int policy) {
-        logl("notifyDataEnabledOverrideChanged: enabled=" + enabled);
-        mDataSettingsManagerCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                () -> callback.onDataEnabledOverrideChanged(enabled, policy)));
-    }
-
-    /**
-     * Register the callback for receiving information from {@link DataSettingsManager}.
-     *
-     * @param callback The callback.
-     */
-    public void registerCallback(@NonNull DataSettingsManagerCallback callback) {
-        mDataSettingsManagerCallbacks.add(callback);
-    }
-
-    /**
-     * Unregister the callback for receiving information from {@link DataSettingsManager}.
-     *
-     * @param callback The callback.
-     */
-    public void unregisterCallback(@NonNull DataSettingsManagerCallback callback) {
-        mDataSettingsManagerCallbacks.remove(callback);
-    }
-
-    private static String dataEnabledChangedReasonToString(
-            @TelephonyManager.DataEnabledChangedReason int reason) {
-        switch (reason) {
-            case TelephonyManager.DATA_ENABLED_REASON_USER:
-                return "USER";
-            case TelephonyManager.DATA_ENABLED_REASON_POLICY:
-                return "POLICY";
-            case TelephonyManager.DATA_ENABLED_REASON_CARRIER:
-                return "CARRIER";
-            case TelephonyManager.DATA_ENABLED_REASON_THERMAL:
-                return "THERMAL";
-            case TelephonyManager.DATA_ENABLED_REASON_OVERRIDE:
-                return "OVERRIDE";
-            default:
-                return "UNKNOWN";
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "[isUserDataEnabled=" + isUserDataEnabled()
-                + ", isProvisioningDataEnabled=" + isProvisioningDataEnabled()
-                + ", mIsDataEnabled=" + mIsDataEnabled
-                + ", mDataEnabledSettings=" + mDataEnabledSettings
-                + ", mDataEnabledOverride=" + mDataEnabledOverride
-                + "]";
-    }
-
-    /**
-     * Log debug messages.
-     * @param s debug messages
-     */
-    private void log(@NonNull String s) {
-        Rlog.d(mLogTag, s);
-    }
-
-    /**
-     * Log error messages.
-     * @param s error messages
-     */
-    private void loge(@NonNull String s) {
-        Rlog.e(mLogTag, s);
-    }
-
-    /**
-     * Log debug messages and also log into the local log.
-     * @param s debug messages
-     */
-    private void logl(@NonNull String s) {
-        log(s);
-        mLocalLog.log(s);
-    }
-
-    /**
-     * Dump the state of DataSettingsManager
-     *
-     * @param fd File descriptor
-     * @param printWriter Print writer
-     * @param args Arguments
-     */
-    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
-        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
-        pw.println(DataSettingsManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":");
-        pw.increaseIndent();
-        pw.println("mIsDataEnabled=" + mIsDataEnabled);
-        pw.println("isDataEnabled(internet)=" + isDataEnabled(ApnSetting.TYPE_DEFAULT));
-        pw.println("isDataEnabled(mms)=" + isDataEnabled(ApnSetting.TYPE_MMS));
-        pw.println("isUserDataEnabled=" + isUserDataEnabled());
-        pw.println("isDataRoamingEnabled=" + isDataRoamingEnabled());
-        pw.println("isDefaultDataRoamingEnabled=" + isDefaultDataRoamingEnabled());
-        pw.println("isDataRoamingFromUserAction=" + isDataRoamingFromUserAction());
-        pw.println("device_provisioned=" + Settings.Global.getInt(
-                mResolver, Settings.Global.DEVICE_PROVISIONED, 0));
-        pw.println("isProvisioningDataEnabled=" + isProvisioningDataEnabled());
-        pw.println("data_stall_recovery_on_bad_network=" + Settings.Global.getInt(
-                mResolver, Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 1));
-        pw.println("mDataEnabledSettings=" + mDataEnabledSettings.entrySet().stream()
-                .map(entry ->
-                        dataEnabledChangedReasonToString(entry.getKey()) + "=" + entry.getValue())
-                .collect(Collectors.joining(", ")));
-        pw.println("mDataEnabledOverride=" + mDataEnabledOverride);
-        pw.println("Local logs:");
-        pw.increaseIndent();
-        mLocalLog.dump(fd, pw, args);
-        pw.decreaseIndent();
-        pw.decreaseIndent();
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java b/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
deleted file mode 100644
index 22d0498..0000000
--- a/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
+++ /dev/null
@@ -1,828 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.ElapsedRealtimeLong;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.content.Intent;
-import android.net.NetworkAgent;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.SystemClock;
-import android.telephony.Annotation.RadioPowerState;
-import android.telephony.Annotation.ValidationStatus;
-import android.telephony.CellSignalStrength;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.telephony.data.DataProfile;
-import android.util.IndentingPrintWriter;
-import android.util.LocalLog;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
-import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback;
-import com.android.internal.telephony.metrics.DataStallRecoveryStats;
-import com.android.internal.telephony.metrics.TelephonyMetrics;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.Executor;
-
-/**
- * DataStallRecoveryManager monitors the network validation result from connectivity service and
- * takes actions to recovery data network.
- */
-public class DataStallRecoveryManager extends Handler {
-    private static final boolean VDBG = false;
-
-    /** Recovery actions taken in case of data stall */
-    @IntDef(
-            value = {
-                RECOVERY_ACTION_GET_DATA_CALL_LIST,
-                RECOVERY_ACTION_CLEANUP,
-                RECOVERY_ACTION_REREGISTER,
-                RECOVERY_ACTION_RADIO_RESTART,
-                RECOVERY_ACTION_RESET_MODEM
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface RecoveryAction {};
-
-    /* DataStallRecoveryManager queries RIL for link properties (IP addresses, DNS server addresses
-     * etc) using RIL_REQUEST_GET_DATA_CALL_LIST.  This will help in cases where the data stall
-     * occurred because of a link property changed but not notified to connectivity service.
-     */
-    public static final int RECOVERY_ACTION_GET_DATA_CALL_LIST = 0;
-
-    /* DataStallRecoveryManager will request DataNetworkController to reestablish internet using
-     * RIL_REQUEST_DEACTIVATE_DATA_CALL and sets up the data call back using SETUP_DATA_CALL.
-     * It will help to reestablish the channel between RIL and modem.
-     */
-    public static final int RECOVERY_ACTION_CLEANUP = 1;
-
-    /**
-     * Add the RECOVERY_ACTION_REREGISTER to align the RecoveryActions between
-     * DataStallRecoveryManager and atoms.proto. In Android T, This action will not process because
-     * the boolean array for skip recovery action is default true in carrier config setting.
-     *
-     * @deprecated Do not use.
-     */
-    @java.lang.Deprecated
-    public static final int RECOVERY_ACTION_REREGISTER = 2;
-
-    /* DataStallRecoveryManager will request ServiceStateTracker to send RIL_REQUEST_RADIO_POWER
-     * to restart radio. It will restart the radio and re-attch to the network.
-     */
-    public static final int RECOVERY_ACTION_RADIO_RESTART = 3;
-
-    /* DataStallRecoveryManager will request to reboot modem using NV_RESET_CONFIG. It will recover
-     * if there is a problem in modem side.
-     */
-    public static final int RECOVERY_ACTION_RESET_MODEM = 4;
-
-    /** Recovered reason taken in case of data stall recovered */
-    @IntDef(
-            value = {
-                RECOVERED_REASON_NONE,
-                RECOVERED_REASON_DSRM,
-                RECOVERED_REASON_MODEM,
-                RECOVERED_REASON_USER
-            })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface RecoveredReason {};
-
-    /** The reason when data stall recovered. */
-    /** The data stall not recovered yet. */
-    private static final int RECOVERED_REASON_NONE = 0;
-    /** The data stall recovered by our DataStallRecoveryManager. */
-    private static final int RECOVERED_REASON_DSRM = 1;
-    /** The data stall recovered by modem(Radio Power off/on). */
-    private static final int RECOVERED_REASON_MODEM = 2;
-    /** The data stall recovered by user (Mobile Data Power off/on). */
-    private static final int RECOVERED_REASON_USER = 3;
-
-    /** Event for data config updated. */
-    private static final int EVENT_DATA_CONFIG_UPDATED = 1;
-
-    /** Event for triggering recovery action. */
-    private static final int EVENT_DO_RECOVERY = 2;
-
-    /** Event for radio state changed. */
-    private static final int EVENT_RADIO_STATE_CHANGED = 3;
-
-    private final @NonNull Phone mPhone;
-    private final @NonNull String mLogTag;
-    private final @NonNull LocalLog mLocalLog = new LocalLog(128);
-
-    /** Data network controller */
-    private final @NonNull DataNetworkController mDataNetworkController;
-
-    /** Data config manager */
-    private final @NonNull DataConfigManager mDataConfigManager;
-
-    /** Cellular data service */
-    private final @NonNull DataServiceManager mWwanDataServiceManager;
-
-    /** The data stall recovery action. */
-    private @RecoveryAction int mRecovryAction;
-    /** The elapsed real time of last recovery attempted */
-    private @ElapsedRealtimeLong long mTimeLastRecoveryStartMs;
-    /** Whether current network is good or not */
-    private boolean mIsValidNetwork;
-    /** Whether data stall happened or not. */
-    private boolean mDataStalled;
-    /** Whether the result of last action(RADIO_RESTART) reported. */
-    private boolean mLastActionReported;
-    /** The real time for data stall start. */
-    private @ElapsedRealtimeLong long mDataStallStartMs;
-    /** Last data stall recovery action. */
-    private @RecoveryAction int mLastAction;
-    /** Last radio power state. */
-    private @RadioPowerState int mRadioPowerState;
-    /** Whether the NetworkCheckTimer start. */
-    private boolean mNetworkCheckTimerStarted = false;
-    /** Whether radio state changed during data stall. */
-    private boolean mRadioStateChangedDuringDataStall;
-    /** Whether mobile data change to Enabled during data stall. */
-    private boolean mMobileDataChangedToEnabledDuringDataStall;
-    /** Whether attempted all recovery steps. */
-    private boolean mIsAttemptedAllSteps;
-    /** Whether internet network connected. */
-    private boolean mIsInternetNetworkConnected;
-
-    /** The array for the timers between recovery actions. */
-    private @NonNull long[] mDataStallRecoveryDelayMillisArray;
-    /** The boolean array for the flags. They are used to skip the recovery actions if needed. */
-    private @NonNull boolean[] mSkipRecoveryActionArray;
-
-    private DataStallRecoveryManagerCallback mDataStallRecoveryManagerCallback;
-
-    /**
-     * The data stall recovery manager callback. Note this is only used for passing information
-     * internally in the data stack, should not be used externally.
-     */
-    public abstract static class DataStallRecoveryManagerCallback extends DataCallback {
-        /**
-         * Constructor
-         *
-         * @param executor The executor of the callback.
-         */
-        public DataStallRecoveryManagerCallback(@NonNull @CallbackExecutor Executor executor) {
-            super(executor);
-        }
-
-        /**
-         * Called when data stall occurs and needed to tear down / setup a new data network for
-         * internet.
-         */
-        public abstract void onDataStallReestablishInternet();
-    }
-
-    /**
-     * Constructor
-     *
-     * @param phone The phone instance.
-     * @param dataNetworkController Data network controller
-     * @param dataServiceManager The WWAN data service manager.
-     * @param looper The looper to be used by the handler. Currently the handler thread is the phone
-     *     process's main thread.
-     * @param callback Callback to notify data network controller for data stall events.
-     */
-    public DataStallRecoveryManager(
-            @NonNull Phone phone,
-            @NonNull DataNetworkController dataNetworkController,
-            @NonNull DataServiceManager dataServiceManager,
-            @NonNull Looper looper,
-            @NonNull DataStallRecoveryManagerCallback callback) {
-        super(looper);
-        mPhone = phone;
-        mLogTag = "DSRM-" + mPhone.getPhoneId();
-        log("DataStallRecoveryManager created.");
-        mDataNetworkController = dataNetworkController;
-        mWwanDataServiceManager = dataServiceManager;
-        mDataConfigManager = mDataNetworkController.getDataConfigManager();
-        mDataNetworkController
-                .getDataSettingsManager()
-                .registerCallback(
-                        new DataSettingsManagerCallback(this::post) {
-                            @Override
-                            public void onDataEnabledChanged(
-                                    boolean enabled,
-                                    @TelephonyManager.DataEnabledChangedReason int reason,
-                                    @NonNull String callingPackage) {
-                                onMobileDataEnabledChanged(enabled);
-                            }
-                        });
-        mDataStallRecoveryManagerCallback = callback;
-        mRadioPowerState = mPhone.getRadioPowerState();
-        updateDataStallRecoveryConfigs();
-
-        registerAllEvents();
-    }
-
-    /** Register for all events that data stall monitor is interested. */
-    private void registerAllEvents() {
-        mDataConfigManager.registerForConfigUpdate(this, EVENT_DATA_CONFIG_UPDATED);
-        mDataNetworkController.registerDataNetworkControllerCallback(
-                new DataNetworkControllerCallback(this::post) {
-                    @Override
-                    public void onInternetDataNetworkValidationStatusChanged(
-                            @ValidationStatus int validationStatus) {
-                        onInternetValidationStatusChanged(validationStatus);
-                    }
-
-                    @Override
-                    public void onInternetDataNetworkConnected(
-                            @NonNull List<DataProfile> dataProfiles) {
-                        mIsInternetNetworkConnected = true;
-                        logl("onInternetDataNetworkConnected");
-                    }
-
-                    @Override
-                    public void onInternetDataNetworkDisconnected() {
-                        mIsInternetNetworkConnected = false;
-                        logl("onInternetDataNetworkDisconnected");
-                    }
-                });
-        mPhone.mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null);
-    }
-
-    @Override
-    public void handleMessage(Message msg) {
-        logv("handleMessage = " + msg);
-        switch (msg.what) {
-            case EVENT_DATA_CONFIG_UPDATED:
-                onDataConfigUpdated();
-                break;
-            case EVENT_DO_RECOVERY:
-                doRecovery();
-                break;
-            case EVENT_RADIO_STATE_CHANGED:
-                mRadioPowerState = mPhone.getRadioPowerState();
-                if (mDataStalled) {
-                    // Store the radio state changed flag only when data stall occurred.
-                    mRadioStateChangedDuringDataStall = true;
-                }
-                break;
-            default:
-                loge("Unexpected message = " + msg);
-                break;
-        }
-    }
-
-    /** Update the data stall recovery configs from DataConfigManager. */
-    private void updateDataStallRecoveryConfigs() {
-        mDataStallRecoveryDelayMillisArray = mDataConfigManager.getDataStallRecoveryDelayMillis();
-        mSkipRecoveryActionArray = mDataConfigManager.getDataStallRecoveryShouldSkipArray();
-    }
-
-    /**
-     * Get the duration for specific data stall recovery action.
-     *
-     * @param recoveryAction The recovery action to query.
-     * @return the delay in milliseconds for the specific recovery action.
-     */
-    private long getDataStallRecoveryDelayMillis(@RecoveryAction int recoveryAction) {
-        return mDataStallRecoveryDelayMillisArray[recoveryAction];
-    }
-
-    /**
-     * Check if the recovery action needs to be skipped.
-     *
-     * @param recoveryAction The recovery action.
-     * @return {@code true} if the action needs to be skipped.
-     */
-    private boolean shouldSkipRecoveryAction(@RecoveryAction int recoveryAction) {
-        return mSkipRecoveryActionArray[recoveryAction];
-    }
-
-    /** Called when data config was updated. */
-    private void onDataConfigUpdated() {
-        updateDataStallRecoveryConfigs();
-    }
-
-    /**
-     * Called when mobile data setting changed.
-     *
-     * @param enabled true for mobile data settings enabled & false for disabled.
-     */
-    private void onMobileDataEnabledChanged(boolean enabled) {
-        logl("onMobileDataEnabledChanged: DataEnabled:" + enabled + ",DataStalled:" + mDataStalled);
-        // Store the mobile data changed flag (from disabled to enabled) as TRUE
-        // during data stalled.
-        if (mDataStalled && enabled) {
-            mMobileDataChangedToEnabledDuringDataStall = true;
-        }
-    }
-
-    /**
-     * Called when internet validation status passed. We will initialize all parameters.
-     */
-    private void reset() {
-        mIsValidNetwork = true;
-        mIsAttemptedAllSteps = false;
-        mRadioStateChangedDuringDataStall = false;
-        mMobileDataChangedToEnabledDuringDataStall = false;
-        cancelNetworkCheckTimer();
-        mTimeLastRecoveryStartMs = 0;
-        mLastAction = RECOVERY_ACTION_GET_DATA_CALL_LIST;
-        mRecovryAction = RECOVERY_ACTION_GET_DATA_CALL_LIST;
-    }
-
-    /**
-     * Called when internet validation status changed.
-     *
-     * @param validationStatus Validation status.
-     */
-    private void onInternetValidationStatusChanged(@ValidationStatus int status) {
-        logl("onInternetValidationStatusChanged: " + DataUtils.validationStatusToString(status));
-        final boolean isValid = status == NetworkAgent.VALIDATION_STATUS_VALID;
-        setNetworkValidationState(isValid);
-        if (isValid) {
-            reset();
-        } else {
-            if (mIsValidNetwork || isRecoveryAlreadyStarted()) {
-                mIsValidNetwork = false;
-                if (isRecoveryNeeded(true)) {
-                    log("trigger data stall recovery");
-                    mTimeLastRecoveryStartMs = SystemClock.elapsedRealtime();
-                    sendMessage(obtainMessage(EVENT_DO_RECOVERY));
-                }
-            }
-        }
-    }
-
-    /** Reset the action to initial step. */
-    private void resetAction() {
-        mTimeLastRecoveryStartMs = 0;
-        mMobileDataChangedToEnabledDuringDataStall = false;
-        mRadioStateChangedDuringDataStall = false;
-        setRecoveryAction(RECOVERY_ACTION_GET_DATA_CALL_LIST);
-    }
-
-    /**
-     * Get recovery action from settings.
-     *
-     * @return recovery action
-     */
-    @VisibleForTesting
-    @RecoveryAction
-    public int getRecoveryAction() {
-        log("getRecoveryAction: " + recoveryActionToString(mRecovryAction));
-        return mRecovryAction;
-    }
-
-    /**
-     * Put recovery action into settings.
-     *
-     * @param action The next recovery action.
-     */
-    @VisibleForTesting
-    public void setRecoveryAction(@RecoveryAction int action) {
-        mRecovryAction = action;
-
-        // Check if the mobile data enabled is TRUE, it means that the mobile data setting changed
-        // from DISABLED to ENABLED, we will set the next recovery action to
-        // RECOVERY_ACTION_RADIO_RESTART due to already did the RECOVERY_ACTION_CLEANUP.
-        if (mMobileDataChangedToEnabledDuringDataStall
-                && mRecovryAction < RECOVERY_ACTION_RADIO_RESTART) {
-            mRecovryAction = RECOVERY_ACTION_RADIO_RESTART;
-        }
-        // Check if the radio state changed from off to on, it means that the modem already
-        // did the radio restart, we will set the next action to RECOVERY_ACTION_RESET_MODEM.
-        if (mRadioStateChangedDuringDataStall
-                && mRadioPowerState == TelephonyManager.RADIO_POWER_ON) {
-            mRecovryAction = RECOVERY_ACTION_RESET_MODEM;
-        }
-        // To check the flag from DataConfigManager if we need to skip the step.
-        if (shouldSkipRecoveryAction(mRecovryAction)) {
-            switch (mRecovryAction) {
-                case RECOVERY_ACTION_GET_DATA_CALL_LIST:
-                    setRecoveryAction(RECOVERY_ACTION_CLEANUP);
-                    break;
-                case RECOVERY_ACTION_CLEANUP:
-                    setRecoveryAction(RECOVERY_ACTION_RADIO_RESTART);
-                    break;
-                case RECOVERY_ACTION_RADIO_RESTART:
-                    setRecoveryAction(RECOVERY_ACTION_RESET_MODEM);
-                    break;
-                case RECOVERY_ACTION_RESET_MODEM:
-                    resetAction();
-                    break;
-            }
-        }
-
-        log("setRecoveryAction: " + recoveryActionToString(mRecovryAction));
-    }
-
-    /**
-     * Check if recovery already started.
-     *
-     * @return {@code true} if recovery already started, {@code false} recovery not started.
-     */
-    private boolean isRecoveryAlreadyStarted() {
-        return getRecoveryAction() != RECOVERY_ACTION_GET_DATA_CALL_LIST;
-    }
-
-    /**
-     * Get elapsed time since last recovery.
-     *
-     * @return the time since last recovery started.
-     */
-    private long getElapsedTimeSinceRecoveryMs() {
-        return (SystemClock.elapsedRealtime() - mTimeLastRecoveryStartMs);
-    }
-
-    /**
-     * Broadcast intent when data stall occurred.
-     *
-     * @param recoveryAction Send the data stall detected intent with RecoveryAction info.
-     */
-    private void broadcastDataStallDetected(@RecoveryAction int recoveryAction) {
-        log("broadcastDataStallDetected recoveryAction: " + recoveryAction);
-        Intent intent = new Intent(TelephonyManager.ACTION_DATA_STALL_DETECTED);
-        SubscriptionManager.putPhoneIdAndSubIdExtra(intent, mPhone.getPhoneId());
-        intent.putExtra(TelephonyManager.EXTRA_RECOVERY_ACTION, recoveryAction);
-        mPhone.getContext().sendBroadcast(intent);
-    }
-
-    /** Recovery Action: RECOVERY_ACTION_GET_DATA_CALL_LIST */
-    private void getDataCallList() {
-        log("getDataCallList: request data call list");
-        mWwanDataServiceManager.requestDataCallList(null);
-    }
-
-    /** Recovery Action: RECOVERY_ACTION_CLEANUP */
-    private void cleanUpDataNetwork() {
-        log("cleanUpDataNetwork: notify clean up data network");
-        mDataStallRecoveryManagerCallback.invokeFromExecutor(
-                () -> mDataStallRecoveryManagerCallback.onDataStallReestablishInternet());
-    }
-
-    /** Recovery Action: RECOVERY_ACTION_RADIO_RESTART */
-    private void powerOffRadio() {
-        log("powerOffRadio: Restart radio");
-        mPhone.getServiceStateTracker().powerOffRadioSafely();
-    }
-
-    /** Recovery Action: RECOVERY_ACTION_RESET_MODEM */
-    private void rebootModem() {
-        log("rebootModem: reboot modem");
-        mPhone.rebootModem(null);
-    }
-
-    /**
-     * Initialize the network check timer.
-     *
-     * @param action The recovery action to start the network check timer.
-     */
-    private void startNetworkCheckTimer(@RecoveryAction int action) {
-        // Ignore send message delayed due to reached the last action.
-        if (action == RECOVERY_ACTION_RESET_MODEM) return;
-        log("startNetworkCheckTimer(): " + getDataStallRecoveryDelayMillis(action) + "ms");
-        if (!mNetworkCheckTimerStarted) {
-            mNetworkCheckTimerStarted = true;
-            mTimeLastRecoveryStartMs = SystemClock.elapsedRealtime();
-            sendMessageDelayed(
-                    obtainMessage(EVENT_DO_RECOVERY), getDataStallRecoveryDelayMillis(action));
-        }
-    }
-
-    /** Cancel the network check timer. */
-    private void cancelNetworkCheckTimer() {
-        log("cancelNetworkCheckTimer()");
-        if (mNetworkCheckTimerStarted) {
-            mNetworkCheckTimerStarted = false;
-            removeMessages(EVENT_DO_RECOVERY);
-        }
-    }
-
-    /**
-     * Check the conditions if we need to do recovery action.
-     *
-     * @param isNeedToCheckTimer {@code true} indicating we need the check timer when
-     * we receive the internet validation status changed.
-     * @return {@code true} if need to do recovery action, {@code false} no need to do recovery
-     *     action.
-     */
-    private boolean isRecoveryNeeded(boolean isNeedToCheckTimer) {
-        logv("enter: isRecoveryNeeded()");
-
-        // Skip recovery if we have already attempted all steps.
-        if (mIsAttemptedAllSteps) {
-            logl("skip retrying continue recovery action");
-            return false;
-        }
-
-        // To avoid back to back recovery, wait for a grace period
-        if (getElapsedTimeSinceRecoveryMs() < getDataStallRecoveryDelayMillis(mLastAction)
-                && isNeedToCheckTimer) {
-            logl("skip back to back data stall recovery");
-            return false;
-        }
-
-        // Skip recovery if it can cause a call to drop
-        if (mPhone.getState() != PhoneConstants.State.IDLE
-                && getRecoveryAction() > RECOVERY_ACTION_CLEANUP) {
-            logl("skip data stall recovery as there is an active call");
-            return false;
-        }
-
-        // Skip when poor signal strength
-        if (mPhone.getSignalStrength().getLevel() <= CellSignalStrength.SIGNAL_STRENGTH_POOR) {
-            logl("skip data stall recovery as in poor signal condition");
-            return false;
-        }
-
-        if (!mDataNetworkController.isInternetDataAllowed()) {
-            logl("skip data stall recovery as data not allowed.");
-            return false;
-        }
-
-        if (!mIsInternetNetworkConnected) {
-            logl("skip data stall recovery as data not connected");
-            return false;
-        }
-
-        return true;
-    }
-
-    /**
-     * Set the validation status into metrics.
-     *
-     * @param isValid true for validation passed & false for validation failed
-     */
-    private void setNetworkValidationState(boolean isValid) {
-        // Validation status is true and was not data stall.
-        if (isValid && !mDataStalled) {
-            return;
-        }
-
-        if (!mDataStalled) {
-            mDataStalled = true;
-            mDataStallStartMs = SystemClock.elapsedRealtime();
-            logl("data stall: start time = " + DataUtils.elapsedTimeToString(mDataStallStartMs));
-            return;
-        }
-
-        if (!mLastActionReported) {
-            @RecoveredReason int reason = getRecoveredReason(isValid);
-            int timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs);
-            logl(
-                    "data stall: lastaction = "
-                            + recoveryActionToString(mLastAction)
-                            + ", isRecovered = "
-                            + isValid
-                            + ", reason = "
-                            + recoveredReasonToString(reason)
-                            + ", TimeDuration = "
-                            + timeDuration);
-            DataStallRecoveryStats.onDataStallEvent(
-                    mLastAction, mPhone, isValid, timeDuration, reason);
-            mLastActionReported = true;
-        }
-
-        if (isValid) {
-            mLastActionReported = false;
-            mDataStalled = false;
-        }
-    }
-
-    /**
-     * Get the data stall recovered reason.
-     *
-     * @param isValid true for validation passed & false for validation failed
-     */
-    @RecoveredReason
-    private int getRecoveredReason(boolean isValid) {
-        if (!isValid) return RECOVERED_REASON_NONE;
-
-        int ret = RECOVERED_REASON_DSRM;
-        if (mRadioStateChangedDuringDataStall) {
-            if (mLastAction <= RECOVERY_ACTION_CLEANUP) {
-                ret = RECOVERED_REASON_MODEM;
-            }
-            if (mLastAction > RECOVERY_ACTION_CLEANUP) {
-                ret = RECOVERED_REASON_DSRM;
-            }
-        } else if (mMobileDataChangedToEnabledDuringDataStall) {
-            ret = RECOVERED_REASON_USER;
-        }
-        return ret;
-    }
-
-    /** Perform a series of data stall recovery actions. */
-    private void doRecovery() {
-        @RecoveryAction final int recoveryAction = getRecoveryAction();
-        final int signalStrength = mPhone.getSignalStrength().getLevel();
-
-        // DSRM used sendMessageDelayed to process the next event EVENT_DO_RECOVERY, so it need
-        // to check the condition if DSRM need to process the recovery action.
-        if (!isRecoveryNeeded(false)) {
-            cancelNetworkCheckTimer();
-            startNetworkCheckTimer(recoveryAction);
-            return;
-        }
-
-        TelephonyMetrics.getInstance()
-                .writeSignalStrengthEvent(mPhone.getPhoneId(), signalStrength);
-        TelephonyMetrics.getInstance().writeDataStallEvent(mPhone.getPhoneId(), recoveryAction);
-        mLastAction = recoveryAction;
-        mLastActionReported = false;
-        broadcastDataStallDetected(recoveryAction);
-        mNetworkCheckTimerStarted = false;
-
-        switch (recoveryAction) {
-            case RECOVERY_ACTION_GET_DATA_CALL_LIST:
-                logl("doRecovery(): get data call list");
-                getDataCallList();
-                setRecoveryAction(RECOVERY_ACTION_CLEANUP);
-                break;
-            case RECOVERY_ACTION_CLEANUP:
-                logl("doRecovery(): cleanup all connections");
-                cleanUpDataNetwork();
-                setRecoveryAction(RECOVERY_ACTION_RADIO_RESTART);
-                break;
-            case RECOVERY_ACTION_RADIO_RESTART:
-                logl("doRecovery(): restarting radio");
-                setRecoveryAction(RECOVERY_ACTION_RESET_MODEM);
-                powerOffRadio();
-                break;
-            case RECOVERY_ACTION_RESET_MODEM:
-                logl("doRecovery(): modem reset");
-                rebootModem();
-                resetAction();
-                mIsAttemptedAllSteps = true;
-                break;
-            default:
-                throw new RuntimeException(
-                        "doRecovery: Invalid recoveryAction = "
-                                + recoveryActionToString(recoveryAction));
-        }
-
-        startNetworkCheckTimer(mLastAction);
-    }
-
-    /**
-     * Convert @RecoveredReason to string
-     *
-     * @param reason The recovered reason.
-     * @return The recovered reason in string format.
-     */
-    private static @NonNull String recoveredReasonToString(@RecoveredReason int reason) {
-        switch (reason) {
-            case RECOVERED_REASON_NONE:
-                return "RECOVERED_REASON_NONE";
-            case RECOVERED_REASON_DSRM:
-                return "RECOVERED_REASON_DSRM";
-            case RECOVERED_REASON_MODEM:
-                return "RECOVERED_REASON_MODEM";
-            case RECOVERED_REASON_USER:
-                return "RECOVERED_REASON_USER";
-            default:
-                return "Unknown(" + reason + ")";
-        }
-    }
-
-    /**
-     * Convert RadioPowerState to string
-     *
-     * @param state The radio power state
-     * @return The radio power state in string format.
-     */
-    private static @NonNull String radioPowerStateToString(@RadioPowerState int state) {
-        switch (state) {
-            case TelephonyManager.RADIO_POWER_OFF:
-                return "RADIO_POWER_OFF";
-            case TelephonyManager.RADIO_POWER_ON:
-                return "RADIO_POWER_ON";
-            case TelephonyManager.RADIO_POWER_UNAVAILABLE:
-                return "RADIO_POWER_UNAVAILABLE";
-            default:
-                return "Unknown(" + state + ")";
-        }
-    }
-
-    /**
-     * Convert RecoveryAction to string
-     *
-     * @param action The recovery action
-     * @return The recovery action in string format.
-     */
-    private static @NonNull String recoveryActionToString(@RecoveryAction int action) {
-        switch (action) {
-            case RECOVERY_ACTION_GET_DATA_CALL_LIST:
-                return "RECOVERY_ACTION_GET_DATA_CALL_LIST";
-            case RECOVERY_ACTION_CLEANUP:
-                return "RECOVERY_ACTION_CLEANUP";
-            case RECOVERY_ACTION_RADIO_RESTART:
-                return "RECOVERY_ACTION_RADIO_RESTART";
-            case RECOVERY_ACTION_RESET_MODEM:
-                return "RECOVERY_ACTION_RESET_MODEM";
-            default:
-                return "Unknown(" + action + ")";
-        }
-    }
-
-    /**
-     * Log debug messages.
-     *
-     * @param s debug messages
-     */
-    private void log(@NonNull String s) {
-        Rlog.d(mLogTag, s);
-    }
-
-    /**
-     * Log verbose messages.
-     *
-     * @param s debug messages.
-     */
-    private void logv(@NonNull String s) {
-        if (VDBG) Rlog.v(mLogTag, s);
-    }
-
-    /**
-     * Log error messages.
-     *
-     * @param s error messages
-     */
-    private void loge(@NonNull String s) {
-        Rlog.e(mLogTag, s);
-    }
-
-    /**
-     * Log debug messages and also log into the local log.
-     *
-     * @param s debug messages
-     */
-    private void logl(@NonNull String s) {
-        log(s);
-        mLocalLog.log(s);
-    }
-
-    /**
-     * Dump the state of DataStallRecoveryManager
-     *
-     * @param fd File descriptor
-     * @param printWriter Print writer
-     * @param args Arguments
-     */
-    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
-        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
-        pw.println(
-                DataStallRecoveryManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":");
-        pw.increaseIndent();
-
-        pw.println("mIsValidNetwork=" + mIsValidNetwork);
-        pw.println("mIsInternetNetworkConnected=" + mIsInternetNetworkConnected);
-        pw.println("mDataStalled=" + mDataStalled);
-        pw.println("mLastAction=" + recoveryActionToString(mLastAction));
-        pw.println("mIsAttemptedAllSteps=" + mIsAttemptedAllSteps);
-        pw.println("mDataStallStartMs=" + DataUtils.elapsedTimeToString(mDataStallStartMs));
-        pw.println("mRadioPowerState=" + radioPowerStateToString(mRadioPowerState));
-        pw.println("mLastActionReported=" + mLastActionReported);
-        pw.println("mTimeLastRecoveryStartMs="
-                        + DataUtils.elapsedTimeToString(mTimeLastRecoveryStartMs));
-        pw.println("getRecoveryAction()=" + recoveryActionToString(getRecoveryAction()));
-        pw.println("mRadioStateChangedDuringDataStall=" + mRadioStateChangedDuringDataStall);
-        pw.println(
-                "mMobileDataChangedToEnabledDuringDataStall="
-                        + mMobileDataChangedToEnabledDuringDataStall);
-        pw.println(
-                "DataStallRecoveryDelayMillisArray="
-                        + Arrays.toString(mDataStallRecoveryDelayMillisArray));
-        pw.println("SkipRecoveryActionArray=" + Arrays.toString(mSkipRecoveryActionArray));
-        pw.decreaseIndent();
-        pw.println("");
-
-        pw.println("Local logs:");
-        pw.increaseIndent();
-        mLocalLog.dump(fd, pw, args);
-        pw.decreaseIndent();
-        pw.decreaseIndent();
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/DataUtils.java b/src/java/com/android/internal/telephony/data/DataUtils.java
deleted file mode 100644
index 0bfddc2..0000000
--- a/src/java/com/android/internal/telephony/data/DataUtils.java
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.CurrentTimeMillisLong;
-import android.annotation.ElapsedRealtimeLong;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.NetworkAgent;
-import android.net.NetworkCapabilities;
-import android.os.SystemClock;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.AccessNetworkConstants.RadioAccessNetworkType;
-import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.Annotation.DataActivityType;
-import android.telephony.Annotation.NetCapability;
-import android.telephony.Annotation.NetworkType;
-import android.telephony.Annotation.ValidationStatus;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.ApnSetting.ApnType;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataCallResponse.LinkStatus;
-import android.telephony.data.DataProfile;
-import android.telephony.ims.feature.ImsFeature;
-import android.util.ArrayMap;
-
-import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
-
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-/**
- * This class contains all the utility methods used by telephony data stack.
- */
-public class DataUtils {
-    /** The time format for converting time to readable string. */
-    private static final SimpleDateFormat TIME_FORMAT =
-            new SimpleDateFormat("HH:mm:ss.SSS", Locale.US);
-
-    /**
-     * Get the network capability from the string.
-     *
-     * @param capabilityString The capability in string format
-     * @return The network capability. -1 if not found.
-     */
-    public static @NetCapability int getNetworkCapabilityFromString(
-            @NonNull String capabilityString) {
-        switch (capabilityString.toUpperCase(Locale.ROOT)) {
-            case "MMS": return NetworkCapabilities.NET_CAPABILITY_MMS;
-            case "SUPL": return NetworkCapabilities.NET_CAPABILITY_SUPL;
-            case "DUN": return NetworkCapabilities.NET_CAPABILITY_DUN;
-            case "FOTA": return NetworkCapabilities.NET_CAPABILITY_FOTA;
-            case "IMS": return NetworkCapabilities.NET_CAPABILITY_IMS;
-            case "CBS": return NetworkCapabilities.NET_CAPABILITY_CBS;
-            case "XCAP": return NetworkCapabilities.NET_CAPABILITY_XCAP;
-            case "EIMS": return NetworkCapabilities.NET_CAPABILITY_EIMS;
-            case "INTERNET": return NetworkCapabilities.NET_CAPABILITY_INTERNET;
-            case "MCX": return NetworkCapabilities.NET_CAPABILITY_MCX;
-            case "VSIM": return NetworkCapabilities.NET_CAPABILITY_VSIM;
-            case "BIP" : return NetworkCapabilities.NET_CAPABILITY_BIP;
-            case "ENTERPRISE": return NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
-            case "PRIORITIZE_BANDWIDTH":
-                return NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH;
-            case "PRIORITIZE_LATENCY":
-                return NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY;
-            default:
-                return -1;
-        }
-    }
-
-    /**
-     * Get Set of network capabilities from string joined by {@code |}, space is ignored.
-     * If input string contains unknown capability or malformatted(e.g. empty string), -1 is
-     * included in the returned set.
-     *
-     * @param capabilitiesString capability strings joined by {@code |}
-     * @return Set of capabilities
-     */
-    public static @NetCapability Set<Integer> getNetworkCapabilitiesFromString(
-            @NonNull String capabilitiesString) {
-        // e.g. "IMS|" is not allowed
-        if (!capabilitiesString.matches("(\\s*[a-zA-Z]+\\s*)(\\|\\s*[a-zA-Z]+\\s*)*")) {
-            return Collections.singleton(-1);
-        }
-        return Arrays.stream(capabilitiesString.split("\\s*\\|\\s*"))
-                .map(String::trim)
-                .map(DataUtils::getNetworkCapabilityFromString)
-                .collect(Collectors.toSet());
-    }
-
-    /**
-     * Convert a network capability to string.
-     *
-     * This is for debugging and logging purposes only.
-     *
-     * @param netCap Network capability.
-     * @return Network capability in string format.
-     */
-    public static @NonNull String networkCapabilityToString(@NetCapability int netCap) {
-        switch (netCap) {
-            case NetworkCapabilities.NET_CAPABILITY_MMS:                  return "MMS";
-            case NetworkCapabilities.NET_CAPABILITY_SUPL:                 return "SUPL";
-            case NetworkCapabilities.NET_CAPABILITY_DUN:                  return "DUN";
-            case NetworkCapabilities.NET_CAPABILITY_FOTA:                 return "FOTA";
-            case NetworkCapabilities.NET_CAPABILITY_IMS:                  return "IMS";
-            case NetworkCapabilities.NET_CAPABILITY_CBS:                  return "CBS";
-            case NetworkCapabilities.NET_CAPABILITY_WIFI_P2P:             return "WIFI_P2P";
-            case NetworkCapabilities.NET_CAPABILITY_IA:                   return "IA";
-            case NetworkCapabilities.NET_CAPABILITY_RCS:                  return "RCS";
-            case NetworkCapabilities.NET_CAPABILITY_XCAP:                 return "XCAP";
-            case NetworkCapabilities.NET_CAPABILITY_EIMS:                 return "EIMS";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_METERED:          return "NOT_METERED";
-            case NetworkCapabilities.NET_CAPABILITY_INTERNET:             return "INTERNET";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED:       return "NOT_RESTRICTED";
-            case NetworkCapabilities.NET_CAPABILITY_TRUSTED:              return "TRUSTED";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_VPN:              return "NOT_VPN";
-            case NetworkCapabilities.NET_CAPABILITY_VALIDATED:            return "VALIDATED";
-            case NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL:       return "CAPTIVE_PORTAL";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING:          return "NOT_ROAMING";
-            case NetworkCapabilities.NET_CAPABILITY_FOREGROUND:           return "FOREGROUND";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED:        return "NOT_CONGESTED";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED:        return "NOT_SUSPENDED";
-            case NetworkCapabilities.NET_CAPABILITY_OEM_PAID:             return "OEM_PAID";
-            case NetworkCapabilities.NET_CAPABILITY_MCX:                  return "MCX";
-            case NetworkCapabilities.NET_CAPABILITY_PARTIAL_CONNECTIVITY:
-                return "PARTIAL_CONNECTIVITY";
-            case NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED:
-                return "TEMPORARILY_NOT_METERED";
-            case NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE:          return "OEM_PRIVATE";
-            case NetworkCapabilities.NET_CAPABILITY_VEHICLE_INTERNAL:     return "VEHICLE_INTERNAL";
-            case NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED:      return "NOT_VCN_MANAGED";
-            case NetworkCapabilities.NET_CAPABILITY_ENTERPRISE:           return "ENTERPRISE";
-            case NetworkCapabilities.NET_CAPABILITY_VSIM:                 return "VSIM";
-            case NetworkCapabilities.NET_CAPABILITY_BIP:                  return "BIP";
-            case NetworkCapabilities.NET_CAPABILITY_HEAD_UNIT:            return "HEAD_UNIT";
-            case NetworkCapabilities.NET_CAPABILITY_MMTEL:                return "MMTEL";
-            case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY:
-                return "PRIORITIZE_LATENCY";
-            case NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH:
-                return "PRIORITIZE_BANDWIDTH";
-            default:
-                return "Unknown(" + netCap + ")";
-        }
-    }
-
-    /**
-     * Convert network capabilities to string.
-     *
-     * This is for debugging and logging purposes only.
-     *
-     * @param netCaps Network capabilities.
-     * @return Network capabilities in string format.
-     */
-    public static @NonNull String networkCapabilitiesToString(
-            @NetCapability @Nullable Collection<Integer> netCaps) {
-        if (netCaps == null || netCaps.isEmpty()) return "";
-        return "[" + netCaps.stream()
-                .map(DataUtils::networkCapabilityToString)
-                .collect(Collectors.joining("|")) + "]";
-    }
-
-    /**
-     * Convert network capabilities to string.
-     *
-     * This is for debugging and logging purposes only.
-     *
-     * @param netCaps Network capabilities.
-     * @return Network capabilities in string format.
-     */
-    public static @NonNull String networkCapabilitiesToString(@NetCapability int[] netCaps) {
-        if (netCaps == null) return "";
-        return "[" + Arrays.stream(netCaps)
-                .mapToObj(DataUtils::networkCapabilityToString)
-                .collect(Collectors.joining("|")) + "]";
-    }
-
-    /**
-     * Convert the validation status to string.
-     *
-     * @param status The validation status.
-     * @return The validation status in string format.
-     */
-    public static @NonNull String validationStatusToString(@ValidationStatus int status) {
-        switch (status) {
-            case NetworkAgent.VALIDATION_STATUS_VALID: return "VALID";
-            case NetworkAgent.VALIDATION_STATUS_NOT_VALID: return "INVALID";
-            default: return "UNKNOWN(" + status + ")";
-        }
-    }
-
-    /**
-     * Convert network capability into APN type.
-     *
-     * @param networkCapability Network capability.
-     * @return APN type.
-     */
-    public static @ApnType int networkCapabilityToApnType(@NetCapability int networkCapability) {
-        switch (networkCapability) {
-            case NetworkCapabilities.NET_CAPABILITY_MMS:
-                return ApnSetting.TYPE_MMS;
-            case NetworkCapabilities.NET_CAPABILITY_SUPL:
-                return ApnSetting.TYPE_SUPL;
-            case NetworkCapabilities.NET_CAPABILITY_DUN:
-                return ApnSetting.TYPE_DUN;
-            case NetworkCapabilities.NET_CAPABILITY_FOTA:
-                return ApnSetting.TYPE_FOTA;
-            case NetworkCapabilities.NET_CAPABILITY_IMS:
-                return ApnSetting.TYPE_IMS;
-            case NetworkCapabilities.NET_CAPABILITY_CBS:
-                return ApnSetting.TYPE_CBS;
-            case NetworkCapabilities.NET_CAPABILITY_XCAP:
-                return ApnSetting.TYPE_XCAP;
-            case NetworkCapabilities.NET_CAPABILITY_EIMS:
-                return ApnSetting.TYPE_EMERGENCY;
-            case NetworkCapabilities.NET_CAPABILITY_INTERNET:
-                return ApnSetting.TYPE_DEFAULT;
-            case NetworkCapabilities.NET_CAPABILITY_MCX:
-                return ApnSetting.TYPE_MCX;
-            case NetworkCapabilities.NET_CAPABILITY_IA:
-                return ApnSetting.TYPE_IA;
-            case NetworkCapabilities.NET_CAPABILITY_ENTERPRISE:
-                return ApnSetting.TYPE_ENTERPRISE;
-            case NetworkCapabilities.NET_CAPABILITY_VSIM:
-                return ApnSetting.TYPE_VSIM;
-            case NetworkCapabilities.NET_CAPABILITY_BIP:
-                return ApnSetting.TYPE_BIP;
-            default:
-                return ApnSetting.TYPE_NONE;
-        }
-    }
-
-    /**
-     * Convert APN type to capability.
-     *
-     * @param apnType APN type.
-     * @return Network capability.
-     */
-    public static @NetCapability int apnTypeToNetworkCapability(@ApnType int apnType) {
-        switch (apnType) {
-            case ApnSetting.TYPE_MMS:
-                return NetworkCapabilities.NET_CAPABILITY_MMS;
-            case ApnSetting.TYPE_SUPL:
-                return NetworkCapabilities.NET_CAPABILITY_SUPL;
-            case ApnSetting.TYPE_DUN:
-                return NetworkCapabilities.NET_CAPABILITY_DUN;
-            case ApnSetting.TYPE_FOTA:
-                return NetworkCapabilities.NET_CAPABILITY_FOTA;
-            case ApnSetting.TYPE_IMS:
-                return NetworkCapabilities.NET_CAPABILITY_IMS;
-            case ApnSetting.TYPE_CBS:
-                return NetworkCapabilities.NET_CAPABILITY_CBS;
-            case ApnSetting.TYPE_XCAP:
-                return NetworkCapabilities.NET_CAPABILITY_XCAP;
-            case ApnSetting.TYPE_EMERGENCY:
-                return NetworkCapabilities.NET_CAPABILITY_EIMS;
-            case ApnSetting.TYPE_DEFAULT:
-                return NetworkCapabilities.NET_CAPABILITY_INTERNET;
-            case ApnSetting.TYPE_MCX:
-                return NetworkCapabilities.NET_CAPABILITY_MCX;
-            case ApnSetting.TYPE_IA:
-                return NetworkCapabilities.NET_CAPABILITY_IA;
-            case ApnSetting.TYPE_BIP:
-                return NetworkCapabilities.NET_CAPABILITY_BIP;
-            case ApnSetting.TYPE_VSIM:
-                return NetworkCapabilities.NET_CAPABILITY_VSIM;
-            case ApnSetting.TYPE_ENTERPRISE:
-                return NetworkCapabilities.NET_CAPABILITY_ENTERPRISE;
-            default:
-                return -1;
-        }
-    }
-
-    /**
-     * Convert network type to access network type.
-     *
-     * @param networkType The network type.
-     * @return The access network type.
-     */
-    public static @RadioAccessNetworkType int networkTypeToAccessNetworkType(
-            @NetworkType int networkType) {
-        switch (networkType) {
-            case TelephonyManager.NETWORK_TYPE_GPRS:
-            case TelephonyManager.NETWORK_TYPE_EDGE:
-            case TelephonyManager.NETWORK_TYPE_GSM:
-                return AccessNetworkType.GERAN;
-            case TelephonyManager.NETWORK_TYPE_UMTS:
-            case TelephonyManager.NETWORK_TYPE_HSDPA:
-            case TelephonyManager.NETWORK_TYPE_HSPAP:
-            case TelephonyManager.NETWORK_TYPE_HSUPA:
-            case TelephonyManager.NETWORK_TYPE_HSPA:
-            case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
-                return AccessNetworkType.UTRAN;
-            case TelephonyManager.NETWORK_TYPE_CDMA:
-            case TelephonyManager.NETWORK_TYPE_EVDO_0:
-            case TelephonyManager.NETWORK_TYPE_EVDO_A:
-            case TelephonyManager.NETWORK_TYPE_EVDO_B:
-            case TelephonyManager.NETWORK_TYPE_1xRTT:
-            case TelephonyManager.NETWORK_TYPE_EHRPD:
-                return AccessNetworkType.CDMA2000;
-            case TelephonyManager.NETWORK_TYPE_LTE:
-            case TelephonyManager.NETWORK_TYPE_LTE_CA:
-                return AccessNetworkType.EUTRAN;
-            case TelephonyManager.NETWORK_TYPE_IWLAN:
-                return AccessNetworkType.IWLAN;
-            case TelephonyManager.NETWORK_TYPE_NR:
-                return AccessNetworkType.NGRAN;
-            default:
-                return AccessNetworkType.UNKNOWN;
-        }
-    }
-
-    /**
-     * Convert the elapsed time to the current time with readable time format.
-     *
-     * @param elapsedTime The elapsed time retrieved from {@link SystemClock#elapsedRealtime()}.
-     * @return The string format time.
-     */
-    public static @NonNull String elapsedTimeToString(@ElapsedRealtimeLong long elapsedTime) {
-        return (elapsedTime != 0) ? systemTimeToString(System.currentTimeMillis()
-                - SystemClock.elapsedRealtime() + elapsedTime) : "never";
-    }
-
-    /**
-     * Convert the system time to the human readable format.
-     *
-     * @param systemTime The system time retrieved from {@link System#currentTimeMillis()}.
-     * @return The string format time.
-     */
-    public static @NonNull String systemTimeToString(@CurrentTimeMillisLong long systemTime) {
-        return (systemTime != 0) ? TIME_FORMAT.format(systemTime) : "never";
-    }
-
-    /**
-     * Convert the IMS feature to string.
-     *
-     * @param imsFeature IMS feature.
-     * @return IMS feature in string format.
-     */
-    public static @NonNull String imsFeatureToString(@ImsFeature.FeatureType int imsFeature) {
-        switch (imsFeature) {
-            case ImsFeature.FEATURE_MMTEL: return "MMTEL";
-            case ImsFeature.FEATURE_RCS: return "RCS";
-            default:
-                return "Unknown(" + imsFeature + ")";
-        }
-    }
-
-    /**
-     * Get the highest priority supported network capability from the specified data profile.
-     *
-     * @param dataConfigManager The data config that contains network priority information.
-     * @param dataProfile The data profile
-     * @return The highest priority network capability. -1 if cannot find one.
-     */
-    public static @NetCapability int getHighestPriorityNetworkCapabilityFromDataProfile(
-            @NonNull DataConfigManager dataConfigManager, @NonNull DataProfile dataProfile) {
-        if (dataProfile.getApnSetting() == null
-                || dataProfile.getApnSetting().getApnTypes().isEmpty()) return -1;
-        return dataProfile.getApnSetting().getApnTypes().stream()
-                .map(DataUtils::apnTypeToNetworkCapability)
-                .sorted(Comparator.comparing(dataConfigManager::getNetworkCapabilityPriority)
-                        .reversed())
-                .collect(Collectors.toList())
-                .get(0);
-    }
-
-    /**
-     * Group the network requests into several list that contains the same network capabilities.
-     *
-     * @param networkRequestList The provided network requests.
-     * @return The network requests after grouping.
-     */
-    public static @NonNull List<NetworkRequestList> getGroupedNetworkRequestList(
-            @NonNull NetworkRequestList networkRequestList) {
-        // Key is the capabilities set.
-        Map<Set<Integer>, NetworkRequestList> requestsMap = new ArrayMap<>();
-        for (TelephonyNetworkRequest networkRequest : networkRequestList) {
-            requestsMap.computeIfAbsent(Arrays.stream(networkRequest.getCapabilities())
-                            .boxed().collect(Collectors.toSet()),
-                    v -> new NetworkRequestList()).add(networkRequest);
-        }
-        // Sort the list, so the network request list contains higher priority will be in the front
-        // of the list.
-        return new ArrayList<>(requestsMap.values()).stream()
-                .sorted((list1, list2) -> Integer.compare(
-                        list2.get(0).getPriority(), list1.get(0).getPriority()))
-                .collect(Collectors.toList());
-    }
-
-    /**
-     * Get the target transport from source transport. This is only used for handover between
-     * IWLAN and cellular scenario.
-     *
-     * @param sourceTransport The source transport.
-     * @return The target transport.
-     */
-    public static @TransportType int getTargetTransport(@TransportType int sourceTransport) {
-        return sourceTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
-                ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
-                : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
-    }
-
-    /**
-     * Get the source transport from target transport. This is only used for handover between
-     * IWLAN and cellular scenario.
-     *
-     * @param targetTransport The target transport.
-     * @return The source transport.
-     */
-    public static @TransportType int getSourceTransport(@TransportType int targetTransport) {
-        return targetTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
-                ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
-                : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
-    }
-
-    /**
-     * Convert link status to string.
-     *
-     * @param linkStatus The link status.
-     * @return The link status in string format.
-     */
-    public static @NonNull String linkStatusToString(@LinkStatus int linkStatus) {
-        switch (linkStatus) {
-            case DataCallResponse.LINK_STATUS_UNKNOWN: return "UNKNOWN";
-            case DataCallResponse.LINK_STATUS_INACTIVE: return "INACTIVE";
-            case DataCallResponse.LINK_STATUS_ACTIVE: return "ACTIVE";
-            case DataCallResponse.LINK_STATUS_DORMANT: return "DORMANT";
-            default: return "UNKNOWN(" + linkStatus + ")";
-        }
-    }
-
-    /**
-     * Check if access network type is valid.
-     *
-     * @param accessNetworkType The access network type to check.
-     * @return {@code true} if the access network type is valid.
-     */
-    public static boolean isValidAccessNetwork(@RadioAccessNetworkType int accessNetworkType) {
-        switch (accessNetworkType) {
-            case AccessNetworkType.GERAN:
-            case AccessNetworkType.UTRAN:
-            case AccessNetworkType.EUTRAN:
-            case AccessNetworkType.CDMA2000:
-            case AccessNetworkType.IWLAN:
-            case AccessNetworkType.NGRAN:
-                return true;
-            default:
-                return false;
-        }
-    }
-
-    /**
-     * Convert data activity to string.
-     *
-     * @param dataActivity The data activity.
-     * @return The data activity in string format.
-     */
-    public static @NonNull String dataActivityToString(@DataActivityType int dataActivity) {
-        switch (dataActivity) {
-            case TelephonyManager.DATA_ACTIVITY_NONE: return "NONE";
-            case TelephonyManager.DATA_ACTIVITY_IN: return "IN";
-            case TelephonyManager.DATA_ACTIVITY_OUT: return "OUT";
-            case TelephonyManager.DATA_ACTIVITY_INOUT: return "INOUT";
-            case TelephonyManager.DATA_ACTIVITY_DORMANT: return "DORMANT";
-            default: return "UNKNOWN(" + dataActivity + ")";
-        }
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/KeepaliveTracker.java b/src/java/com/android/internal/telephony/data/KeepaliveTracker.java
deleted file mode 100644
index f9139ec..0000000
--- a/src/java/com/android/internal/telephony/data/KeepaliveTracker.java
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.NonNull;
-import android.net.KeepalivePacketData;
-import android.net.NattKeepalivePacketData;
-import android.net.SocketKeepalive;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.telephony.AccessNetworkConstants;
-import android.util.SparseArray;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.data.KeepaliveStatus.KeepaliveStatusCode;
-import com.android.internal.telephony.data.TelephonyNetworkAgent.TelephonyNetworkAgentCallback;
-import com.android.telephony.Rlog;
-
-import java.time.Duration;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Keepalive tracker tracks the active keepalive requests from the connectivity service, forwards
- * it to the modem, and handles keepalive status update from the modem.
- */
-public class KeepaliveTracker extends Handler {
-    /** Event for keepalive session started. */
-    private static final int EVENT_KEEPALIVE_STARTED = 1;
-
-    /** Event for keepalive session stopped. */
-    private static final int EVENT_KEEPALIVE_STOPPED = 2;
-
-    /** Event for keepalive status updated from the modem. */
-    private static final int EVENT_KEEPALIVE_STATUS = 3;
-
-    /** Event for registering keepalive status. */
-    private static final int EVENT_REGISTER_FOR_KEEPALIVE_STATUS = 4;
-
-    /** Event for unregistering keepalive status. */
-    private static final int EVENT_UNREGISTER_FOR_KEEPALIVE_STATUS = 5;
-
-    /** The phone instance. */
-    private final @NonNull Phone mPhone;
-
-    /** The parent data network. */
-    private final @NonNull DataNetwork mDataNetwork;
-
-    /** The associated network agent. */
-    private final @NonNull TelephonyNetworkAgent mNetworkAgent;
-
-    /** The log tag. */
-    private final @NonNull String mLogTag;
-
-    /** The keepalive records. */
-    private final @NonNull SparseArray<KeepaliveRecord> mKeepalives = new SparseArray<>();
-
-    /**
-     * Keepalive session record
-     */
-    private static class KeepaliveRecord {
-        /** Associated SIM slot index. */
-        public int slotIndex;
-
-        /** The current status. */
-        public @KeepaliveStatusCode int currentStatus;
-
-        /**
-         * Constructor
-         *
-         * @param slotIndex The associated SIM slot index.
-         * @param status The keepalive status.
-         */
-        KeepaliveRecord(int slotIndex, @KeepaliveStatusCode int status) {
-            this.slotIndex = slotIndex;
-            this.currentStatus = status;
-        }
-    }
-
-    /**
-     * Constructor
-     *
-     * @param phone The phone instance.
-     * @param looper The looper to be used by the handler. Currently the handler thread is the
-     * phone process's main thread.
-     * @param dataNetwork The parent data network.
-     * @param networkAgent The associated network agent.
-     */
-    public KeepaliveTracker(@NonNull Phone phone, @NonNull Looper looper,
-            @NonNull DataNetwork dataNetwork, @NonNull TelephonyNetworkAgent networkAgent) {
-        super(looper);
-        mPhone = phone;
-        mDataNetwork = dataNetwork;
-        mNetworkAgent = networkAgent;
-        mLogTag = "KT-" + networkAgent.getId();
-        mNetworkAgent.registerCallback(new TelephonyNetworkAgentCallback(this::post) {
-            @Override
-            public void onStartSocketKeepalive(int slot, @NonNull Duration interval,
-                    @NonNull KeepalivePacketData packet) {
-                onStartSocketKeepaliveRequested(slot, interval, packet);
-            }
-
-            @Override
-            public void onStopSocketKeepalive(int slot) {
-                onStopSocketKeepaliveRequested(slot);
-            }
-        });
-    }
-
-    @Override
-    public void handleMessage(@NonNull Message msg) {
-        AsyncResult ar;
-        KeepaliveStatus ks;
-        int slotIndex;
-        switch (msg.what) {
-            case EVENT_KEEPALIVE_STARTED:
-                ar = (AsyncResult) msg.obj;
-                slotIndex = msg.arg1;
-                if (ar.exception != null || ar.result == null) {
-                    loge("EVENT_KEEPALIVE_STARTED: error starting keepalive, e="
-                            + ar.exception);
-                    mNetworkAgent.sendSocketKeepaliveEvent(
-                            slotIndex, SocketKeepalive.ERROR_HARDWARE_ERROR);
-                    break;
-                }
-                ks = (KeepaliveStatus) ar.result;
-                onSocketKeepaliveStarted(slotIndex, ks);
-                break;
-            case EVENT_KEEPALIVE_STOPPED:
-                ar = (AsyncResult) msg.obj;
-                final int handle = msg.arg1;
-
-                if (ar.exception != null) {
-                    loge("EVENT_KEEPALIVE_STOPPED: error stopping keepalive for handle="
-                            + handle + " e=" + ar.exception);
-                    onKeepaliveStatus(new KeepaliveStatus(
-                            KeepaliveStatus.ERROR_UNKNOWN));
-                } else {
-                    log("Keepalive Stop Requested for handle=" + handle);
-                    onKeepaliveStatus(new KeepaliveStatus(
-                            handle, KeepaliveStatus.STATUS_INACTIVE));
-                }
-                break;
-            case EVENT_KEEPALIVE_STATUS:
-                ar = (AsyncResult) msg.obj;
-                if (ar.exception != null) {
-                    loge("EVENT_KEEPALIVE_STATUS: error in keepalive, e=" + ar.exception);
-                    // We have no way to notify connectivity in this case.
-                } else if (ar.result != null) {
-                    ks = (KeepaliveStatus) ar.result;
-                    onKeepaliveStatus(ks);
-                }
-                break;
-            case EVENT_REGISTER_FOR_KEEPALIVE_STATUS:
-                mPhone.mCi.registerForNattKeepaliveStatus(this, EVENT_KEEPALIVE_STATUS, null);
-                break;
-            case EVENT_UNREGISTER_FOR_KEEPALIVE_STATUS:
-                mPhone.mCi.unregisterForNattKeepaliveStatus(this);
-                break;
-            default:
-                loge("Unexpected message " + msg);
-        }
-    }
-
-    /**
-     * Called when connectivity service requests that the network hardware send the specified
-     * packet at the specified interval.
-     *
-     * @param slotIndex the hardware slot on which to start the keepalive.
-     * @param interval the interval between packets, between 10 and 3600. Note that this API
-     * does not support sub-second precision and will round off the request.
-     * @param packet the packet to send.
-     */
-    private void onStartSocketKeepaliveRequested(int slotIndex, @NonNull Duration interval,
-            @NonNull KeepalivePacketData packet) {
-        log("onStartSocketKeepaliveRequested: slot=" + slotIndex + ", interval="
-                + interval.getSeconds() + "s, packet=" + packet);
-        if (packet instanceof NattKeepalivePacketData) {
-            if (mDataNetwork.getTransport() == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
-                mPhone.mCi.startNattKeepalive(mDataNetwork.getId(), packet,
-                        (int) TimeUnit.SECONDS.toMillis(interval.getSeconds()),
-                        obtainMessage(EVENT_KEEPALIVE_STARTED, slotIndex, 0, null));
-            } else {
-                // We currently do not support NATT Keepalive requests using the
-                // DataService API, so unless the request is WWAN (always bound via
-                // the CommandsInterface), the request cannot be honored.
-                //
-                // TODO: b/72331356 to add support for Keepalive to the DataService
-                // so that keepalive requests can be handled (if supported) by the
-                // underlying transport.
-                mNetworkAgent.sendSocketKeepaliveEvent(
-                        slotIndex, SocketKeepalive.ERROR_INVALID_NETWORK);
-            }
-        } else {
-            mNetworkAgent.sendSocketKeepaliveEvent(slotIndex, SocketKeepalive.ERROR_UNSUPPORTED);
-        }
-    }
-
-    /**
-     * Called when connectivity service requests that the network hardware stop a previously-started
-     * keepalive.
-     *
-     * @param slotIndex the hardware slot on which to stop the keepalive.
-     */
-    private void onStopSocketKeepaliveRequested(int slotIndex) {
-        log("onStopSocketKeepaliveRequested: slot=" + slotIndex);
-        int handle = getHandleForSlot(slotIndex);
-        if (handle < 0) {
-            loge("No slot found for stopSocketKeepalive! " + slotIndex);
-            mNetworkAgent.sendSocketKeepaliveEvent(
-                    slotIndex, SocketKeepalive.ERROR_NO_SUCH_SLOT);
-            return;
-        }
-
-        log("Stopping keepalive with handle: " + handle);
-        mPhone.mCi.stopNattKeepalive(handle, obtainMessage(EVENT_KEEPALIVE_STOPPED, handle,
-                slotIndex, null));
-    }
-
-    /**
-     * Get the keepalive handle for the slot.
-     *
-     * @param slotIndex The associated SIM slot index.
-     *
-     * @return The keepalive handle.
-     */
-    private int getHandleForSlot(int slotIndex) {
-        for (int i = 0; i < mKeepalives.size(); i++) {
-            KeepaliveRecord kr = mKeepalives.valueAt(i);
-            if (kr.slotIndex == slotIndex) return mKeepalives.keyAt(i);
-        }
-        return -1;
-    }
-
-    /**
-     * Convert the error code.
-     *
-     * @param error The keepalive status error.
-     * @return The socket alive error.
-     */
-    private int keepaliveStatusErrorToPacketKeepaliveError(int error) {
-        switch(error) {
-            case KeepaliveStatus.ERROR_NONE:
-                return SocketKeepalive.SUCCESS;
-            case KeepaliveStatus.ERROR_UNSUPPORTED:
-                return SocketKeepalive.ERROR_UNSUPPORTED;
-            case KeepaliveStatus.ERROR_NO_RESOURCES:
-                return SocketKeepalive.ERROR_INSUFFICIENT_RESOURCES;
-            case KeepaliveStatus.ERROR_UNKNOWN:
-            default:
-                return SocketKeepalive.ERROR_HARDWARE_ERROR;
-        }
-    }
-
-    /**
-     * Called when keepalive session started.
-     *
-     * @param slotIndex The SIM slot index.
-     * @param ks Keepalive status.
-     */
-    private void onSocketKeepaliveStarted(int slotIndex, @NonNull KeepaliveStatus ks) {
-        log("onSocketKeepaliveStarted: slot=" + slotIndex + ", keepaliveStatus=" + ks);
-        switch (ks.statusCode) {
-            case KeepaliveStatus.STATUS_INACTIVE:
-                mNetworkAgent.sendSocketKeepaliveEvent(slotIndex,
-                        keepaliveStatusErrorToPacketKeepaliveError(ks.errorCode));
-                break;
-            case KeepaliveStatus.STATUS_ACTIVE:
-                mNetworkAgent.sendSocketKeepaliveEvent(slotIndex, SocketKeepalive.SUCCESS);
-                // fall through to add record
-            case KeepaliveStatus.STATUS_PENDING:
-                log("Adding keepalive handle=" + ks.sessionHandle + " slotIndex = " + slotIndex);
-                mKeepalives.put(ks.sessionHandle, new KeepaliveRecord(slotIndex, ks.statusCode));
-                break;
-            default:
-                log("Invalid KeepaliveStatus Code: " + ks.statusCode);
-                break;
-        }
-    }
-
-    /**
-     * Called when receiving keepalive status from the modem.
-     *
-     * @param ks Keepalive status.
-     */
-    private void onKeepaliveStatus(@NonNull KeepaliveStatus ks) {
-        log("onKeepaliveStatus: " + ks);
-        final KeepaliveRecord kr;
-        kr = mKeepalives.get(ks.sessionHandle);
-
-        if (kr == null) {
-            // If there is no slot for the session handle, we received an event
-            // for a different data connection. This is not an error because the
-            // keepalive session events are broadcast to all listeners.
-            loge("Discarding keepalive event for different data connection:" + ks);
-            return;
-        }
-        // Switch on the current state, to see what we do with the status update
-        switch (kr.currentStatus) {
-            case KeepaliveStatus.STATUS_INACTIVE:
-                log("Inactive Keepalive received status!");
-                mNetworkAgent.sendSocketKeepaliveEvent(
-                        kr.slotIndex, SocketKeepalive.ERROR_HARDWARE_ERROR);
-                break;
-            case KeepaliveStatus.STATUS_PENDING:
-                switch (ks.statusCode) {
-                    case KeepaliveStatus.STATUS_INACTIVE:
-                        mNetworkAgent.sendSocketKeepaliveEvent(kr.slotIndex,
-                                keepaliveStatusErrorToPacketKeepaliveError(ks.errorCode));
-                        kr.currentStatus = KeepaliveStatus.STATUS_INACTIVE;
-                        mKeepalives.remove(ks.sessionHandle);
-                        break;
-                    case KeepaliveStatus.STATUS_ACTIVE:
-                        log("Pending Keepalive received active status!");
-                        kr.currentStatus = KeepaliveStatus.STATUS_ACTIVE;
-                        mNetworkAgent.sendSocketKeepaliveEvent(
-                                kr.slotIndex, SocketKeepalive.SUCCESS);
-                        break;
-                    case KeepaliveStatus.STATUS_PENDING:
-                        loge("Invalid unsolicited Keepalive Pending Status!");
-                        break;
-                    default:
-                        loge("Invalid Keepalive Status received, " + ks.statusCode);
-                }
-                break;
-            case KeepaliveStatus.STATUS_ACTIVE:
-                switch (ks.statusCode) {
-                    case KeepaliveStatus.STATUS_INACTIVE:
-                        log("Keepalive received stopped status!");
-                        mNetworkAgent.sendSocketKeepaliveEvent(kr.slotIndex,
-                                SocketKeepalive.SUCCESS);
-
-                        kr.currentStatus = KeepaliveStatus.STATUS_INACTIVE;
-                        mKeepalives.remove(ks.sessionHandle);
-                        break;
-                    case KeepaliveStatus.STATUS_PENDING:
-                    case KeepaliveStatus.STATUS_ACTIVE:
-                        loge("Active Keepalive received invalid status!");
-                        break;
-                    default:
-                        loge("Invalid Keepalive Status received, " + ks.statusCode);
-                }
-                break;
-            default:
-                loge("Invalid Keepalive Status received, " + kr.currentStatus);
-        }
-    }
-
-    /**
-     * Register keepalive status update from the modem. Calling this multiple times won't result in
-     * multiple status update.
-     */
-    public void registerForKeepaliveStatus() {
-        sendEmptyMessage(EVENT_REGISTER_FOR_KEEPALIVE_STATUS);
-    }
-
-    /**
-     * Unregister keepalive status update from the modem.
-     */
-    public void unregisterForKeepaliveStatus() {
-        sendEmptyMessage(EVENT_UNREGISTER_FOR_KEEPALIVE_STATUS);
-    }
-
-    /**
-     * Log debug messages.
-     * @param s debug messages
-     */
-    private void log(@NonNull String s) {
-        Rlog.d(mLogTag, s);
-    }
-
-    /**
-     * Log error messages.
-     * @param s error messages
-     */
-    private void loge(@NonNull String s) {
-        Rlog.e(mLogTag, s);
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/NotifyQosSessionInterface.java b/src/java/com/android/internal/telephony/data/NotifyQosSessionInterface.java
deleted file mode 100644
index 554177a..0000000
--- a/src/java/com/android/internal/telephony/data/NotifyQosSessionInterface.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.NonNull;
-import android.net.NetworkAgent;
-import android.net.QosSessionAttributes;
-
-/**
- * The temporary interface that is shared by
- * {@link com.android.internal.telephony.dataconnection.DcNetworkAgent} and
- * {@link com.android.internal.telephony.data.TelephonyNetworkAgent} so they can both interact
- * with {@link QosCallbackTracker}.
- */
-// TODO: Remove after DcNetworkAgent is removed.
-public interface NotifyQosSessionInterface {
-    /**
-     * Sends the attributes of Qos Session back to the Application. This method is create for
-     * Mockito to mock since
-     * {@link NetworkAgent#sendQosSessionAvailable(int, int, QosSessionAttributes)} is
-     * {@code final} that can't be mocked.
-     *
-     * @param qosCallbackId the callback id that the session belongs to.
-     * @param sessionId the unique session id across all Qos Sessions.
-     * @param attributes the attributes of the Qos Session.
-     */
-    void notifyQosSessionAvailable(int qosCallbackId, int sessionId,
-            @NonNull QosSessionAttributes attributes);
-
-    /**
-     * Sends event that the Qos Session was lost. This method is create for Mockito to mock
-     * since {@link NetworkAgent#sendQosSessionLost(int, int, int)} is {@code final} that can't be
-     * mocked..
-     *
-     * @param qosCallbackId the callback id that the session belongs to.
-     * @param sessionId the unique session id across all Qos Sessions.
-     * @param qosSessionType the session type {@code QosSession#QosSessionType}.
-     */
-    void notifyQosSessionLost(int qosCallbackId, int sessionId, int qosSessionType);
-}
diff --git a/src/java/com/android/internal/telephony/data/QosCallbackTracker.java b/src/java/com/android/internal/telephony/data/QosCallbackTracker.java
deleted file mode 100644
index b7cecbd..0000000
--- a/src/java/com/android/internal/telephony/data/QosCallbackTracker.java
+++ /dev/null
@@ -1,487 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.LinkAddress;
-import android.net.NetworkAgent;
-import android.net.QosFilter;
-import android.net.QosSession;
-import android.os.Handler;
-import android.telephony.TelephonyManager;
-import android.telephony.data.EpsBearerQosSessionAttributes;
-import android.telephony.data.EpsQos;
-import android.telephony.data.NrQos;
-import android.telephony.data.NrQosSessionAttributes;
-import android.telephony.data.QosBearerFilter;
-import android.telephony.data.QosBearerSession;
-
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.metrics.RcsStats;
-import com.android.telephony.Rlog;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Matches filters with qos sessions and send corresponding available and lost events.
- */
-public class QosCallbackTracker extends Handler {
-    private static final int DEDICATED_BEARER_EVENT_STATE_NONE = 0;
-    private static final int DEDICATED_BEARER_EVENT_STATE_ADDED = 1;
-    private static final int DEDICATED_BEARER_EVENT_STATE_MODIFIED = 2;
-    private static final int DEDICATED_BEARER_EVENT_STATE_DELETED = 3;
-
-    private final @NonNull String mLogTag;
-    // TODO: Change this to TelephonyNetworkAgent
-    private final @NonNull NotifyQosSessionInterface mNetworkAgent;
-    private final @NonNull Map<Integer, QosBearerSession> mQosBearerSessions;
-    private final @NonNull RcsStats mRcsStats;
-
-    // We perform an exact match on the address
-    private final @NonNull Map<Integer, IFilter> mCallbacksToFilter;
-
-    private final int mPhoneId;
-
-    /**
-     * QOS sessions filter interface
-     */
-    public interface IFilter {
-        /**
-         * Filter using the local address.
-         *
-         * @param address The local address.
-         * @param startPort Starting port.
-         * @param endPort Ending port.
-         * @return {@code true} if matches, {@code false} otherwise.
-         */
-        boolean matchesLocalAddress(InetAddress address, int startPort, int endPort);
-
-        /**
-         * Filter using the remote address.
-         *
-         * @param address The local address.
-         * @param startPort Starting port.
-         * @param endPort Ending port.
-         * @return {@code true} if matches, {@code false} otherwise.
-         */
-        boolean matchesRemoteAddress(InetAddress address, int startPort, int endPort);
-    }
-
-    /**
-     * Constructor
-     *
-     * @param networkAgent The network agent to send events to.
-     * @param phone The phone instance.
-     */
-    public QosCallbackTracker(@NonNull NotifyQosSessionInterface networkAgent,
-            @NonNull Phone phone) {
-        mQosBearerSessions = new HashMap<>();
-        mCallbacksToFilter = new HashMap<>();
-        mNetworkAgent = networkAgent;
-        mPhoneId = phone.getPhoneId();
-        mRcsStats = RcsStats.getInstance();
-        mLogTag = "QOSCT" + "-" + ((NetworkAgent) mNetworkAgent).getNetwork().getNetId();
-
-        if (phone.isUsingNewDataStack()) {
-            //TODO: Replace the NetworkAgent in the constructor with TelephonyNetworkAgent
-            //  after mPhone.isUsingNewDataStack() check is removed.
-            ((TelephonyNetworkAgent) networkAgent).registerCallback(
-                    new TelephonyNetworkAgent.TelephonyNetworkAgentCallback(this::post) {
-                        @Override
-                        public void onQosCallbackRegistered(int qosCallbackId,
-                                @NonNull QosFilter filter) {
-                            addFilter(qosCallbackId,
-                                    new QosCallbackTracker.IFilter() {
-                                        @Override
-                                        public boolean matchesLocalAddress(
-                                                @NonNull InetAddress address, int startPort,
-                                                int endPort) {
-                                            return filter.matchesLocalAddress(address, startPort,
-                                                    endPort);
-                                        }
-
-                                        @Override
-                                        public boolean matchesRemoteAddress(
-                                                @NonNull InetAddress address, int startPort,
-                                                int endPort) {
-                                            return filter.matchesRemoteAddress(address, startPort,
-                                                    endPort);
-                                        }
-                                    });
-                        }
-
-                        @Override
-                        public void onQosCallbackUnregistered(int qosCallbackId) {
-
-                        }
-                    });
-        }
-    }
-
-    /**
-     * Add new filter that is to receive events.
-     *
-     * @param callbackId the associated callback id.
-     * @param filter provides the matching logic.
-     */
-    public void addFilter(final int callbackId, final IFilter filter) {
-        post(() -> {
-            log("addFilter: callbackId=" + callbackId);
-            // Called from mDcNetworkAgent
-            mCallbacksToFilter.put(callbackId, filter);
-
-            //On first change. Check all sessions and send.
-            for (final QosBearerSession session : mQosBearerSessions.values()) {
-                if (doFiltersMatch(session, filter)) {
-                    sendSessionAvailable(callbackId, session, filter);
-
-                    notifyMetricDedicatedBearerListenerAdded(callbackId, session);
-                }
-            }
-        });
-    }
-
-    /**
-     * Remove the filter with the associated callback id.
-     *
-     * @param callbackId the qos callback id.
-     */
-    public void removeFilter(final int callbackId) {
-        post(() -> {
-            log("removeFilter: callbackId=" + callbackId);
-            mCallbacksToFilter.remove(callbackId);
-            notifyMetricDedicatedBearerListenerRemoved(callbackId);
-        });
-    }
-
-    /**
-     * Update the list of qos sessions and send out corresponding events
-     *
-     * @param sessions the new list of qos sessions
-     */
-    public void updateSessions(@NonNull final List<QosBearerSession> sessions) {
-        post(() -> {
-            log("updateSessions: sessions size=" + sessions.size());
-
-            int bearerState = DEDICATED_BEARER_EVENT_STATE_NONE;
-
-            final List<QosBearerSession> sessionsToAdd = new ArrayList<>();
-            final Map<Integer, QosBearerSession> incomingSessions = new HashMap<>();
-            final HashSet<Integer> sessionsReportedToMetric = new HashSet<>();
-            for (final QosBearerSession incomingSession : sessions) {
-                int sessionId = incomingSession.getQosBearerSessionId();
-                incomingSessions.put(sessionId, incomingSession);
-
-                final QosBearerSession existingSession = mQosBearerSessions.get(sessionId);
-                for (final int callbackId : mCallbacksToFilter.keySet()) {
-                    final IFilter filter = mCallbacksToFilter.get(callbackId);
-
-                    final boolean incomingSessionMatch = doFiltersMatch(incomingSession, filter);
-                    final boolean existingSessionMatch =
-                            existingSession != null && doFiltersMatch(existingSession, filter);
-
-                    if (!existingSessionMatch && incomingSessionMatch) {
-                        // The filter matches now and didn't match earlier
-                        sendSessionAvailable(callbackId, incomingSession, filter);
-
-                        bearerState = DEDICATED_BEARER_EVENT_STATE_ADDED;
-                    }
-
-                    if (existingSessionMatch && incomingSessionMatch) {
-                        // The same sessions matches the same filter, but if the qos changed,
-                        // the callback still needs to be notified
-                        if (!incomingSession.getQos().equals(existingSession.getQos())) {
-                            sendSessionAvailable(callbackId, incomingSession, filter);
-                            bearerState = DEDICATED_BEARER_EVENT_STATE_MODIFIED;
-                        }
-                    }
-
-                    // this QosBearerSession has registered QosCallbackId
-                    if (!sessionsReportedToMetric.contains(sessionId) && incomingSessionMatch) {
-                        // this session has listener
-                        notifyMetricDedicatedBearerEvent(incomingSession, bearerState, true);
-                        sessionsReportedToMetric.add(sessionId);
-                    }
-                }
-
-                // this QosBearerSession does not have registered QosCallbackId
-                if (!sessionsReportedToMetric.contains(sessionId)) {
-                    // no listener is registered to this session
-                    bearerState = DEDICATED_BEARER_EVENT_STATE_ADDED;
-                    notifyMetricDedicatedBearerEvent(incomingSession, bearerState, false);
-                    sessionsReportedToMetric.add(sessionId);
-                }
-                sessionsToAdd.add(incomingSession);
-            }
-
-            final List<Integer> sessionsToRemove = new ArrayList<>();
-            sessionsReportedToMetric.clear();
-            bearerState = DEDICATED_BEARER_EVENT_STATE_DELETED;
-            // Find sessions that no longer exist
-            for (final QosBearerSession existingSession : mQosBearerSessions.values()) {
-                final int sessionId = existingSession.getQosBearerSessionId();
-                if (!incomingSessions.containsKey(sessionId)) {
-                    for (final int callbackId : mCallbacksToFilter.keySet()) {
-                        final IFilter filter = mCallbacksToFilter.get(callbackId);
-                        // The filter matches which means it was previously available, and now is
-                        // lost
-                        if (doFiltersMatch(existingSession, filter)) {
-                            bearerState = DEDICATED_BEARER_EVENT_STATE_DELETED;
-                            sendSessionLost(callbackId, existingSession);
-                            notifyMetricDedicatedBearerEvent(existingSession, bearerState, true);
-                            sessionsReportedToMetric.add(sessionId);
-                        }
-                    }
-                    sessionsToRemove.add(sessionId);
-                    if (!sessionsReportedToMetric.contains(sessionId)) {
-                        notifyMetricDedicatedBearerEvent(existingSession, bearerState, false);
-                        sessionsReportedToMetric.add(sessionId);
-                    }
-                }
-            }
-
-            // Add in the new or existing sessions with updated information
-            for (final QosBearerSession sessionToAdd : sessionsToAdd) {
-                mQosBearerSessions.put(sessionToAdd.getQosBearerSessionId(), sessionToAdd);
-            }
-
-            // Remove any old sessions
-            for (final int sessionToRemove : sessionsToRemove) {
-                mQosBearerSessions.remove(sessionToRemove);
-            }
-        });
-    }
-
-    private boolean doFiltersMatch(final @NonNull QosBearerSession qosBearerSession,
-            final @NonNull IFilter filter) {
-        return getMatchingQosBearerFilter(qosBearerSession, filter) != null;
-    }
-
-    private boolean matchesByLocalAddress(final @NonNull QosBearerFilter sessionFilter,
-            final @NonNull IFilter filter) {
-        if (sessionFilter.getLocalPortRange() == null) return false;
-        for (final LinkAddress qosAddress : sessionFilter.getLocalAddresses()) {
-            return filter.matchesLocalAddress(qosAddress.getAddress(),
-                    sessionFilter.getLocalPortRange().getStart(),
-                    sessionFilter.getLocalPortRange().getEnd());
-        }
-        return false;
-    }
-
-    private boolean matchesByRemoteAddress(@NonNull QosBearerFilter sessionFilter,
-            final @NonNull IFilter filter) {
-        if (sessionFilter.getRemotePortRange() == null) return false;
-        for (final LinkAddress qosAddress : sessionFilter.getRemoteAddresses()) {
-            return filter.matchesRemoteAddress(qosAddress.getAddress(),
-                    sessionFilter.getRemotePortRange().getStart(),
-                    sessionFilter.getRemotePortRange().getEnd());
-        }
-        return false;
-    }
-
-    private boolean matchesByRemoteAndLocalAddress(@NonNull QosBearerFilter sessionFilter,
-            final @NonNull IFilter filter) {
-        if (sessionFilter.getLocalPortRange() == null
-                || sessionFilter.getRemotePortRange() == null) return false;
-        for (final LinkAddress remoteAddress : sessionFilter.getRemoteAddresses()) {
-            for (final LinkAddress localAddress : sessionFilter.getLocalAddresses()) {
-                return filter.matchesRemoteAddress(remoteAddress.getAddress(),
-                        sessionFilter.getRemotePortRange().getStart(),
-                        sessionFilter.getRemotePortRange().getEnd())
-                        && filter.matchesLocalAddress(localAddress.getAddress(),
-                              sessionFilter.getLocalPortRange().getStart(),
-                              sessionFilter.getLocalPortRange().getEnd());
-            }
-        }
-        return false;
-    }
-
-    private QosBearerFilter getFilterByPrecedence(
-            @Nullable QosBearerFilter qosFilter, QosBearerFilter sessionFilter) {
-        // Find for the highest precedence filter, lower the value is the higher the precedence
-        return qosFilter == null || sessionFilter.getPrecedence() < qosFilter.getPrecedence()
-                ? sessionFilter : qosFilter;
-    }
-
-    private @Nullable QosBearerFilter getMatchingQosBearerFilter(
-            @NonNull QosBearerSession qosBearerSession, final @NonNull IFilter filter) {
-        QosBearerFilter qosFilter = null;
-
-        for (final QosBearerFilter sessionFilter : qosBearerSession.getQosBearerFilterList()) {
-            if (!sessionFilter.getLocalAddresses().isEmpty()
-                    && !sessionFilter.getRemoteAddresses().isEmpty()
-                    && sessionFilter.getLocalPortRange() != null
-                    && sessionFilter.getLocalPortRange().isValid()
-                    && sessionFilter.getRemotePortRange() != null
-                    && sessionFilter.getRemotePortRange().isValid()) {
-                if (matchesByRemoteAndLocalAddress(sessionFilter, filter)) {
-                    qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
-                }
-            } else if (!sessionFilter.getRemoteAddresses().isEmpty()
-                    && sessionFilter.getRemotePortRange() != null
-                    && sessionFilter.getRemotePortRange().isValid()) {
-                if (matchesByRemoteAddress(sessionFilter, filter)) {
-                    qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
-                }
-            } else if (!sessionFilter.getLocalAddresses().isEmpty()
-                    && sessionFilter.getLocalPortRange() != null
-                    && sessionFilter.getLocalPortRange().isValid()) {
-                if (matchesByLocalAddress(sessionFilter, filter)) {
-                    qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
-                }
-            }
-        }
-        return qosFilter;
-    }
-
-    private void sendSessionAvailable(final int callbackId, final @NonNull QosBearerSession session,
-            @NonNull IFilter filter) {
-        QosBearerFilter qosBearerFilter = getMatchingQosBearerFilter(session, filter);
-        List<InetSocketAddress> remoteAddresses = new ArrayList<>();
-        if (qosBearerFilter.getRemoteAddresses().size() > 0
-                && qosBearerFilter.getRemotePortRange() != null) {
-            remoteAddresses.add(
-                    new InetSocketAddress(qosBearerFilter.getRemoteAddresses().get(0).getAddress(),
-                            qosBearerFilter.getRemotePortRange().getStart()));
-        }
-
-        if (session.getQos() instanceof EpsQos) {
-            EpsQos qos = (EpsQos) session.getQos();
-            EpsBearerQosSessionAttributes epsBearerAttr =
-                    new EpsBearerQosSessionAttributes(qos.getQci(),
-                            qos.getUplinkBandwidth().getMaxBitrateKbps(),
-                            qos.getDownlinkBandwidth().getMaxBitrateKbps(),
-                            qos.getDownlinkBandwidth().getGuaranteedBitrateKbps(),
-                            qos.getUplinkBandwidth().getGuaranteedBitrateKbps(),
-                            remoteAddresses);
-            mNetworkAgent.notifyQosSessionAvailable(
-                    callbackId, session.getQosBearerSessionId(), epsBearerAttr);
-        } else {
-            NrQos qos = (NrQos) session.getQos();
-            NrQosSessionAttributes nrQosAttr =
-                    new NrQosSessionAttributes(qos.get5Qi(), qos.getQfi(),
-                            qos.getUplinkBandwidth().getMaxBitrateKbps(),
-                            qos.getDownlinkBandwidth().getMaxBitrateKbps(),
-                            qos.getDownlinkBandwidth().getGuaranteedBitrateKbps(),
-                            qos.getUplinkBandwidth().getGuaranteedBitrateKbps(),
-                            qos.getAveragingWindow(), remoteAddresses);
-            mNetworkAgent.notifyQosSessionAvailable(
-                    callbackId, session.getQosBearerSessionId(), nrQosAttr);
-        }
-
-        // added to notify to Metric for passing DedicatedBearerEstablished info
-        notifyMetricDedicatedBearerListenerBearerUpdateSession(callbackId, session);
-
-        log("sendSessionAvailable, callbackId=" + callbackId);
-    }
-
-    private void sendSessionLost(int callbackId, @NonNull QosBearerSession session) {
-        mNetworkAgent.notifyQosSessionLost(callbackId, session.getQosBearerSessionId(),
-                session.getQos() instanceof EpsQos
-                        ? QosSession.TYPE_EPS_BEARER : QosSession.TYPE_NR_BEARER);
-        log("sendSessionLost, callbackId=" + callbackId);
-    }
-
-    private void notifyMetricDedicatedBearerListenerAdded(final int callbackId,
-            final @NonNull QosBearerSession session) {
-
-        final int slotId = mPhoneId;
-        final int rat = getRatInfoFromSessionInfo(session);
-        final int qci = getQCIFromSessionInfo(session);
-
-        mRcsStats.onImsDedicatedBearerListenerAdded(callbackId, slotId, rat, qci);
-    }
-
-    private void notifyMetricDedicatedBearerListenerBearerUpdateSession(
-            final int callbackId, final @NonNull QosBearerSession session) {
-        mRcsStats.onImsDedicatedBearerListenerUpdateSession(callbackId, mPhoneId,
-                getRatInfoFromSessionInfo(session), getQCIFromSessionInfo(session), true);
-    }
-
-    private void notifyMetricDedicatedBearerListenerRemoved(final int callbackId) {
-        mRcsStats.onImsDedicatedBearerListenerRemoved(callbackId);
-    }
-
-    private int getQCIFromSessionInfo(final QosBearerSession session) {
-        if (session.getQos() instanceof EpsQos) {
-            return ((EpsQos) session.getQos()).getQci();
-        } else if (session.getQos() instanceof NrQos) {
-            return ((NrQos) session.getQos()).get5Qi();
-        }
-
-        return 0;
-    }
-
-    private int getRatInfoFromSessionInfo(final QosBearerSession session) {
-        if (session.getQos() instanceof EpsQos) {
-            return TelephonyManager.NETWORK_TYPE_LTE;
-        } else if (session.getQos() instanceof NrQos) {
-            return TelephonyManager.NETWORK_TYPE_NR;
-        }
-
-        return 0;
-    }
-
-    private boolean doesLocalConnectionInfoExist(final QosBearerSession qosBearerSession) {
-        for (final QosBearerFilter sessionFilter : qosBearerSession.getQosBearerFilterList()) {
-            if (!sessionFilter.getLocalAddresses().isEmpty()
-                    && sessionFilter.getLocalPortRange() != null
-                    && sessionFilter.getLocalPortRange().isValid()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private boolean doesRemoteConnectionInfoExist(final QosBearerSession qosBearerSession) {
-        for (final QosBearerFilter sessionFilter : qosBearerSession.getQosBearerFilterList()) {
-            if (!sessionFilter.getRemoteAddresses().isEmpty()
-                    && sessionFilter.getRemotePortRange() != null
-                    && sessionFilter.getRemotePortRange().isValid()) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private void notifyMetricDedicatedBearerEvent(final QosBearerSession session,
-            final int bearerState, final boolean hasListener) {
-        final int slotId = mPhoneId;
-        int ratAtEnd = getRatInfoFromSessionInfo(session);
-        int qci = getQCIFromSessionInfo(session);
-        boolean localConnectionInfoReceived = doesLocalConnectionInfoExist(session);
-        boolean remoteConnectionInfoReceived = doesRemoteConnectionInfoExist(session);
-
-        mRcsStats.onImsDedicatedBearerEvent(slotId, ratAtEnd, qci, bearerState,
-                localConnectionInfoReceived, remoteConnectionInfoReceived, hasListener);
-    }
-
-    /**
-     * Log debug messages.
-     * @param s debug messages
-     */
-    private void log(@NonNull String s) {
-        Rlog.d(mLogTag, s);
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkAgent.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkAgent.java
deleted file mode 100644
index 3b12562..0000000
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkAgent.java
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.CallbackExecutor;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.KeepalivePacketData;
-import android.net.NetworkAgent;
-import android.net.NetworkAgentConfig;
-import android.net.NetworkProvider;
-import android.net.NetworkScore;
-import android.net.QosFilter;
-import android.net.QosSessionAttributes;
-import android.net.Uri;
-import android.os.Looper;
-import android.util.ArraySet;
-import android.util.IndentingPrintWriter;
-import android.util.LocalLog;
-
-import com.android.internal.telephony.Phone;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.time.Duration;
-import java.util.Set;
-import java.util.concurrent.Executor;
-
-/**
- * TelephonyNetworkAgent class represents a single PDN (Packet Data Network). It is an agent
- * for telephony to propagate network related information to the connectivity service. It always
- * has an associated parent {@link DataNetwork}.
- */
-public class TelephonyNetworkAgent extends NetworkAgent implements NotifyQosSessionInterface {
-    private final String mLogTag;
-    private final Phone mPhone;
-    private final LocalLog mLocalLog = new LocalLog(128);
-
-    /** The parent data network. */
-    private final @NonNull DataNetwork mDataNetwork;
-
-    /** Network agent config. For unit test use only. */
-    private final @NonNull NetworkAgentConfig mNetworkAgentConfig;
-
-    /** This is the id from {@link NetworkAgent#register()}. */
-    private final int mId;
-
-    /**
-     * Indicates if this network agent is abandoned. if {@code true}, it ignores the
-     * @link NetworkAgent#onNetworkUnwanted()} calls from connectivity service.
-     */
-    private boolean mAbandoned = false;
-
-    /**
-     * The callbacks that are used to pass information to {@link DataNetwork} and
-     * {@link QosCallbackTracker}.
-     */
-    private final @NonNull Set<TelephonyNetworkAgentCallback> mTelephonyNetworkAgentCallbacks =
-            new ArraySet<>();
-
-    /**
-     * Telephony network agent callback. This should be only used by {@link DataNetwork}.
-     */
-    public abstract static class TelephonyNetworkAgentCallback extends DataCallback {
-        /**
-         * Constructor
-         *
-         * @param executor The executor of the callback.
-         */
-        public TelephonyNetworkAgentCallback(@NonNull @CallbackExecutor Executor executor) {
-            super(executor);
-        }
-
-        /**
-         * Called when the system determines the usefulness of this network.
-         *
-         * @param status one of {@link NetworkAgent#VALIDATION_STATUS_VALID} or
-         * {@link NetworkAgent#VALIDATION_STATUS_NOT_VALID}.
-         * @param redirectUri 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}.
-         *
-         * @see NetworkAgent#onValidationStatus(int, Uri)
-         */
-        public void onValidationStatus(@android.telephony.Annotation.ValidationStatus int status,
-                @Nullable Uri redirectUri) {}
-
-        /**
-         * Called when a qos callback is registered with a filter.
-         *
-         * @param qosCallbackId the id for the callback registered
-         * @param filter the filter being registered
-         */
-        public void onQosCallbackRegistered(int qosCallbackId, @NonNull QosFilter filter) {}
-
-        /**
-         * Called when a qos callback is registered with a filter.
-         *
-         * Any QoS events that are sent with the same callback id after this method is called are a
-         * no-op.
-         *
-         * @param qosCallbackId the id for the callback being unregistered.
-         */
-        public void onQosCallbackUnregistered(int qosCallbackId) {}
-
-        /**
-         * 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 interval the interval between packets, between 10 and 3600. Note that this API
-         *                 does not support sub-second precision and will round off the request.
-         * @param packet the packet to send.
-         */
-        public void onStartSocketKeepalive(int slot, @NonNull Duration interval,
-                @NonNull KeepalivePacketData packet) {}
-
-        /**
-         * 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) {}
-    }
-
-    /**
-     * Constructor
-     *
-     * @param phone The phone instance.
-     * @param looper The looper to be used by the handler. Currently the handler thread is the
-     * phone process's main thread.
-     * @param dataNetwork The data network which owns this network agent.
-     * @param score The initial score of the network.
-     * @param config The network agent config.
-     * @param provider The network provider.
-     */
-    public TelephonyNetworkAgent(@NonNull Phone phone, @NonNull Looper looper,
-            @NonNull DataNetwork dataNetwork, @NonNull NetworkScore score,
-            @NonNull NetworkAgentConfig config, @NonNull NetworkProvider provider,
-            @NonNull TelephonyNetworkAgentCallback callback) {
-        super(phone.getContext(), looper, "TelephonyNetworkAgent",
-                dataNetwork.getNetworkCapabilities(), dataNetwork.getLinkProperties(), score,
-                config, provider);
-        register();
-        mDataNetwork = dataNetwork;
-        mNetworkAgentConfig = config;
-        mTelephonyNetworkAgentCallbacks.add(callback);
-        mPhone = phone;
-        mId = getNetwork().getNetId();
-        mLogTag = "TNA-" + mId;
-
-        log("TelephonyNetworkAgent created, nc="
-                + dataNetwork.getNetworkCapabilities() + ", score=" + score);
-    }
-
-    /**
-     * Called when connectivity service has indicated they no longer want this network.
-     */
-    @Override
-    public void onNetworkUnwanted() {
-        if (mAbandoned) {
-            log("The agent is already abandoned. Ignored onNetworkUnwanted.");
-            return;
-        }
-
-        mDataNetwork.tearDown(DataNetwork.TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED);
-    }
-
-    /**
-     * @return The unique id of the agent.
-     */
-    public int getId() {
-        return mId;
-    }
-
-    /**
-     * Called when the system determines the usefulness of this network.
-     *
-     * @param status one of {@link NetworkAgent#VALIDATION_STATUS_VALID} or
-     * {@link NetworkAgent#VALIDATION_STATUS_NOT_VALID}.
-     * @param redirectUri 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}.
-     *
-     * @see NetworkAgent#onValidationStatus(int, Uri)
-     */
-    @Override
-    public void onValidationStatus(@android.telephony.Annotation.ValidationStatus int status,
-            @Nullable Uri redirectUri) {
-        if (mAbandoned) {
-            log("The agent is already abandoned. Ignored onValidationStatus.");
-            return;
-        }
-        mTelephonyNetworkAgentCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                () -> callback.onValidationStatus(status, redirectUri)));
-    }
-
-    /**
-     * Called when connectivity service request a bandwidth update.
-     */
-    @Override
-    public void onBandwidthUpdateRequested() {
-        // Drop the support for IRadio 1.0 and 1.1. On newer HAL, LCE should be reported from
-        // modem unsolicited.
-        loge("onBandwidthUpdateRequested: RIL.pullLceData is not supported anymore.");
-    }
-
-    /**
-     * Called when connectivity service 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 interval the interval between packets, between 10 and 3600. Note that this API
-     *                 does not support sub-second precision and will round off the request.
-     * @param packet the packet to send.
-     */
-    @Override
-    public void onStartSocketKeepalive(int slot, @NonNull Duration interval,
-            @NonNull KeepalivePacketData packet) {
-        if (mAbandoned) {
-            log("The agent is already abandoned. Ignored onStartSocketKeepalive.");
-            return;
-        }
-        mTelephonyNetworkAgentCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                () -> callback.onStartSocketKeepalive(slot, interval, packet)));
-    }
-
-    /**
-     * Called when connectivity service requests that the network hardware stop a previously-started
-     * keepalive.
-     *
-     * @param slot the hardware slot on which to stop the keepalive.
-     */
-    @Override
-    public void onStopSocketKeepalive(int slot) {
-        if (mAbandoned) {
-            log("The agent is already abandoned. Ignored onStopSocketKeepalive.");
-            return;
-        }
-        mTelephonyNetworkAgentCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                () -> callback.onStopSocketKeepalive(slot)));
-    }
-
-    /**
-     * Called when a qos callback is registered with a filter.
-     *
-     * @param qosCallbackId the id for the callback registered
-     * @param filter the filter being registered
-     */
-    @Override
-    public void onQosCallbackRegistered(final int qosCallbackId, final @NonNull QosFilter filter) {
-        if (mAbandoned) {
-            log("The agent is already abandoned. Ignored onQosCallbackRegistered.");
-            return;
-        }
-        mTelephonyNetworkAgentCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                () -> callback.onQosCallbackRegistered(qosCallbackId, filter)));
-    }
-
-    /**
-     * Called when a qos callback is registered with a filter.
-     *
-     * Any QoS events that are sent with the same callback id after this method is called are a
-     * no-op.
-     *
-     * @param qosCallbackId the id for the callback being unregistered.
-     */
-    @Override
-    public void onQosCallbackUnregistered(final int qosCallbackId) {
-        if (mAbandoned) {
-            log("The agent is already abandoned. Ignored onQosCallbackUnregistered.");
-            return;
-        }
-        mTelephonyNetworkAgentCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                () -> callback.onQosCallbackUnregistered(qosCallbackId)));
-    }
-
-    /**
-     * Sends the attributes of Qos Session back to the Application. This method is create for
-     * Mockito to mock since
-     * {@link NetworkAgent#sendQosSessionAvailable(int, int, QosSessionAttributes)} is
-     * {@code final} that can't be mocked.
-     *
-     * @param qosCallbackId the callback id that the session belongs to.
-     * @param sessionId the unique session id across all Qos Sessions.
-     * @param attributes the attributes of the Qos Session.
-     */
-    @Override
-    public void notifyQosSessionAvailable(final int qosCallbackId, final int sessionId,
-            @NonNull final QosSessionAttributes attributes) {
-        super.sendQosSessionAvailable(qosCallbackId, sessionId, attributes);
-    }
-
-    /**
-     * Sends event that the Qos Session was lost. This method is create for Mockito to mock
-     * since {@link NetworkAgent#sendQosSessionLost(int, int, int)} is {@code final} that can't be
-     * mocked..
-     *
-     * @param qosCallbackId the callback id that the session belongs to.
-     * @param sessionId the unique session id across all Qos Sessions.
-     * @param qosSessionType the session type {@code QosSession#QosSessionType}.
-     */
-    @Override
-    public void notifyQosSessionLost(final int qosCallbackId,
-            final int sessionId, final int qosSessionType) {
-        super.sendQosSessionLost(qosCallbackId, sessionId, qosSessionType);
-    }
-
-    /**
-     * Abandon the network agent. This is used for telephony to re-create the network agent when
-     * immutable capabilities got changed, where telephony calls {@link NetworkAgent#unregister()}
-     * and then create another network agent with new capabilities. Abandon this network agent
-     * allowing it ignore the subsequent {@link #onNetworkUnwanted()} invocation caused by
-     * {@link NetworkAgent#unregister()}.
-     */
-    public void abandon() {
-        mAbandoned = true;
-        unregister();
-    }
-
-    /**
-     * Register the callback for receiving information from {@link TelephonyNetworkAgent}.
-     *
-     * @param callback The callback.
-     */
-    public void registerCallback(@NonNull TelephonyNetworkAgentCallback callback) {
-        mTelephonyNetworkAgentCallbacks.add(callback);
-    }
-
-    /**
-     * Unregister the previously registered {@link TelephonyNetworkAgentCallback}.
-     *
-     * @param callback The callback to unregister.
-     */
-    public void unregisterCallback(@NonNull TelephonyNetworkAgentCallback callback) {
-        mTelephonyNetworkAgentCallbacks.remove(callback);
-    }
-
-    /**
-     * Log debug messages.
-     * @param s debug messages
-     */
-    protected void log(@NonNull String s) {
-        Rlog.d(mLogTag, s);
-    }
-
-    /**
-     * Log error messages.
-     * @param s error messages
-     */
-    private void loge(@NonNull String s) {
-        Rlog.e(mLogTag, s);
-    }
-
-    /**
-     * Log debug messages and also log into the local log.
-     * @param s debug messages
-     */
-    private void logl(@NonNull String s) {
-        log(s);
-        mLocalLog.log(s);
-    }
-
-    /**
-     * Dump the state of TelephonyNetworkAgent
-     *
-     * @param fd File descriptor
-     * @param printWriter Print writer
-     * @param args Arguments
-     */
-    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
-        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
-        pw.println(mLogTag + ":");
-        pw.increaseIndent();
-        pw.println("Local logs:");
-        pw.increaseIndent();
-        mLocalLog.dump(fd, pw, args);
-        pw.decreaseIndent();
-        pw.decreaseIndent();
-    }
-}
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java b/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
deleted file mode 100644
index b55304a..0000000
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkRequest.java
+++ /dev/null
@@ -1,479 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import android.annotation.ElapsedRealtimeLong;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.NetworkSpecifier;
-import android.os.SystemClock;
-import android.telephony.Annotation.NetCapability;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataProfile;
-import android.telephony.data.TrafficDescriptor;
-import android.telephony.data.TrafficDescriptor.OsAppId;
-
-import com.android.internal.telephony.Phone;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.AbstractMap.SimpleImmutableEntry;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-/**
- * TelephonyNetworkRequest is a wrapper class on top of {@link NetworkRequest}, which is originated
- * from the apps to request network. This class is intended to track supplemental information
- * related to this request, for example priority, evaluation result, whether this request is
- * actively being satisfied, timestamp, etc...
- *
- */
-public class TelephonyNetworkRequest {
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(prefix = {"REQUEST_STATE_"},
-            value = {
-                    REQUEST_STATE_UNSATISFIED,
-                    REQUEST_STATE_SATISFIED})
-    public @interface RequestState {}
-
-    /**
-     * Indicating currently no data networks can satisfy this network request.
-     */
-    public static final int REQUEST_STATE_UNSATISFIED = 0;
-
-    /**
-     * Indicating this request is already satisfied. It must have an attached network (which could
-     * be in any state, including disconnecting). Also note this does not mean the network request
-     * is satisfied in telephony layer. Whether the network request is finally satisfied or not is
-     * determined at the connectivity service layer.
-     */
-    public static final int REQUEST_STATE_SATISFIED = 1;
-
-    /** @hide */
-    @IntDef(flag = true, prefix = { "CAPABILITY_ATTRIBUTE_" }, value = {
-            CAPABILITY_ATTRIBUTE_NONE,
-            CAPABILITY_ATTRIBUTE_APN_SETTING,
-            CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN,
-            CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface NetCapabilityAttribute {}
-
-    /** Network capability attribute none. */
-    public static final int CAPABILITY_ATTRIBUTE_NONE = 0;
-
-    /**
-     * The network capability should result in filling {@link ApnSetting} in {@link DataProfile}.
-     */
-    public static final int CAPABILITY_ATTRIBUTE_APN_SETTING = 1;
-
-    /** The network capability should result in filling DNN in {@link TrafficDescriptor}. */
-    public static final int CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN = 1 << 1;
-
-    /** The network capability should result in filling OS/APP id in {@link TrafficDescriptor}. */
-    public static final int CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID = 1 << 2;
-
-    /**
-     * Describes the attributes of network capabilities. Different capabilities can be translated
-     * to different fields in {@link DataProfile}, or might be expanded to support special actions
-     * in telephony in the future.
-     */
-    private static final Map<Integer, Integer> CAPABILITY_ATTRIBUTE_MAP = Map.ofEntries(
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_MMS,
-                    CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_SUPL,
-                    CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_DUN,
-                    CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_FOTA,
-                    CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_IMS,
-                    CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_CBS,
-                    CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN
-                            | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_XCAP,
-                    CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_EIMS,
-                    CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_INTERNET,
-                    CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_MCX,
-                    CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE,
-                    CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN
-                            | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_VSIM,
-                    CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_BIP,
-                    CAPABILITY_ATTRIBUTE_APN_SETTING | CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY,
-                    CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID),
-            new SimpleImmutableEntry<>(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH,
-                    CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID)
-    );
-
-    /** The phone instance. */
-    private final @NonNull Phone mPhone;
-
-    /**
-     * Native network request from the clients. See {@link NetworkRequest};
-     */
-    private final @NonNull NetworkRequest mNativeNetworkRequest;
-
-    /**
-     * The attributes of the network capabilities in this network request. This describes how this
-     * network request can be translated to different fields in {@link DataProfile} or perform
-     * special actions in telephony.
-     */
-    private final @NetCapabilityAttribute int mCapabilitiesAttributes;
-
-    /**
-     * Priority of the network request. The network request has higher priority will be satisfied
-     * first than lower priority ones.
-     */
-    private int mPriority;
-
-    /**
-     * Data config manager for retrieving data config.
-     */
-    // TODO: Make this @NonNull after old data stack removed.
-    private final @Nullable DataConfigManager mDataConfigManager;
-
-    /**
-     * The attached data network. Note that the data network could be in any state. {@code null}
-     * indicates this network request is not satisfied.
-     */
-    private @Nullable DataNetwork mAttachedDataNetwork;
-
-    /**
-     * The state of the network request.
-     *
-     * @see #REQUEST_STATE_UNSATISFIED
-     * @see #REQUEST_STATE_SATISFIED
-     */
-    // This is not a boolean because there might be more states in the future.
-    private @RequestState int mState;
-
-    /** The timestamp when this network request enters telephony. */
-    private final @ElapsedRealtimeLong long mCreatedTimeMillis;
-
-    /** The data evaluation result. */
-    private @Nullable DataEvaluation mEvaluation;
-
-    /**
-     * Constructor
-     *
-     * @param request The native network request from the clients.
-     * @param phone The phone instance
-     */
-    public TelephonyNetworkRequest(NetworkRequest request, Phone phone) {
-        mPhone = phone;
-        mNativeNetworkRequest = request;
-
-        int capabilitiesAttributes = CAPABILITY_ATTRIBUTE_NONE;
-        for (int networkCapability : mNativeNetworkRequest.getCapabilities()) {
-            capabilitiesAttributes |= CAPABILITY_ATTRIBUTE_MAP.getOrDefault(
-                    networkCapability, CAPABILITY_ATTRIBUTE_NONE);
-        }
-        mCapabilitiesAttributes = capabilitiesAttributes;
-
-        mPriority = 0;
-        mAttachedDataNetwork = null;
-        // When the request was first created, it is in active state so we can actively attempt
-        // to satisfy it.
-        mState = REQUEST_STATE_UNSATISFIED;
-        mCreatedTimeMillis = SystemClock.elapsedRealtime();
-        if (phone.isUsingNewDataStack()) {
-            mDataConfigManager = phone.getDataNetworkController().getDataConfigManager();
-            updatePriority();
-        } else {
-            mDataConfigManager = null;
-        }
-    }
-
-    /**
-     * @see NetworkRequest#getNetworkSpecifier()
-     */
-    public @Nullable NetworkSpecifier getNetworkSpecifier() {
-        return mNativeNetworkRequest.getNetworkSpecifier();
-    }
-
-    /**
-     * @see NetworkRequest#getCapabilities()
-     */
-    public @NonNull @NetCapability int[] getCapabilities() {
-        return mNativeNetworkRequest.getCapabilities();
-    }
-
-    /**
-     * @see NetworkRequest#hasCapability(int)
-     */
-    public boolean hasCapability(@NetCapability int capability) {
-        return mNativeNetworkRequest.hasCapability(capability);
-    }
-
-    /**
-     * @see NetworkRequest#canBeSatisfiedBy(NetworkCapabilities)
-     */
-    public boolean canBeSatisfiedBy(@Nullable NetworkCapabilities nc) {
-        return mNativeNetworkRequest.canBeSatisfiedBy(nc);
-    }
-
-
-    /**
-     * Check if the request's capabilities have certain attributes.
-     *
-     * @param capabilitiesAttributes The attributes to check.
-     * @return {@code true} if the capabilities have provided attributes.
-     *
-     * @see NetCapabilityAttribute
-     */
-    public boolean hasAttribute(@NetCapabilityAttribute int capabilitiesAttributes) {
-        return (mCapabilitiesAttributes & capabilitiesAttributes) == capabilitiesAttributes;
-    }
-
-    /**
-     * Check if this network request can be satisfied by a data profile.
-     *
-     * @param dataProfile The data profile to check.
-     * @return {@code true} if this network request can be satisfied by the data profile.
-     */
-    public boolean canBeSatisfiedBy(@NonNull DataProfile dataProfile) {
-        // If the network request can be translated to OS/App id, then check if the data profile's
-        // OS/App id can satisfy it.
-        if (hasAttribute(CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID)
-                && getOsAppId() != null) {
-            // The network request has traffic descriptor type capabilities. Match the traffic
-            // descriptor.
-            if (dataProfile.getTrafficDescriptor() != null && Arrays.equals(getOsAppId().getBytes(),
-                    dataProfile.getTrafficDescriptor().getOsAppId())) {
-                return true;
-            }
-        }
-
-        // If the network request can be translated to APN setting or DNN in traffic descriptor,
-        // then check if the data profile's APN setting can satisfy it.
-        if ((hasAttribute(CAPABILITY_ATTRIBUTE_APN_SETTING)
-                || hasAttribute(CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_DNN))
-                && dataProfile.getApnSetting() != null) {
-            // Fallback to the legacy APN type matching.
-            List<Integer> apnTypes = Arrays.stream(getCapabilities()).boxed()
-                    .map(DataUtils::networkCapabilityToApnType)
-                    .filter(apnType -> apnType != ApnSetting.TYPE_NONE)
-                    .collect(Collectors.toList());
-            // In case of enterprise network request, the network request will have internet,
-            // but APN type will not have default type as the enterprise apn should not be used
-            // as default network. Ignore default type of the network request if it
-            // has enterprise type as well. This will make sure the network request with
-            // internet and enterprise will be satisfied with data profile with enterprise at the
-            // same time default network request will not get satisfied with enterprise data
-            // profile.
-            // TODO b/232264746
-            if (apnTypes.contains(ApnSetting.TYPE_ENTERPRISE)) {
-                apnTypes.remove((Integer) ApnSetting.TYPE_DEFAULT);
-            }
-
-            return apnTypes.stream().allMatch(dataProfile.getApnSetting()::canHandleType);
-        }
-        return false;
-    }
-
-    /**
-     * Get the priority of the network request.
-     *
-     * @return The priority from 0 to 100. 100 indicates the highest priority.
-     */
-    public int getPriority() {
-        return mPriority;
-    }
-
-    /**
-     * Update the priority from data config manager.
-     */
-    public void updatePriority() {
-        mPriority = Arrays.stream(mNativeNetworkRequest.getCapabilities())
-                .map(mDataConfigManager::getNetworkCapabilityPriority)
-                .max()
-                .orElse(0);
-    }
-
-    /**
-     * Get the network capability which is APN-type based from the network request. If there are
-     * multiple APN types capability, the highest priority one will be returned.
-     *
-     * @return The highest priority APN type based network capability from this network request. -1
-     * if there is no APN type capabilities in this network request.
-     */
-    public @NetCapability int getApnTypeNetworkCapability() {
-        if (!hasAttribute(CAPABILITY_ATTRIBUTE_APN_SETTING)) return -1;
-        return Arrays.stream(getCapabilities()).boxed()
-                .filter(cap -> DataUtils.networkCapabilityToApnType(cap) != ApnSetting.TYPE_NONE)
-                .max(Comparator.comparingInt(mDataConfigManager::getNetworkCapabilityPriority))
-                .orElse(-1);
-    }
-    /**
-     * @return The native network request.
-     */
-    public @NonNull NetworkRequest getNativeNetworkRequest() {
-        return mNativeNetworkRequest;
-    }
-
-    /**
-     * Set the attached data network.
-     *
-     * @param dataNetwork The data network.
-     */
-    public void setAttachedNetwork(@NonNull DataNetwork dataNetwork) {
-        mAttachedDataNetwork = dataNetwork;
-    }
-
-    /**
-     * @return The attached network. {@code null} indicates the request is not attached to any
-     * network (i.e. the request is unsatisfied).
-     */
-    public @Nullable DataNetwork getAttachedNetwork() {
-        return mAttachedDataNetwork;
-    }
-
-    /**
-     * Set the state of the network request.
-     *
-     * @param state The state.
-     */
-    public void setState(@RequestState int state) {
-        mState = state;
-    }
-
-    /**
-     * @return The state of the network request.
-     */
-    public @RequestState int getState() {
-        return mState;
-    }
-
-    /**
-     * Set the data evaluation result.
-     *
-     * @param evaluation The data evaluation result.
-     */
-    public void setEvaluation(@NonNull DataEvaluation evaluation) {
-        mEvaluation = evaluation;
-    }
-
-    /**
-     * Get the capability differentiator from the network request. Some capabilities
-     * (e.g. {@link NetworkCapabilities#NET_CAPABILITY_ENTERPRISE} could support more than one
-     * traffic (e.g. "ENTERPRISE2", "ENTERPRISE3"). This method returns that differentiator.
-     *
-     * @return The differentiator. 0 if not found.
-     */
-    public int getCapabilityDifferentiator() {
-        if (hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)) {
-            int[] ids = mNativeNetworkRequest.getEnterpriseIds();
-            // No need to verify the range of the id. It has been done in NetworkCapabilities.
-            if (ids.length > 0) return ids[0];
-        }
-        return 0;
-    }
-
-    /**
-     * @return {@code true} if this network request can result in bringing up a metered network.
-     */
-    public boolean isMeteredRequest() {
-        // TODO: Remove null check after old data stack removed.
-        return mDataConfigManager != null && mDataConfigManager.isAnyMeteredCapability(
-                getCapabilities(), mPhone.getServiceState().getDataRoaming());
-    }
-
-    /**
-     * Get Os/App id from the network request.
-     *
-     * @return Os/App id. {@code null} if the request does not have traffic descriptor based network
-     * capabilities.
-     */
-    public @Nullable OsAppId getOsAppId() {
-        if (!hasAttribute(CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID)) return null;
-
-        // We do not support multiple network capabilities translated to Os/App id at this time.
-        // If someday this needs to be done, we need to expand TrafficDescriptor to support
-        // connection capabilities instead of using Os/App id to do the work.
-        int networkCapability = Arrays.stream(getCapabilities()).boxed()
-                .filter(cap -> (CAPABILITY_ATTRIBUTE_MAP.getOrDefault(
-                        cap, CAPABILITY_ATTRIBUTE_NONE)
-                        & CAPABILITY_ATTRIBUTE_TRAFFIC_DESCRIPTOR_OS_APP_ID) != 0)
-                .findFirst()
-                .orElse(-1);
-
-        if (networkCapability == -1) return null;
-
-        int differentiator = getCapabilityDifferentiator();
-        if (differentiator > 0) {
-            return new OsAppId(OsAppId.ANDROID_OS_ID,
-                    DataUtils.networkCapabilityToString(networkCapability), differentiator);
-        } else {
-            return new OsAppId(OsAppId.ANDROID_OS_ID,
-                    DataUtils.networkCapabilityToString(networkCapability));
-        }
-    }
-
-    /**
-     * Convert the telephony request state to string.
-     *
-     * @param state The request state.
-     * @return The request state in string format.
-     */
-    private static @NonNull String requestStateToString(
-            @TelephonyNetworkRequest.RequestState int state) {
-        switch (state) {
-            case TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED: return "UNSATISFIED";
-            case TelephonyNetworkRequest.REQUEST_STATE_SATISFIED: return "SATISFIED";
-            default: return "UNKNOWN(" + state + ")";
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "[" + mNativeNetworkRequest.toString() + ", mPriority=" + mPriority
-                + ", state=" + requestStateToString(mState)
-                + ", mAttachedDataNetwork=" + (mAttachedDataNetwork != null
-                ? mAttachedDataNetwork.name() : null) + ", isMetered=" + isMeteredRequest()
-                + ", created time=" + DataUtils.elapsedTimeToString(mCreatedTimeMillis)
-                + ", evaluation result=" + mEvaluation + "]";
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        TelephonyNetworkRequest that = (TelephonyNetworkRequest) o;
-        // Only compare the native network request.
-        return mNativeNetworkRequest.equals(that.mNativeNetworkRequest);
-    }
-
-    @Override
-    public int hashCode() {
-        // Only use the native network request's hash code.
-        return mNativeNetworkRequest.hashCode();
-    }
-}
diff --git a/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java b/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java
new file mode 100644
index 0000000..53b7515
--- /dev/null
+++ b/src/java/com/android/internal/telephony/dataconnection/AccessNetworksManager.java
@@ -0,0 +1,498 @@
+/*
+ * Copyright 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.dataconnection;
+
+import android.annotation.NonNull;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.pm.PackageManager;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.PersistableBundle;
+import android.os.Registrant;
+import android.os.RegistrantList;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.Annotation.ApnType;
+import android.telephony.AnomalyReporter;
+import android.telephony.CarrierConfigManager;
+import android.telephony.data.ApnSetting;
+import android.telephony.data.IQualifiedNetworksService;
+import android.telephony.data.IQualifiedNetworksServiceCallback;
+import android.telephony.data.QualifiedNetworksService;
+import android.telephony.data.ThrottleStatus;
+import android.text.TextUtils;
+import android.util.IndentingPrintWriter;
+import android.util.SparseArray;
+
+import com.android.internal.telephony.Phone;
+import com.android.telephony.Rlog;
+
+import java.io.FileDescriptor;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * Access network manager manages the qualified/available networks for mobile data connection.
+ * It binds to the vendor's qualified networks service and actively monitors the qualified
+ * networks changes.
+ */
+public class AccessNetworksManager extends Handler {
+    private final String mLogTag;
+    private static final boolean DBG = false;
+    private final UUID mAnomalyUUID = UUID.fromString("c2d1a639-00e2-4561-9619-6acf37d90590");
+    private String mLastBoundPackageName;
+
+    private static final int[] SUPPORTED_APN_TYPES = {
+            ApnSetting.TYPE_DEFAULT,
+            ApnSetting.TYPE_MMS,
+            ApnSetting.TYPE_FOTA,
+            ApnSetting.TYPE_IMS,
+            ApnSetting.TYPE_CBS,
+            ApnSetting.TYPE_SUPL,
+            ApnSetting.TYPE_EMERGENCY,
+            ApnSetting.TYPE_XCAP
+    };
+
+    private final Phone mPhone;
+
+    private final CarrierConfigManager mCarrierConfigManager;
+
+    private IQualifiedNetworksService mIQualifiedNetworksService;
+
+    private AccessNetworksManagerDeathRecipient mDeathRecipient;
+
+    private String mTargetBindingPackageName;
+
+    private QualifiedNetworksServiceConnection mServiceConnection;
+
+    // Available networks. Key is the APN type.
+    private final SparseArray<int[]> mAvailableNetworks = new SparseArray<>();
+
+    private final RegistrantList mQualifiedNetworksChangedRegistrants = new RegistrantList();
+
+    private final Set<DataThrottler> mDataThrottlers = new HashSet<>();
+
+    private final BroadcastReceiver mConfigChangedReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            final String action = intent.getAction();
+            if (CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED.equals(action)
+                    && mPhone.getPhoneId() == intent.getIntExtra(
+                    CarrierConfigManager.EXTRA_SLOT_INDEX, 0)) {
+                // We should wait for carrier config changed event because the target binding
+                // package name can come from the carrier config. Note that we still get this event
+                // even when SIM is absent.
+                if (DBG) log("Carrier config changed. Try to bind qualified network service.");
+                bindQualifiedNetworksService();
+            }
+        }
+    };
+
+    /**
+     * Registers the data throttler in order to receive APN status changes.
+     *
+     * @param dataThrottler the data throttler to register
+     */
+    public void registerDataThrottler(DataThrottler dataThrottler) {
+        this.post(() -> {
+            QualifiedNetworksServiceConnection serviceConnection = mServiceConnection;
+            this.mDataThrottlers.add(dataThrottler);
+            if (serviceConnection != null) {
+                serviceConnection.registerDataThrottler(dataThrottler);
+            }
+        });
+    }
+
+    /**
+     * Represents qualified network types list on a specific APN type.
+     */
+    public static class QualifiedNetworks {
+        public final @ApnType int apnType;
+        // The qualified networks in preferred order. Each network is a AccessNetworkType.
+        public final int[] qualifiedNetworks;
+        public QualifiedNetworks(@ApnType int apnType, int[] qualifiedNetworks) {
+            this.apnType = apnType;
+            this.qualifiedNetworks = qualifiedNetworks;
+        }
+
+        @Override
+        public String toString() {
+            List<String> accessNetworkStrings = new ArrayList<>();
+            for (int network : qualifiedNetworks) {
+                accessNetworkStrings.add(AccessNetworkType.toString(network));
+            }
+            return "[QualifiedNetworks: apnType="
+                    + ApnSetting.getApnTypeString(apnType)
+                    + ", networks="
+                    + Arrays.stream(qualifiedNetworks)
+                    .mapToObj(type -> AccessNetworkType.toString(type))
+                    .collect(Collectors.joining(","))
+                    + "]";
+        }
+    }
+
+    private class AccessNetworksManagerDeathRecipient implements IBinder.DeathRecipient {
+        @Override
+        public void binderDied() {
+            // TODO: try to rebind the service.
+            String message = "Qualified network service " + mLastBoundPackageName + " died.";
+            loge(message);
+            AnomalyReporter.reportAnomaly(mAnomalyUUID, message);
+        }
+    }
+
+    private final class QualifiedNetworksServiceConnection implements ServiceConnection {
+
+        /**
+         * The APN throttle status callback is attached to the service connection so that they have
+         * the same life cycle.
+         */
+        @NonNull
+        private final ThrottleStatusChangedCallback mThrottleStatusCallback;
+
+        QualifiedNetworksServiceConnection() {
+            mThrottleStatusCallback = new ThrottleStatusChangedCallback();
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            if (DBG) log("onServiceConnected " + name);
+            mIQualifiedNetworksService = IQualifiedNetworksService.Stub.asInterface(service);
+            mDeathRecipient = new AccessNetworksManagerDeathRecipient();
+            mLastBoundPackageName = getQualifiedNetworksServicePackageName();
+
+            try {
+                service.linkToDeath(mDeathRecipient, 0 /* flags */);
+                mIQualifiedNetworksService.createNetworkAvailabilityProvider(mPhone.getPhoneId(),
+                        new QualifiedNetworksServiceCallback());
+
+                registerDataThrottlersFirstTime();
+
+            } catch (RemoteException e) {
+                loge("Remote exception. " + e);
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            if (DBG) log("onServiceDisconnected " + name);
+            unregisterForThrottleCallbacks();
+            mTargetBindingPackageName = null;
+        }
+
+        /**
+         * Runs on all of the data throttlers when the service is connected
+         */
+        private void registerDataThrottlersFirstTime() {
+            post(() -> {
+                for (DataThrottler dataThrottler : mDataThrottlers) {
+                    dataThrottler.registerForThrottleStatusChanges(mThrottleStatusCallback);
+                }
+            });
+        }
+
+        private void registerDataThrottler(DataThrottler dataThrottler) {
+            post(() -> {
+                dataThrottler.registerForThrottleStatusChanges(mThrottleStatusCallback);
+            });
+        }
+
+        private void unregisterForThrottleCallbacks() {
+            post(() -> {
+                for (DataThrottler dataThrottler : mDataThrottlers) {
+                    dataThrottler.unregisterForThrottleStatusChanges(mThrottleStatusCallback);
+                }
+            });
+        }
+    }
+
+    private class ThrottleStatusChangedCallback implements DataThrottler.Callback {
+        @Override
+        public void onThrottleStatusChanged(List<ThrottleStatus> throttleStatuses) {
+            post(() -> {
+                try {
+                    List<ThrottleStatus> throttleStatusesBySlot =
+                            throttleStatuses
+                                    .stream()
+                                    .filter(x -> x.getSlotIndex() == mPhone.getPhoneId())
+                                    .collect(Collectors.toList());
+
+                    mIQualifiedNetworksService.reportThrottleStatusChanged(mPhone.getPhoneId(),
+                            throttleStatusesBySlot);
+                } catch (Exception ex) {
+                    loge("onThrottleStatusChanged", ex);
+                }
+            });
+        }
+    }
+
+    private final class QualifiedNetworksServiceCallback extends
+            IQualifiedNetworksServiceCallback.Stub {
+        @Override
+        public void onQualifiedNetworkTypesChanged(int apnTypes, int[] qualifiedNetworkTypes) {
+            log("onQualifiedNetworkTypesChanged. apnTypes = ["
+                    + ApnSetting.getApnTypesStringFromBitmask(apnTypes)
+                    + "], networks = [" + Arrays.stream(qualifiedNetworkTypes)
+                    .mapToObj(i -> AccessNetworkType.toString(i)).collect(Collectors.joining(","))
+                    + "]");
+            List<QualifiedNetworks> qualifiedNetworksList = new ArrayList<>();
+            for (int supportedApnType : SUPPORTED_APN_TYPES) {
+                if ((apnTypes & supportedApnType) == supportedApnType) {
+                    // TODO: Verify the preference from data settings manager to make sure the order
+                    // of the networks do not violate users/carrier's preference.
+                    if (mAvailableNetworks.get(supportedApnType) != null) {
+                        if (Arrays.equals(mAvailableNetworks.get(supportedApnType),
+                                qualifiedNetworkTypes)) {
+                            log("Available networks for "
+                                    + ApnSetting.getApnTypesStringFromBitmask(supportedApnType)
+                                    + " not changed.");
+                            continue;
+                        }
+                    }
+                    mAvailableNetworks.put(supportedApnType, qualifiedNetworkTypes);
+                    qualifiedNetworksList.add(new QualifiedNetworks(supportedApnType,
+                            qualifiedNetworkTypes));
+                }
+            }
+
+            if (!qualifiedNetworksList.isEmpty()) {
+                mQualifiedNetworksChangedRegistrants.notifyResult(qualifiedNetworksList);
+            }
+        }
+    }
+
+    /**
+     * Constructor
+     *
+     * @param phone The phone object
+     */
+    public AccessNetworksManager(Phone phone) {
+        mPhone = phone;
+        mCarrierConfigManager = (CarrierConfigManager) phone.getContext().getSystemService(
+                Context.CARRIER_CONFIG_SERVICE);
+        mLogTag = "ANM-" + mPhone.getPhoneId();
+
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        try {
+            Context contextAsUser = phone.getContext().createPackageContextAsUser(
+                phone.getContext().getPackageName(), 0, UserHandle.ALL);
+            contextAsUser.registerReceiver(mConfigChangedReceiver, intentFilter,
+                null /* broadcastPermission */, null);
+        } catch (PackageManager.NameNotFoundException e) {
+            loge("Package name not found: ", e);
+        }
+        bindQualifiedNetworksService();
+    }
+
+    /**
+     * Find the qualified network service from configuration and binds to it. It reads the
+     * configuration from carrier config if it exists. If not, read it from resources.
+     */
+    private void bindQualifiedNetworksService() {
+        post(() -> {
+            Intent intent = null;
+            String packageName = getQualifiedNetworksServicePackageName();
+            String className = getQualifiedNetworksServiceClassName();
+
+            if (DBG) log("Qualified network service package = " + packageName);
+            if (TextUtils.isEmpty(packageName)) {
+                loge("Can't find the binding package");
+                return;
+            }
+
+            if (TextUtils.isEmpty(className)) {
+                intent = new Intent(QualifiedNetworksService.QUALIFIED_NETWORKS_SERVICE_INTERFACE);
+                intent.setPackage(packageName);
+            } else {
+                ComponentName cm = new ComponentName(packageName, className);
+                intent = new Intent(QualifiedNetworksService.QUALIFIED_NETWORKS_SERVICE_INTERFACE)
+                        .setComponent(cm);
+            }
+
+            if (TextUtils.equals(packageName, mTargetBindingPackageName)) {
+                if (DBG) log("Service " + packageName + " already bound or being bound.");
+                return;
+            }
+
+            if (mIQualifiedNetworksService != null
+                    && mIQualifiedNetworksService.asBinder().isBinderAlive()) {
+                // Remove the network availability updater and then unbind the service.
+                try {
+                    mIQualifiedNetworksService.removeNetworkAvailabilityProvider(
+                            mPhone.getPhoneId());
+                } catch (RemoteException e) {
+                    loge("Cannot remove network availability updater. " + e);
+                }
+
+                mPhone.getContext().unbindService(mServiceConnection);
+            }
+
+            try {
+                mServiceConnection = new QualifiedNetworksServiceConnection();
+                log("bind to " + packageName);
+                if (!mPhone.getContext().bindService(intent, mServiceConnection,
+                        Context.BIND_AUTO_CREATE)) {
+                    loge("Cannot bind to the qualified networks service.");
+                    return;
+                }
+                mTargetBindingPackageName = packageName;
+            } catch (Exception e) {
+                loge("Cannot bind to the qualified networks service. Exception: " + e);
+            }
+        });
+    }
+
+    /**
+     * Get the qualified network service package.
+     *
+     * @return package name of the qualified networks service package. Return empty string when in
+     * legacy mode (i.e. Dedicated IWLAN data/network service is not supported).
+     */
+    private String getQualifiedNetworksServicePackageName() {
+        // Read package name from the resource
+        String packageName = mPhone.getContext().getResources().getString(
+                com.android.internal.R.string.config_qualified_networks_service_package);
+
+        PersistableBundle b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId());
+
+        if (b != null) {
+            // If carrier config overrides it, use the one from carrier config
+            String carrierConfigPackageName =  b.getString(CarrierConfigManager
+                    .KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_PACKAGE_OVERRIDE_STRING);
+            if (!TextUtils.isEmpty(carrierConfigPackageName)) {
+                if (DBG) log("Found carrier config override " + carrierConfigPackageName);
+                packageName = carrierConfigPackageName;
+            }
+        }
+
+        return packageName;
+    }
+
+    /**
+     * Get the qualified network service class name.
+     *
+     * @return class name of the qualified networks service package.
+     */
+    private String getQualifiedNetworksServiceClassName() {
+        // Read package name from the resource
+        String className = mPhone.getContext().getResources().getString(
+                com.android.internal.R.string.config_qualified_networks_service_class);
+
+        PersistableBundle b = mCarrierConfigManager.getConfigForSubId(mPhone.getSubId());
+
+        if (b != null) {
+            // If carrier config overrides it, use the one from carrier config
+            String carrierConfigClassName =  b.getString(CarrierConfigManager
+                    .KEY_CARRIER_QUALIFIED_NETWORKS_SERVICE_CLASS_OVERRIDE_STRING);
+            if (!TextUtils.isEmpty(carrierConfigClassName)) {
+                if (DBG) log("Found carrier config override " + carrierConfigClassName);
+                className = carrierConfigClassName;
+            }
+        }
+
+        return className;
+    }
+
+    private @NonNull List<QualifiedNetworks> getQualifiedNetworksList() {
+        List<QualifiedNetworks> qualifiedNetworksList = new ArrayList<>();
+        for (int i = 0; i < mAvailableNetworks.size(); i++) {
+            qualifiedNetworksList.add(new QualifiedNetworks(mAvailableNetworks.keyAt(i),
+                    mAvailableNetworks.valueAt(i)));
+        }
+
+        return qualifiedNetworksList;
+    }
+
+    /**
+     * Register for qualified networks changed event.
+     *
+     * @param h The target to post the event message to.
+     * @param what The event.
+     */
+    public void registerForQualifiedNetworksChanged(Handler h, int what) {
+        if (h != null) {
+            Registrant r = new Registrant(h, what, null);
+            mQualifiedNetworksChangedRegistrants.add(r);
+
+            // Notify for the first time if there is already something in the available network
+            // list.
+            if (mAvailableNetworks.size() != 0) {
+                r.notifyResult(getQualifiedNetworksList());
+            }
+        }
+    }
+
+    /**
+     * Unregister for qualified networks changed event.
+     *
+     * @param h The handler
+     */
+    public void unregisterForQualifiedNetworksChanged(Handler h) {
+        if (h != null) {
+            mQualifiedNetworksChangedRegistrants.remove(h);
+        }
+    }
+
+    /**
+     * Dump the state of transport manager
+     *
+     * @param fd File descriptor
+     * @param pw Print writer
+     * @param args Arguments
+     */
+    public void dump(FileDescriptor fd, IndentingPrintWriter pw, String[] args) {
+        pw.println("AccessNetworksManager:");
+        pw.increaseIndent();
+        pw.println("Available networks:");
+        pw.increaseIndent();
+
+        for (int i = 0; i < mAvailableNetworks.size(); i++) {
+            pw.println("APN type "
+                    + ApnSetting.getApnTypeString(mAvailableNetworks.keyAt(i))
+                    + ": [" + Arrays.stream(mAvailableNetworks.valueAt(i))
+                    .mapToObj(AccessNetworkType::toString)
+                    .collect(Collectors.joining(",")) + "]");
+        }
+        pw.decreaseIndent();
+        pw.decreaseIndent();
+    }
+
+    private void log(String s) {
+        Rlog.d(mLogTag, s);
+    }
+
+    private void loge(String s) {
+        Rlog.e(mLogTag, s);
+    }
+
+    private void loge(String s, Exception ex) {
+        Rlog.e(mLogTag, s, ex);
+    }
+
+}
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
index 3f487cd..49eb7c5 100644
--- a/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
+++ b/src/java/com/android/internal/telephony/dataconnection/ApnContext.java
@@ -394,21 +394,13 @@
         }
     }
 
+    private final LocalLog mLocalLog = new LocalLog(150);
     private final ArraySet<NetworkRequest> mNetworkRequests = new ArraySet<>();
-    private final LocalLog mStateLocalLog = new LocalLog(32);
+    private final LocalLog mStateLocalLog = new LocalLog(50);
 
-    private static final LocalLog sLocalLog = new LocalLog(256);
-
-    /** Add a line to the ApnContext local log. */
-    public static void requestLog(ApnContext apnContext, String str) {
-        if (apnContext != null) {
-            String logString = "[ApnContext:" + apnContext.getApnType() + "] " + str;
-            if (DBG) {
-                Rlog.d(SLOG_TAG, logString);
-            }
-            synchronized (sLocalLog) {
-                sLocalLog.log(logString);
-            }
+    public void requestLog(String str) {
+        synchronized (mLocalLog) {
+            mLocalLog.log(str);
         }
     }
 
@@ -424,7 +416,7 @@
             Message onHandoverCompleteMsg) {
         synchronized (mRefCountLock) {
             mNetworkRequests.add(networkRequest);
-            requestLog(this, "requestNetwork for " + networkRequest + ", type="
+            logl("requestNetwork for " + networkRequest + ", type="
                     + DcTracker.requestTypeToString(type));
             mDcTracker.enableApn(ApnSetting.getApnTypesBitmaskFromString(mApnType), type,
                     onHandoverCompleteMsg);
@@ -445,7 +437,7 @@
                     // the data connection. For example, the score may change.
                     mDataConnection.reevaluateDataConnectionProperties();
                 }
-                requestLog(this, "releaseNetwork left with " + mNetworkRequests.size()
+                logl("releaseNetwork left with " + mNetworkRequests.size()
                         + " requests.");
                 if (mNetworkRequests.size() == 0
                         || type == DcTracker.RELEASE_TYPE_DETACH
@@ -478,7 +470,7 @@
     private final SparseIntArray mRetriesLeftPerErrorCode = new SparseIntArray();
 
     public void resetErrorCodeRetries() {
-        requestLog(this, "resetErrorCodeRetries");
+        logl("ApnContext.resetErrorCodeRetries");
 
         String[] config = mPhone.getContext().getResources().getStringArray(
                 com.android.internal.R.array.config_cell_retries_per_error_code);
@@ -528,7 +520,7 @@
                 }
             }
         }
-        requestLog(this, "restartOnError(" + errorCode + ") found " + retriesLeft
+        logl("ApnContext.restartOnError(" + errorCode + ") found " + retriesLeft
                 + " and returned " + result);
         return result;
     }
@@ -545,13 +537,7 @@
         return mRetryManager.getRetryAfterDisconnectDelay();
     }
 
-    /**
-     * Get APN type from the network request.
-     *
-     * @param nr The network request.
-     * @return The APN type.
-     */
-    public static @ApnType int getApnTypeFromNetworkRequest(NetworkRequest nr) {
+    static @ApnType int getApnTypeFromNetworkRequest(NetworkRequest nr) {
         // For now, ignore the bandwidth stuff
         if (nr.getTransportTypes().length > 0
                 && !nr.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
@@ -644,6 +630,11 @@
         }
     }
 
+    private void logl(String s) {
+        log(s);
+        mLocalLog.log(s);
+    }
+
     public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
         final IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
         synchronized (mRefCountLock) {
@@ -656,6 +647,12 @@
                 }
                 pw.decreaseIndent();
             }
+            pw.increaseIndent();
+            pw.println("-----");
+            pw.println("Local log:");
+            mLocalLog.dump(fd, pw, args);
+            pw.println("-----");
+            pw.decreaseIndent();
             pw.println("Historical APN state:");
             pw.increaseIndent();
             mStateLocalLog.dump(fd, pw, args);
@@ -664,12 +661,4 @@
             pw.println("--------------------------");
         }
     }
-
-    /** Dumps the ApnContext local log. */
-    public static void dumpLocalLog(FileDescriptor fd, PrintWriter printWriter, String[] args) {
-        printWriter.println("Local log:");
-        synchronized (sLocalLog) {
-            sLocalLog.dump(fd, printWriter, args);
-        }
-    }
 }
diff --git a/src/java/com/android/internal/telephony/dataconnection/ApnSettingUtils.java b/src/java/com/android/internal/telephony/dataconnection/ApnSettingUtils.java
index 3c2a6ef..d072a68 100644
--- a/src/java/com/android/internal/telephony/dataconnection/ApnSettingUtils.java
+++ b/src/java/com/android/internal/telephony/dataconnection/ApnSettingUtils.java
@@ -21,8 +21,10 @@
 import android.telephony.Annotation.ApnType;
 import android.telephony.CarrierConfigManager;
 import android.telephony.data.ApnSetting;
+import android.util.Log;
 
 import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.uicc.IccRecords;
 import com.android.telephony.Rlog;
 
 import java.util.Arrays;
@@ -37,6 +39,76 @@
 
     private static final boolean DBG = false;
 
+    private static boolean iccidMatches(String mvnoData, String iccId) {
+        String[] mvnoIccidList = mvnoData.split(",");
+        for (String mvnoIccid : mvnoIccidList) {
+            if (iccId.startsWith(mvnoIccid)) {
+                Log.d(LOG_TAG, "mvno icc id match found");
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean imsiMatches(String imsiDB, String imsiSIM) {
+        // Note: imsiDB value has digit number or 'x' character for seperating USIM information
+        // for MVNO operator. And then digit number is matched at same order and 'x' character
+        // could replace by any digit number.
+        // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator,
+        //     that means first 6 digits, 8th and 9th digit
+        //     should be set in USIM for GG Operator.
+        int len = imsiDB.length();
+
+        if (len <= 0) return false;
+        if (len > imsiSIM.length()) return false;
+
+        for (int idx = 0; idx < len; idx++) {
+            char c = imsiDB.charAt(idx);
+            if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) {
+                continue;
+            } else {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Check if MVNO type and data match IccRecords.
+     *
+     * @param r the IccRecords
+     * @param mvnoType the MVNO type
+     * @param mvnoMatchData the MVNO match data
+     * @return {@code true} if MVNO type and data match IccRecords, {@code false} otherwise.
+     */
+    public static boolean mvnoMatches(IccRecords r, int mvnoType, String mvnoMatchData) {
+        if (mvnoType == ApnSetting.MVNO_TYPE_SPN) {
+            String spn = r.getServiceProviderNameWithBrandOverride();
+            if ((spn != null) && spn.equalsIgnoreCase(mvnoMatchData)) {
+                return true;
+            }
+        } else if (mvnoType == ApnSetting.MVNO_TYPE_IMSI) {
+            String imsiSIM = r.getIMSI();
+            if ((imsiSIM != null) && imsiMatches(mvnoMatchData, imsiSIM)) {
+                return true;
+            }
+        } else if (mvnoType == ApnSetting.MVNO_TYPE_GID) {
+            String gid1 = r.getGid1();
+            int mvno_match_data_length = mvnoMatchData.length();
+            if ((gid1 != null) && (gid1.length() >= mvno_match_data_length)
+                    && gid1.substring(0, mvno_match_data_length).equalsIgnoreCase(mvnoMatchData)) {
+                return true;
+            }
+        } else if (mvnoType == ApnSetting.MVNO_TYPE_ICCID) {
+            String iccId = r.getIccId();
+            if ((iccId != null) && iccidMatches(mvnoMatchData, iccId)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
     /**
      * Check if this APN type is metered.
      *
diff --git a/src/java/com/android/internal/telephony/data/CellularDataService.java b/src/java/com/android/internal/telephony/dataconnection/CellularDataService.java
similarity index 94%
rename from src/java/com/android/internal/telephony/data/CellularDataService.java
rename to src/java/com/android/internal/telephony/dataconnection/CellularDataService.java
index c5923aa..b38e2be 100644
--- a/src/java/com/android/internal/telephony/data/CellularDataService.java
+++ b/src/java/com/android/internal/telephony/dataconnection/CellularDataService.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony.dataconnection;
 
 import static android.telephony.data.DataServiceCallback.RESULT_SUCCESS;
 
@@ -37,7 +37,6 @@
 import com.android.internal.telephony.PhoneFactory;
 import com.android.telephony.Rlog;
 
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -52,7 +51,7 @@
     private static final boolean DBG = false;
 
     private static final int SETUP_DATA_CALL_COMPLETE               = 1;
-    private static final int DEACTIVATE_DATA_CALL_COMPLETE          = 2;
+    private static final int DEACTIVATE_DATA_ALL_COMPLETE           = 2;
     private static final int SET_INITIAL_ATTACH_APN_COMPLETE        = 3;
     private static final int SET_DATA_PROFILE_COMPLETE              = 4;
     private static final int REQUEST_DATA_CALL_LIST_COMPLETE        = 5;
@@ -88,7 +87,7 @@
                                     : RESULT_SUCCESS,
                                     response);
                             break;
-                        case DEACTIVATE_DATA_CALL_COMPLETE:
+                        case DEACTIVATE_DATA_ALL_COMPLETE:
                             callback.onDeactivateDataCallComplete(ar.exception != null
                                     ? DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE
                                     : RESULT_SUCCESS);
@@ -108,8 +107,8 @@
                                     ar.exception != null
                                             ? DataServiceCallback.RESULT_ERROR_ILLEGAL_STATE
                                             : RESULT_SUCCESS,
-                                    ar.result != null ? (List<DataCallResponse>) ar.result
-                                            : Collections.EMPTY_LIST
+                                    ar.exception != null
+                                            ? null : (List<DataCallResponse>) ar.result
                                     );
                             break;
                         case DATA_CALL_LIST_CHANGED:
@@ -122,11 +121,7 @@
                             callback.onHandoverCancelled(toResultCode(ar.exception));
                             break;
                         case APN_UNTHROTTLED:
-                            if (ar.result instanceof DataProfile) {
-                                notifyDataProfileUnthrottled((DataProfile) ar.result);
-                            } else {
-                                notifyApnUnthrottled((String) ar.result);
-                            }
+                            notifyApnUnthrottled((String) ar.result);
                             break;
                         default:
                             loge("Unexpected event: " + message.what);
@@ -190,7 +185,7 @@
             // Only obtain the message when the caller wants a callback. If the caller doesn't care
             // the request completed or results, then no need to pass the message down.
             if (callback != null) {
-                message = Message.obtain(mHandler, DEACTIVATE_DATA_CALL_COMPLETE);
+                message = Message.obtain(mHandler, DEACTIVATE_DATA_ALL_COMPLETE);
                 mCallbackMap.put(message, callback);
             }
 
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index 348908a..6ddc6fe 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -25,9 +25,6 @@
 import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.UserInfo;
 import android.net.ConnectivityManager;
 import android.net.InetAddresses;
 import android.net.KeepalivePacketData;
@@ -49,10 +46,8 @@
 import android.os.HandlerExecutor;
 import android.os.Message;
 import android.os.PersistableBundle;
-import android.os.Process;
 import android.os.SystemClock;
 import android.os.SystemProperties;
-import android.os.UserManager;
 import android.provider.Telephony;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.TransportType;
@@ -84,7 +79,6 @@
 import android.util.TimeUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.CarrierPrivilegesTracker;
 import com.android.internal.telephony.CarrierSignalAgent;
 import com.android.internal.telephony.DctConstants;
 import com.android.internal.telephony.Phone;
@@ -94,15 +88,12 @@
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.RetryManager;
 import com.android.internal.telephony.TelephonyStatsLog;
-import com.android.internal.telephony.data.DataConfigManager;
-import com.android.internal.telephony.data.KeepaliveStatus;
 import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType;
 import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType;
 import com.android.internal.telephony.metrics.DataCallSessionStats;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.nano.TelephonyProto.RilDataCall;
 import com.android.internal.telephony.uicc.IccUtils;
-import com.android.internal.telephony.util.ArrayUtils;
 import com.android.internal.util.AsyncChannel;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.internal.util.Protocol;
@@ -158,6 +149,8 @@
      */
     private static final UUID OS_ID = UUID.fromString("97a498e3-fc92-5c94-8986-0333d06e4e47");
 
+    private static final int MIN_V6_MTU = 1280;
+
     /**
      * The data connection is not being or been handovered. Note this is the state for the source
      * data connection, not destination data connection
@@ -207,7 +200,7 @@
     private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
 
     // Whether or not the data connection should allocate its own pdu session id
-    private boolean mDoAllocatePduSessionId;
+    private final boolean mDoAllocatePduSessionId;
 
     private static AtomicInteger mInstanceNumber = new AtomicInteger(0);
     private AsyncChannel mAc;
@@ -219,7 +212,7 @@
 
     private final String mTagSuffix;
 
-    private final LocalLog mHandoverLocalLog = new LocalLog(64);
+    private final LocalLog mHandoverLocalLog = new LocalLog(100);
 
     private int[] mAdministratorUids = new int[0];
 
@@ -473,14 +466,15 @@
     public static DataConnection makeDataConnection(Phone phone, int id, DcTracker dct,
                                                     DataServiceManager dataServiceManager,
                                                     DcTesterFailBringUpAll failBringUpAll,
-                                                    DcController dcc) {
+                                                    DcController dcc,
+                                                    boolean doAllocatePduSessionId) {
         String transportType = (dataServiceManager.getTransportType()
                 == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                 ? "C"   // Cellular
                 : "I";  // IWLAN
         DataConnection dc = new DataConnection(phone, transportType + "-"
                 + mInstanceNumber.incrementAndGet(), id, dct, dataServiceManager, failBringUpAll,
-                dcc);
+                dcc, doAllocatePduSessionId);
         dc.start();
         if (DBG) dc.log("Made " + dc.getName());
         return dc;
@@ -682,8 +676,6 @@
      */
     public void updateTrafficDescriptors(DataCallResponse response) {
         mTrafficDescriptors = response.getTrafficDescriptors();
-        mDcController.updateTrafficDescriptorsForCid(response.getId(),
-                response.getTrafficDescriptors());
     }
 
     @VisibleForTesting
@@ -750,9 +742,9 @@
             return;
         }
 
-        if (apn != null && apn.getMtuV4() != PhoneConstants.UNSET_MTU) {
-            lp.setMtu(apn.getMtuV4());
-            if (DBG) log("MTU set by APN to: " + apn.getMtuV4());
+        if (apn != null && apn.getMtu() != PhoneConstants.UNSET_MTU) {
+            lp.setMtu(apn.getMtu());
+            if (DBG) log("MTU set by APN to: " + apn.getMtu());
             return;
         }
 
@@ -767,7 +759,8 @@
     //***** Constructor (NOTE: uses dcc.getHandler() as its Handler)
     private DataConnection(Phone phone, String tagSuffix, int id,
                            DcTracker dct, DataServiceManager dataServiceManager,
-                           DcTesterFailBringUpAll failBringUpAll, DcController dcc) {
+                           DcTesterFailBringUpAll failBringUpAll, DcController dcc,
+                           boolean doAllocatePduSessionId) {
         super("DC-" + tagSuffix, dcc);
         mTagSuffix = tagSuffix;
         setLogRecSize(300);
@@ -786,7 +779,7 @@
         mDataRegState = mPhone.getServiceState().getDataRegistrationState();
         mIsSuspended = false;
         mDataCallSessionStats = new DataCallSessionStats(mPhone);
-        mDoAllocatePduSessionId = false;
+        mDoAllocatePduSessionId = doAllocatePduSessionId;
 
         int networkType = getNetworkType();
         mRilRat = ServiceState.networkTypeToRilRadioTechnology(networkType);
@@ -859,7 +852,7 @@
                 + "' APN='" + mApnSetting.getApnName()
                 + "' proxy='" + mApnSetting.getProxyAddressAsString()
                 + "' port='" + mApnSetting.getProxyPort() + "'");
-        ApnContext.requestLog(cp.mApnContext, "DataConnection.connect");
+        if (cp.mApnContext != null) cp.mApnContext.requestLog("DataConnection.connect");
 
         // Check if we should fake an error.
         if (mDcTesterFailBringUpAll.getDcFailBringUp().mCounter  > 0) {
@@ -889,10 +882,8 @@
         Message msg = obtainMessage(EVENT_SETUP_DATA_CONNECTION_DONE, cp);
         msg.obj = cp;
 
-        DataProfile dp = new DataProfile.Builder()
-                .setApnSetting(mApnSetting)
-                .setPreferred(cp.mIsPreferredApn)
-                .build();
+        DataProfile dp = DcTracker.createDataProfile(mApnSetting, cp.mProfileId,
+                cp.mIsPreferredApn);
 
         // We need to use the actual modem roaming state instead of the framework roaming state
         // here. This flag is only passed down to ril_service for picking the correct protocol (for
@@ -980,7 +971,6 @@
         }
 
         // setup data call for REQUEST_TYPE_NORMAL
-        mDoAllocatePduSessionId = mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
         allocatePduSessionId(psi -> {
             this.setPduSessionId(psi);
             mDataServiceManager.setupDataCall(
@@ -1002,7 +992,7 @@
     }
 
     private void allocatePduSessionId(Consumer<Integer> allocateCallback) {
-        if (mDoAllocatePduSessionId) {
+        if (getDoAllocatePduSessionId()) {
             Message msg = this.obtainMessage(EVENT_ALLOCATE_PDU_SESSION_ID);
             msg.obj = allocateCallback;
             mPhone.mCi.allocatePduSessionId(msg);
@@ -1177,7 +1167,7 @@
 
         String str = "tearDownData. mCid=" + mCid + ", reason=" + discReason;
         if (DBG) log(str);
-        ApnContext.requestLog(apnContext, str);
+        if (apnContext != null) apnContext.requestLog(str);
 
 
         //Needed to be final to work in a closure
@@ -1192,10 +1182,8 @@
     }
 
     private void releasePduSessionId(Runnable releaseCallback) {
-        // If the transport is IWLAN, and there is a valid PDU session id, also the data connection
-        // is not being handovered, we should release the pdu session id.
-        if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN
-                && mHandoverState == HANDOVER_STATE_IDLE
+        // If we are not in the middle of a handover and have a real pdu session id, then we release
+        if (mHandoverState != HANDOVER_STATE_BEING_TRANSFERRED
                 && this.getPduSessionId() != PDU_SESSION_ID_NOT_SET) {
             Message msg = this.obtainMessage(EVENT_RELEASE_PDU_SESSION_ID);
             msg.obj = releaseCallback;
@@ -1365,7 +1353,6 @@
         mHandoverFailureMode = DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN;
         mSliceInfo = null;
         mDefaultQos = null;
-        mDoAllocatePduSessionId = false;
         mQosBearerSessions.clear();
         mTrafficDescriptors.clear();
     }
@@ -1408,12 +1395,6 @@
             }
         } else if (cp.mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE
                 && mDcController.getActiveDcByCid(response.getId()) != null) {
-            if (!mDcController.getTrafficDescriptorsForCid(response.getId())
-                    .equals(response.getTrafficDescriptors())) {
-                if (DBG) log("Updating traffic descriptors: " + response.getTrafficDescriptors());
-                mDcController.getActiveDcByCid(response.getId()).updateTrafficDescriptors(response);
-                mDct.obtainMessage(DctConstants.EVENT_TRAFFIC_DESCRIPTORS_UPDATED).sendToTarget();
-            }
             if (DBG) log("DataConnection already exists for cid: " + response.getId());
             result = SetupResult.ERROR_DUPLICATE_CID;
             result.mFailCause = DataFailCause.DUPLICATE_CID;
@@ -1426,7 +1407,17 @@
         } else {
             if (DBG) log("onSetupConnectionCompleted received successful DataCallResponse");
             mCid = response.getId();
-            setPduSessionId(response.getPduSessionId());
+
+            if (response.getPduSessionId() != getPduSessionId()) {
+                if (getDoAllocatePduSessionId()) {
+                    loge("The pdu session id on DataCallResponse is different than the one "
+                            + "allocated.  response psi=" + response.getPduSessionId()
+                            + ", allocated psi=" + getPduSessionId());
+                } else {
+                    setPduSessionId(response.getPduSessionId());
+                }
+            }
+
             updatePcscfAddr(response);
             updateResponseFields(response);
             result = updateLinkProperty(response).setupResult;
@@ -1583,8 +1574,12 @@
     }
 
     private void updateLinkBandwidthsFromCarrierConfig(int rilRat) {
-        String ratName = DataConfigManager.getDataConfigNetworkType(
-                mPhone.getDisplayInfoController().getTelephonyDisplayInfo());
+        String ratName = ServiceState.rilRadioTechnologyToString(rilRat);
+        if (rilRat == ServiceState.RIL_RADIO_TECHNOLOGY_LTE && isNRConnected()) {
+            ratName = mPhone.getServiceState().getNrFrequencyRange()
+                    == ServiceState.FREQUENCY_RANGE_MMWAVE
+                    ? DctConstants.RAT_NAME_NR_NSA_MMWAVE : DctConstants.RAT_NAME_NR_NSA;
+        }
 
         if (DBG) log("updateLinkBandwidthsFromCarrierConfig: " + ratName);
 
@@ -1664,7 +1659,6 @@
             if (!uplinkUpdated) {
                 mUplinkBandwidth = values.second;
             }
-            mUplinkBandwidth = Math.min(mUplinkBandwidth, mDownlinkBandwidth);
         }
     }
 
@@ -1815,8 +1809,14 @@
      * @return True if this data connection supports enterprise use.
      */
     private boolean isEnterpriseUse() {
-        return  mApnContexts.keySet().stream().anyMatch(
-                ac -> ac.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE);
+        boolean enterpriseTrafficDescriptor = mTrafficDescriptors
+                .stream()
+                .anyMatch(td -> td.getOsAppId() != null && Arrays.equals(td.getOsAppId(),
+                        getEnterpriseOsAppId()));
+        boolean enterpriseApnContext = mApnContexts.keySet()
+                .stream()
+                .anyMatch(ac -> ac.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE);
+        return enterpriseTrafficDescriptor || enterpriseApnContext;
     }
 
     /**
@@ -1960,76 +1960,32 @@
             builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED);
         }
 
-        final int carrierServicePackageUid = getCarrierServicePackageUid();
-
-        // TODO(b/205736323): Owner and Admin UIDs currently come from separate data sources. Unify
-        //                    them, and remove ArrayUtils.contains() check.
-        if (carrierServicePackageUid != Process.INVALID_UID
-                && ArrayUtils.contains(mAdministratorUids, carrierServicePackageUid)) {
-            builder.setOwnerUid(carrierServicePackageUid);
-            builder.setAllowedUids(Collections.singleton(carrierServicePackageUid));
-        }
         builder.setAdministratorUids(mAdministratorUids);
 
         // Always start with NOT_VCN_MANAGED, then remove if VcnManager indicates this is part of a
         // VCN.
         builder.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
-        final VcnNetworkPolicyResult vcnPolicy = getVcnPolicy(builder.build());
-        if (!vcnPolicy.getNetworkCapabilities()
-                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)) {
+        if (isVcnManaged(builder.build())) {
             builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
         }
-        if (!vcnPolicy.getNetworkCapabilities()
-                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
-            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
-        }
 
         return builder.build();
     }
 
-    // TODO(b/205736323): Once TelephonyManager#getCarrierServicePackageNameForLogicalSlot() is
-    //                    plumbed to CarrierPrivilegesTracker's cache, query the cached UIDs.
-    private int getFirstUidForPackage(String pkgName) {
-        if (pkgName == null) {
-            return Process.INVALID_UID;
-        }
-
-        List<UserInfo> users = mPhone.getContext().getSystemService(UserManager.class).getUsers();
-        for (UserInfo user : users) {
-            int userId = user.getUserHandle().getIdentifier();
-            try {
-                PackageManager pm = mPhone.getContext().getPackageManager();
-
-                if (pm != null) {
-                    return pm.getPackageUidAsUser(pkgName, userId);
-                }
-            } catch (NameNotFoundException exception) {
-                // Didn't find package. Try other users
-                Rlog.i(
-                        "DataConnection",
-                        "Unable to find uid for package " + pkgName + " and user " + userId);
-            }
-        }
-        return Process.INVALID_UID;
-    }
-
-    private int getCarrierServicePackageUid() {
-        String pkgName =
-                mPhone.getContext()
-                        .getSystemService(TelephonyManager.class)
-                        .getCarrierServicePackageNameForLogicalSlot(mPhone.getPhoneId());
-
-        return getFirstUidForPackage(pkgName);
-    }
-
     /**
-     * Check if the this data network is VCN-managed.
+     * Returns whether the Network represented by this DataConnection is VCN-managed.
      *
-     * @param networkCapabilities The network capabilities of this data network.
-     * @return The VCN's policy for this DataNetwork.
+     * <p>Determining if the Network is VCN-managed requires polling VcnManager.
      */
-    private VcnNetworkPolicyResult getVcnPolicy(NetworkCapabilities networkCapabilities) {
-        return mVcnManager.applyVcnNetworkPolicy(networkCapabilities, getLinkProperties());
+    private boolean isVcnManaged(NetworkCapabilities networkCapabilities) {
+        VcnNetworkPolicyResult policyResult =
+                mVcnManager.applyVcnNetworkPolicy(networkCapabilities, getLinkProperties());
+
+        // if the Network does have capability NOT_VCN_MANAGED, return false to indicate it's not
+        // VCN-managed
+        return !policyResult
+                .getNetworkCapabilities()
+                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
     }
 
     /** @return {@code true} if validation is required, {@code false} otherwise. */
@@ -2145,9 +2101,31 @@
                     }
                 }
 
+                boolean useLowerMtuValue = false;
+                CarrierConfigManager configManager = (CarrierConfigManager)
+                        mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+                if (configManager != null) {
+                    PersistableBundle bundle = configManager.getConfigForSubId(mSubId);
+                    if (bundle != null) {
+                        useLowerMtuValue = bundle.getBoolean(
+                                CarrierConfigManager.KEY_USE_LOWER_MTU_VALUE_IF_BOTH_RECEIVED)
+                                && response.getMtuV4() != PhoneConstants.UNSET_MTU
+                                && response.getMtuV6() != PhoneConstants.UNSET_MTU;
+                    }
+                }
+
+                int interfaceMtu = response.getMtu();
                 for (InetAddress gateway : response.getGatewayAddresses()) {
                     int mtu = gateway instanceof java.net.Inet6Address ? response.getMtuV6()
                             : response.getMtuV4();
+                    if (useLowerMtuValue) {
+                        mtu = Math.min(response.getMtuV4(), response.getMtuV6());
+                        // Never set an MTU below MIN_V6_MTU on a network that has IPv6.
+                        if (mtu < MIN_V6_MTU) {
+                            mtu = MIN_V6_MTU;
+                        }
+                        interfaceMtu = mtu;
+                    }
                     // Allow 0.0.0.0 or :: as a gateway;
                     // this indicates a point-to-point interface.
                     linkProperties.addRoute(new RouteInfo(null, gateway, null,
@@ -2157,7 +2135,7 @@
                 // set interface MTU
                 // this may clobber the setting read from the APN db, but that's ok
                 // TODO: remove once LinkProperties#setMtu is deprecated
-                linkProperties.setMtu(response.getMtu());
+                linkProperties.setMtu(interfaceMtu);
 
                 result = SetupResult.SUCCESS;
             } catch (UnknownHostException e) {
@@ -2180,6 +2158,10 @@
         return result;
     }
 
+    private boolean getDoAllocatePduSessionId() {
+        return mDoAllocatePduSessionId;
+    }
+
     /**
      * Initialize connection, this will fail if the
      * apnSettings are not compatible.
@@ -2344,8 +2326,7 @@
                                 + " regState=" + ServiceState.rilServiceStateToString(mDataRegState)
                                 + " RAT=" + ServiceState.rilRadioTechnologyToString(mRilRat));
                     }
-                    mDataCallSessionStats.onDrsOrRatChanged(
-                            ServiceState.rilRadioTechnologyToNetworkType(mRilRat));
+                    mDataCallSessionStats.onDrsOrRatChanged(mRilRat);
                     break;
 
                 case EVENT_START_HANDOVER:  //calls startHandover()
@@ -2662,11 +2643,9 @@
             // this connection are going away.
             mRestrictedNetworkOverride = shouldRestrictNetwork();
 
-            CarrierPrivilegesTracker carrierPrivTracker = mPhone.getCarrierPrivilegesTracker();
-            if (carrierPrivTracker != null) {
-                carrierPrivTracker.registerCarrierPrivilegesListener(
+            mPhone.getCarrierPrivilegesTracker()
+                    .registerCarrierPrivilegesListener(
                             getHandler(), EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED, null);
-            }
             notifyDataConnectionState();
             mDataCallSessionStats.onSetupDataCall(apnTypeBitmask);
         }
@@ -2701,8 +2680,9 @@
                         log("DcActivatingState onSetupConnectionCompleted result=" + result
                                 + " dc=" + DataConnection.this);
                     }
-                    ApnContext.requestLog(
-                            cp.mApnContext, "onSetupConnectionCompleted result=" + result);
+                    if (cp.mApnContext != null) {
+                        cp.mApnContext.requestLog("onSetupConnectionCompleted result=" + result);
+                    }
                     switch (result) {
                         case SUCCESS:
                             // All is well
@@ -2731,7 +2711,7 @@
                                     + DataFailCause.toString(result.mFailCause)
                                     + " retry=" + retry;
                             if (DBG) log(logStr);
-                            ApnContext.requestLog(cp.mApnContext, logStr);
+                            if (cp.mApnContext != null) cp.mApnContext.requestLog(logStr);
                             mInactiveState.setEnterNotificationParams(cp, result.mFailCause,
                                     DataCallResponse.HANDOVER_FAILURE_MODE_UNKNOWN);
                             transitionTo(mInactiveState);
@@ -2774,7 +2754,7 @@
                                     + " isPermanentFailure=" +
                                     mDct.isPermanentFailure(result.mFailCause);
                             if (DBG) log(str);
-                            ApnContext.requestLog(cp.mApnContext, str);
+                            if (cp.mApnContext != null) cp.mApnContext.requestLog(str);
 
                             // Save the cause. DcTracker.onDataSetupComplete will check this
                             // failure cause and determine if we need to retry this APN later
@@ -2794,8 +2774,7 @@
                     }
                     retVal = HANDLED;
                     mDataCallSessionStats
-                            .onSetupDataCallResponse(dataCallResponse,
-                                    ServiceState.rilRadioTechnologyToNetworkType(cp.mRilRat),
+                            .onSetupDataCallResponse(dataCallResponse, cp.mRilRat,
                                     getApnTypeBitmask(), mApnSetting.getProtocol(),
                                     result.mFailCause);
                     break;
@@ -3011,10 +2990,7 @@
 
             mVcnManager.removeVcnNetworkPolicyChangeListener(mVcnPolicyChangeListener);
 
-            CarrierPrivilegesTracker carrierPrivTracker = mPhone.getCarrierPrivilegesTracker();
-            if (carrierPrivTracker != null) {
-                carrierPrivTracker.unregisterCarrierPrivilegesListener(getHandler());
-            }
+            mPhone.getCarrierPrivilegesTracker().unregisterCarrierPrivilegesListener(getHandler());
         }
 
         @Override
@@ -3124,8 +3100,7 @@
                         mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
                     }
                     retVal = HANDLED;
-                    mDataCallSessionStats.onDrsOrRatChanged(
-                            ServiceState.rilRadioTechnologyToNetworkType(mRilRat));
+                    mDataCallSessionStats.onDrsOrRatChanged(mRilRat);
                     break;
                 }
                 case EVENT_NR_FREQUENCY_CHANGED:
@@ -3292,8 +3267,7 @@
                     } else {
                         log("Keepalive Stop Requested for handle=" + handle);
                         mNetworkAgent.keepaliveTracker.handleKeepaliveStatus(
-                                new KeepaliveStatus(
-                                        handle, KeepaliveStatus.STATUS_INACTIVE));
+                                new KeepaliveStatus(handle, KeepaliveStatus.STATUS_INACTIVE));
                     }
                     retVal = HANDLED;
                     break;
@@ -3439,7 +3413,7 @@
                             + mApnContexts.size();
 
                     if (DBG) log(str);
-                    ApnContext.requestLog(dp.mApnContext, str);
+                    if (dp.mApnContext != null) dp.mApnContext.requestLog(str);
 
                     // Clear out existing qos sessions
                     updateQosParameters(null);
@@ -3492,7 +3466,7 @@
                         String str = "DcDisconnectionErrorCreatingConnection" +
                                 " msg.what=EVENT_DEACTIVATE_DONE";
                         if (DBG) log(str);
-                        ApnContext.requestLog(cp.mApnContext, str);
+                        if (cp.mApnContext != null) cp.mApnContext.requestLog(str);
 
                         // Transition to inactive but send notifications after
                         // we've entered the mInactive state.
@@ -3725,7 +3699,7 @@
         }
     }
 
-    /** Sets the {@link DataCallSessionStats} mock for this data connection during unit testing. */
+    /** Sets the {@link DataCallSessionStats} mock for this phone ID during unit testing. */
     @VisibleForTesting
     public void setDataCallSessionStats(DataCallSessionStats dataCallSessionStats) {
         mDataCallSessionStats = dataCallSessionStats;
diff --git a/src/java/com/android/internal/telephony/data/DataEnabledOverride.java b/src/java/com/android/internal/telephony/dataconnection/DataEnabledOverride.java
similarity index 98%
rename from src/java/com/android/internal/telephony/data/DataEnabledOverride.java
rename to src/java/com/android/internal/telephony/dataconnection/DataEnabledOverride.java
index e639ba6..ce04e88 100644
--- a/src/java/com/android/internal/telephony/data/DataEnabledOverride.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataEnabledOverride.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2021 The Android Open Source Project
+ * Copyright 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.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony.dataconnection;
 
 import android.annotation.IntDef;
 import android.annotation.NonNull;
@@ -31,7 +31,7 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.SubscriptionController;
-import com.android.internal.telephony.data.DataEnabledOverride.OverrideConditions.Condition;
+import com.android.internal.telephony.dataconnection.DataEnabledOverride.OverrideConditions.Condition;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
index 305b4a8..734dfff 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataEnabledSettings.java
@@ -42,7 +42,6 @@
 import com.android.internal.telephony.MultiSimSettingController;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.SubscriptionController;
-import com.android.internal.telephony.data.DataEnabledOverride;
 import com.android.telephony.Rlog;
 
 import java.io.FileDescriptor;
@@ -136,7 +135,7 @@
     private final RegistrantList mOverallDataEnabledOverrideChangedRegistrants =
             new RegistrantList();
 
-    private final LocalLog mSettingChangeLocalLog = new LocalLog(32);
+    private final LocalLog mSettingChangeLocalLog = new LocalLog(50);
 
     private DataEnabledOverride mDataEnabledOverride;
 
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java b/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
index d006004..3ba577a 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataServiceManager.java
@@ -149,7 +149,7 @@
             String message = "Data service " + mLastBoundPackageName +  " for transport type "
                     + AccessNetworkConstants.transportTypeToString(mTransportType) + " died.";
             loge(message);
-            AnomalyReporter.reportAnomaly(mAnomalyUUID, message, mPhone.getCarrierId());
+            AnomalyReporter.reportAnomaly(mAnomalyUUID, message);
         }
     }
 
@@ -184,7 +184,7 @@
     private void revokePermissionsFromUnusedDataServices() {
         // Except the current data services from having their permissions removed.
         Set<String> dataServices = getAllDataServicePackageNames();
-        for (int transportType : mPhone.getAccessNetworksManager().getAvailableTransports()) {
+        for (int transportType : mPhone.getTransportManager().getAvailableTransports()) {
             dataServices.remove(getDataServicePackageName(transportType));
         }
 
@@ -329,7 +329,6 @@
             sendCompleteMessage(msg, resultCode);
         }
 
-        @Override
         public void onApnUnthrottled(String apn) {
             if (apn != null) {
                 mApnUnthrottledRegistrants.notifyRegistrants(
@@ -338,16 +337,6 @@
                 loge("onApnUnthrottled: apn is null");
             }
         }
-
-        @Override
-        public void onDataProfileUnthrottled(DataProfile dataProfile) {
-            if (dataProfile != null) {
-                mApnUnthrottledRegistrants.notifyRegistrants(
-                        new AsyncResult(null, dataProfile, null));
-            } else {
-                loge("onDataProfileUnthrottled: dataProfile is null");
-            }
-        }
     }
 
     /**
@@ -381,7 +370,6 @@
         } catch (PackageManager.NameNotFoundException e) {
             loge("Package name not found: " + e.getMessage());
         }
-
         PhoneConfigurationManager.registerForMultiSimConfigChange(
                 this, EVENT_BIND_DATA_SERVICE, null);
 
@@ -415,7 +403,7 @@
         // Using fixed UUID to avoid duplicate bugreport notification
         AnomalyReporter.reportAnomaly(
                 UUID.fromString("f5d5cbe6-9bd6-4009-b764-42b1b649b1de"),
-                message, mPhone.getCarrierId());
+                message);
     }
 
     private void unbindDataService() {
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataThrottler.java b/src/java/com/android/internal/telephony/dataconnection/DataThrottler.java
index 4a465d2..47b7d20 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataThrottler.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataThrottler.java
@@ -192,18 +192,9 @@
 
         List<ThrottleStatus> changedStatuses = new ArrayList<>();
         while (apnTypes != 0) {
-            int apnType;
-            // Due to an API mistake of ApnSetting.TYPE_DEFAULT (which combines default and hipri 
-            // bit), we need to do special handling here.
-            if ((apnTypes & ApnSetting.TYPE_DEFAULT) == ApnSetting.TYPE_DEFAULT) {
-                apnType = ApnSetting.TYPE_DEFAULT;
-                apnTypes &= ~ApnSetting.TYPE_DEFAULT;
-            } else {
-                //Extract the least significant bit.
-                apnType = apnTypes & -apnTypes;
-                //Remove the least significant bit.
-                apnTypes &= apnTypes - 1;
-            }
+
+            //Extract the least significant bit.
+            int apnType = apnTypes & -apnTypes;
 
             //Update the apn throttle status
             ThrottleStatus newStatus = createStatus(apnType, retryElapsedTime, newRequestType);
@@ -218,6 +209,9 @@
                 //Put the new status in the temp space
                 mThrottleStatus.put(apnType, newStatus);
             }
+
+            //Remove the least significant bit.
+            apnTypes &= apnTypes - 1;
         }
 
         if (changedStatuses.size() > 0) {
@@ -238,6 +232,12 @@
      */
     @ElapsedRealtimeLong
     public long getRetryTime(@ApnType int apnType) {
+        // This is the workaround to handle the mistake that
+        // ApnSetting.TYPE_DEFAULT = ApnTypes.DEFAULT | ApnTypes.HIPRI.
+        if (apnType == ApnSetting.TYPE_DEFAULT) {
+            apnType &= ~(ApnSetting.TYPE_HIPRI);
+        }
+
         ThrottleStatus status = mThrottleStatus.get(apnType);
         if (status != null) {
             if (status.getThrottleType() == ThrottleStatus.THROTTLE_TYPE_NONE) {
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcController.java b/src/java/com/android/internal/telephony/dataconnection/DcController.java
index c34157e..2156e66 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcController.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcController.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.dataconnection;
 
+import android.annotation.IntDef;
 import android.hardware.radio.V1_4.DataConnActiveStatus;
 import android.net.LinkAddress;
 import android.os.AsyncResult;
@@ -24,11 +25,9 @@
 import android.os.Message;
 import android.os.RegistrantList;
 import android.telephony.AccessNetworkConstants;
-import android.telephony.CarrierConfigManager;
 import android.telephony.DataFailCause;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.DataCallResponse;
-import android.telephony.data.TrafficDescriptor;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.DctConstants;
@@ -42,6 +41,8 @@
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -56,6 +57,24 @@
     private static final boolean DBG = true;
     private static final boolean VDBG = false;
 
+    /** Physical link state unknown */
+    public static final int PHYSICAL_LINK_UNKNOWN = 0;
+
+    /** Physical link state inactive (i.e. RRC idle) */
+    public static final int PHYSICAL_LINK_NOT_ACTIVE = 1;
+
+    /** Physical link state active (i.e. RRC connected) */
+    public static final int PHYSICAL_LINK_ACTIVE = 2;
+
+    /** @hide */
+    @IntDef(prefix = { "PHYSICAL_LINK_" }, value = {
+            PHYSICAL_LINK_UNKNOWN,
+            PHYSICAL_LINK_NOT_ACTIVE,
+            PHYSICAL_LINK_ACTIVE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PhysicalLinkState{}
+
     private final Phone mPhone;
     private final DcTracker mDct;
     private final String mTag;
@@ -67,20 +86,16 @@
     final ArrayList<DataConnection> mDcListAll = new ArrayList<>();
     // @GuardedBy("mDcListAll")
     private final HashMap<Integer, DataConnection> mDcListActiveByCid = new HashMap<>();
-    // @GuardedBy("mTrafficDescriptorsByCid")
-    private final HashMap<Integer, List<TrafficDescriptor>> mTrafficDescriptorsByCid =
-            new HashMap<>();
 
     /**
-     * Aggregated physical link status from all data connections. This reflects the device's RRC
+     * Aggregated physical link state from all data connections. This reflects the device's RRC
      * connection state.
-     * If {@link CarrierConfigManager#KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true,
+     * If {@link CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true,
      * then This reflects "internet data connection" instead of RRC state.
      */
-    private @DataCallResponse.LinkStatus int mPhysicalLinkStatus =
-            DataCallResponse.LINK_STATUS_UNKNOWN;
+    private @PhysicalLinkState int mPhysicalLinkState = PHYSICAL_LINK_UNKNOWN;
 
-    private RegistrantList mPhysicalLinkStatusChangedRegistrants = new RegistrantList();
+    private RegistrantList mPhysicalLinkStateChangedRegistrants = new RegistrantList();
 
     /**
      * Constructor.
@@ -123,9 +138,6 @@
             mDcListActiveByCid.remove(dc.mCid);
             mDcListAll.remove(dc);
         }
-        synchronized (mTrafficDescriptorsByCid) {
-            mTrafficDescriptorsByCid.remove(dc.mCid);
-        }
     }
 
     public void addActiveDcByCid(DataConnection dc) {
@@ -135,7 +147,6 @@
         synchronized (mDcListAll) {
             mDcListActiveByCid.put(dc.mCid, dc);
         }
-        updateTrafficDescriptorsForCid(dc.mCid, dc.getTrafficDescriptors());
     }
 
     DataConnection getActiveDcByCid(int cid) {
@@ -151,9 +162,6 @@
                 log("removeActiveDcByCid removedDc=null dc=" + dc);
             }
         }
-        synchronized (mTrafficDescriptorsByCid) {
-            mTrafficDescriptorsByCid.remove(dc.mCid);
-        }
     }
 
     boolean isDefaultDataActive() {
@@ -164,18 +172,6 @@
         }
     }
 
-    List<TrafficDescriptor> getTrafficDescriptorsForCid(int cid) {
-        synchronized (mTrafficDescriptorsByCid) {
-            return mTrafficDescriptorsByCid.get(cid);
-        }
-    }
-
-    void updateTrafficDescriptorsForCid(int cid, List<TrafficDescriptor> tds) {
-        synchronized (mTrafficDescriptorsByCid) {
-            mTrafficDescriptorsByCid.put(cid, tds);
-        }
-    }
-
     @Override
     public void handleMessage(Message msg) {
         AsyncResult ar;
@@ -211,29 +207,19 @@
         }
 
         // Create hashmap of cid to DataCallResponse
-        HashMap<Integer, DataCallResponse> dataCallResponseListByCid = new HashMap<>();
+        HashMap<Integer, DataCallResponse> dataCallResponseListByCid =
+                new HashMap<Integer, DataCallResponse>();
         for (DataCallResponse dcs : dcsList) {
             dataCallResponseListByCid.put(dcs.getId(), dcs);
         }
 
-        // Add a DC that is active but not in the dcsList to the list of DC's to retry
-        ArrayList<DataConnection> dcsToRetry = new ArrayList<>();
+        // Add a DC that is active but not in the
+        // dcsList to the list of DC's to retry
+        ArrayList<DataConnection> dcsToRetry = new ArrayList<DataConnection>();
         for (DataConnection dc : dcListActiveByCid.values()) {
-            DataCallResponse response = dataCallResponseListByCid.get(dc.mCid);
-            if (response == null) {
+            if (dataCallResponseListByCid.get(dc.mCid) == null) {
                 if (DBG) log("onDataStateChanged: add to retry dc=" + dc);
                 dcsToRetry.add(dc);
-            } else {
-                List<TrafficDescriptor> oldTds = getTrafficDescriptorsForCid(dc.mCid);
-                List<TrafficDescriptor> newTds = response.getTrafficDescriptors();
-                if (!oldTds.equals(newTds)) {
-                    if (DBG) {
-                        log("onDataStateChanged: add to retry due to TD changed dc=" + dc
-                                + ", oldTds=" + oldTds + ", newTds=" + newTds);
-                    }
-                    updateTrafficDescriptorsForCid(dc.mCid, newTds);
-                    dcsToRetry.add(dc);
-                }
             }
         }
         if (DBG) log("onDataStateChanged: dcsToRetry=" + dcsToRetry);
@@ -321,15 +307,16 @@
                                             result.oldLp, result.newLp)) {
                                 // If the same address type was removed and
                                 // added we need to cleanup
-                                CompareOrUpdateResult<Integer, LinkAddress> car
-                                    = new CompareOrUpdateResult(
-                                  result.oldLp != null ?
-                                    result.oldLp.getLinkAddresses() : null,
-                                  result.newLp != null ?
-                                    result.newLp.getLinkAddresses() : null,
-                                  (la) -> Objects.hash(((LinkAddress)la).getAddress(),
-                                                       ((LinkAddress)la).getPrefixLength(),
-                                                       ((LinkAddress)la).getScope()));
+                                CompareOrUpdateResult<Integer, LinkAddress> car =
+                                        new CompareOrUpdateResult(
+                                                result.oldLp != null
+                                                        ? result.oldLp.getLinkAddresses() : null,
+                                                result.newLp != null
+                                                        ? result.newLp.getLinkAddresses() : null,
+                                                (la) -> Objects.hash(((LinkAddress) la)
+                                                                .getAddress(),
+                                                        ((LinkAddress) la).getPrefixLength(),
+                                                        ((LinkAddress) la).getScope()));
                                 if (DBG) {
                                     log("onDataStateChanged: oldLp=" + result.oldLp
                                             + " newLp=" + result.newLp + " car=" + car);
@@ -380,23 +367,22 @@
 
         if (mDataServiceManager.getTransportType()
                 == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
-            boolean isPhysicalLinkStatusFocusingOnInternetData =
+            boolean isPhysicalLinkStateFocusingOnInternetData =
                     mDct.getLteEndcUsingUserDataForIdleDetection();
-            int physicalLinkStatus =
-                    (isPhysicalLinkStatusFocusingOnInternetData
+            int physicalLinkState =
+                    (isPhysicalLinkStateFocusingOnInternetData
                             ? isInternetDataCallActive : isAnyDataCallActive)
-                            ? DataCallResponse.LINK_STATUS_ACTIVE
-                            : DataCallResponse.LINK_STATUS_DORMANT;
-            if (mPhysicalLinkStatus != physicalLinkStatus) {
-                mPhysicalLinkStatus = physicalLinkStatus;
-                mPhysicalLinkStatusChangedRegistrants.notifyResult(mPhysicalLinkStatus);
+                            ? PHYSICAL_LINK_ACTIVE : PHYSICAL_LINK_NOT_ACTIVE;
+            if (mPhysicalLinkState != physicalLinkState) {
+                mPhysicalLinkState = physicalLinkState;
+                mPhysicalLinkStateChangedRegistrants.notifyResult(mPhysicalLinkState);
             }
             if (isAnyDataCallDormant && !isAnyDataCallActive) {
                 // There is no way to indicate link activity per APN right now. So
                 // Link Activity will be considered dormant only when all data calls
                 // are dormant.
                 // If a single data call is in dormant state and none of the data
-                // calls are active broadcast overall link status as dormant.
+                // calls are active broadcast overall link state as dormant.
                 if (DBG) {
                     log("onDataStateChanged: Data activity DORMANT. stopNetStatePoll");
                 }
@@ -433,24 +419,24 @@
     }
 
     /**
-     * Register for physical link status (i.e. RRC state) changed event.
-     * if {@link CarrierConfigManager#KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true,
-     * then physical link status is focusing on "internet data connection" instead of RRC state.
+     * Register for physical link state (i.e. RRC state) changed event.
+     * if {@link CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true,
+     * then physical link state is focusing on "internet data connection" instead of RRC state.
      * @param h The handler
      * @param what The event
      */
     @VisibleForTesting
-    public void registerForPhysicalLinkStatusChanged(Handler h, int what) {
-        mPhysicalLinkStatusChangedRegistrants.addUnique(h, what, null);
+    public void registerForPhysicalLinkStateChanged(Handler h, int what) {
+        mPhysicalLinkStateChangedRegistrants.addUnique(h, what, null);
     }
 
     /**
-     * Unregister from physical link status (i.e. RRC state) changed event.
+     * Unregister from physical link state (i.e. RRC state) changed event.
      *
      * @param h The previously registered handler
      */
-    void unregisterForPhysicalLinkStatusChanged(Handler h) {
-        mPhysicalLinkStatusChangedRegistrants.remove(h);
+    void unregisterForPhysicalLinkStateChanged(Handler h) {
+        mPhysicalLinkStateChangedRegistrants.remove(h);
     }
 
     private void log(String s) {
@@ -463,15 +449,9 @@
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder();
         synchronized (mDcListAll) {
-            sb.append("mDcListAll=").append(mDcListAll)
-                    .append(" mDcListActiveByCid=").append(mDcListActiveByCid);
+            return "mDcListAll=" + mDcListAll + " mDcListActiveByCid=" + mDcListActiveByCid;
         }
-        synchronized (mTrafficDescriptorsByCid) {
-            sb.append("mTrafficDescriptorsByCid=").append(mTrafficDescriptorsByCid);
-        }
-        return sb.toString();
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -480,8 +460,5 @@
             pw.println(" mDcListAll=" + mDcListAll);
             pw.println(" mDcListActiveByCid=" + mDcListActiveByCid);
         }
-        synchronized (mTrafficDescriptorsByCid) {
-            pw.println(" mTrafficDescriptorsByCid=" + mTrafficDescriptorsByCid);
-        }
     }
 }
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java b/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
index c6def34..ab04bc1 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
@@ -29,7 +29,6 @@
 import android.net.QosSessionAttributes;
 import android.net.SocketKeepalive;
 import android.net.Uri;
-import android.os.Handler;
 import android.os.Message;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.TransportType;
@@ -38,18 +37,16 @@
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
+import android.telephony.data.NrQosSessionAttributes;
 import android.telephony.data.QosBearerSession;
+import android.util.ArrayMap;
 import android.util.LocalLog;
 import android.util.SparseArray;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.DctConstants;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.SlidingWindowEventCounter;
-import com.android.internal.telephony.data.KeepaliveStatus;
-import com.android.internal.telephony.data.NotifyQosSessionInterface;
-import com.android.internal.telephony.data.QosCallbackTracker;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.telephony.Rlog;
@@ -62,7 +59,6 @@
 import java.util.Map;
 import java.util.Objects;
 import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.concurrent.TimeUnit;
@@ -77,15 +73,13 @@
  * {@link DataConnection} so for a short window of time this object might be accessed by two
  * different {@link DataConnection}. Thus each method in this class needs to be synchronized.
  */
-public class DcNetworkAgent extends NetworkAgent implements NotifyQosSessionInterface {
+public class DcNetworkAgent extends NetworkAgent {
     private final String mTag;
 
     private final int mId;
 
     private final Phone mPhone;
 
-    private final Handler mHandler;
-
     private int mTransportType;
 
     private NetworkCapabilities mNetworkCapabilities;
@@ -98,18 +92,15 @@
 
     private DataConnection mDataConnection;
 
-    private final LocalLog mNetCapsLocalLog = new LocalLog(32);
+    private final LocalLog mNetCapsLocalLog = new LocalLog(50);
 
     // For interface duplicate detection. Key is the net id, value is the interface name in string.
-    private static Map<Integer, String> sInterfaceNames = new ConcurrentHashMap<>();
+    private static Map<Integer, String> sInterfaceNames = new ArrayMap<>();
 
     private static final long NETWORK_UNWANTED_ANOMALY_WINDOW_MS = TimeUnit.MINUTES.toMillis(5);
     private static final int NETWORK_UNWANTED_ANOMALY_NUM_OCCURRENCES =  12;
 
-    private static final int EVENT_UNWANTED_TIMEOUT = 1;
-
-    @VisibleForTesting
-    public DcNetworkAgent(DataConnection dc, Phone phone, int score, NetworkAgentConfig config,
+    DcNetworkAgent(DataConnection dc, Phone phone, int score, NetworkAgentConfig config,
             NetworkProvider networkProvider, int transportType) {
         super(phone.getContext(), dc.getHandler().getLooper(), "DcNetworkAgent",
                 dc.getNetworkCapabilities(), dc.getLinkProperties(), score, config,
@@ -118,18 +109,6 @@
         mId = getNetwork().getNetId();
         mTag = "DcNetworkAgent" + "-" + mId;
         mPhone = phone;
-        mHandler = new Handler(dc.getHandler().getLooper()) {
-            @Override
-            public void handleMessage(Message msg) {
-                if (msg.what == EVENT_UNWANTED_TIMEOUT) {
-                    loge("onNetworkUnwanted timed out. Perform silent de-register.");
-                    logd("Unregister from connectivity service. " + sInterfaceNames.get(mId)
-                            + " removed.");
-                    sInterfaceNames.remove(mId);
-                    DcNetworkAgent.this.unregister();
-                }
-            }
-        };
         mNetworkCapabilities = dc.getNetworkCapabilities();
         mTransportType = transportType;
         mDataConnection = dc;
@@ -140,7 +119,7 @@
         } else {
             loge("The connection does not have a valid link properties.");
         }
-        mQosCallbackTracker = new QosCallbackTracker(this, mPhone);
+        mQosCallbackTracker = new QosCallbackTracker(this);
     }
 
     private @NetworkType int getNetworkType() {
@@ -166,7 +145,7 @@
                 // Using fixed UUID to avoid duplicate bugreport notification
                 AnomalyReporter.reportAnomaly(
                         UUID.fromString("02f3d3f6-4613-4415-b6cb-8d92c8a938a6"),
-                        message, mPhone.getCarrierId());
+                        message);
                 return;
             }
         }
@@ -222,7 +201,6 @@
 
     @Override
     public synchronized void onNetworkUnwanted() {
-        mHandler.sendEmptyMessageDelayed(EVENT_UNWANTED_TIMEOUT, TimeUnit.SECONDS.toMillis(30));
         trackNetworkUnwanted();
         if (mDataConnection == null) {
             loge("onNetworkUnwanted found called on no-owner DcNetworkAgent!");
@@ -252,7 +230,7 @@
         if (sNetworkUnwantedCounter.addOccurrence()) {
             AnomalyReporter.reportAnomaly(
                     UUID.fromString("3f578b5c-64e9-11eb-ae93-0242ac130002"),
-                    "Network Unwanted called 12 times in 5 minutes.", mPhone.getCarrierId());
+                    "Network Unwanted called 12 times in 5 minutes.");
         }
     }
 
@@ -376,7 +354,6 @@
     public synchronized void unregister(DataConnection dc) {
         if (!isOwned(dc, "unregister")) return;
 
-        mHandler.removeMessages(EVENT_UNWANTED_TIMEOUT);
         logd("Unregister from connectivity service. " + sInterfaceNames.get(mId) + " removed.");
         sInterfaceNames.remove(mId);
         super.unregister();
@@ -436,13 +413,11 @@
         mQosCallbackExecutor.execute(() -> mQosCallbackTracker.updateSessions(qosBearerSessions));
     }
 
-    @Override
     public void notifyQosSessionAvailable(final int qosCallbackId, final int sessionId,
             @NonNull final QosSessionAttributes attributes) {
         super.sendQosSessionAvailable(qosCallbackId, sessionId, attributes);
     }
 
-    @Override
     public void notifyQosSessionLost(final int qosCallbackId,
             final int sessionId, final int qosSessionType) {
         super.sendQosSessionLost(qosCallbackId, sessionId, qosSessionType);
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTesterDeactivateAll.java b/src/java/com/android/internal/telephony/dataconnection/DcTesterDeactivateAll.java
index 11a0ae6..f4b26b6 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTesterDeactivateAll.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTesterDeactivateAll.java
@@ -78,8 +78,7 @@
             filter.addAction(mPhone.getActionDetached());
             log("register for intent action=" + mPhone.getActionDetached());
 
-            phone.getContext().registerReceiver(sIntentReceiver, filter, null, handler,
-                    Context.RECEIVER_EXPORTED);
+            phone.getContext().registerReceiver(sIntentReceiver, filter, null, handler);
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTesterFailBringUpAll.java b/src/java/com/android/internal/telephony/dataconnection/DcTesterFailBringUpAll.java
index 788da29..ba07e12 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTesterFailBringUpAll.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTesterFailBringUpAll.java
@@ -89,8 +89,7 @@
             filter.addAction(mPhone.getActionAttached());
             log("register for intent action=" + mPhone.getActionAttached());
 
-            phone.getContext().registerReceiver(mIntentReceiver, filter, null, handler,
-                    Context.RECEIVER_EXPORTED);
+            phone.getContext().registerReceiver(mIntentReceiver, filter, null, handler);
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
old mode 100755
new mode 100644
index 28f69dc..5bfe15b
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -74,6 +74,7 @@
 import android.telephony.Annotation.ApnType;
 import android.telephony.Annotation.DataFailureCause;
 import android.telephony.Annotation.NetworkType;
+import android.telephony.AnomalyReporter;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellLocation;
 import android.telephony.DataFailCause;
@@ -93,7 +94,6 @@
 import android.telephony.data.DataCallResponse;
 import android.telephony.data.DataCallResponse.HandoverFailureMode;
 import android.telephony.data.DataProfile;
-import android.telephony.data.ThrottleStatus;
 import android.telephony.gsm.GsmCellLocation;
 import android.text.TextUtils;
 import android.util.EventLog;
@@ -112,12 +112,11 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.PhoneSwitcher;
 import com.android.internal.telephony.RILConstants;
 import com.android.internal.telephony.RetryManager;
 import com.android.internal.telephony.SettingsObserver;
 import com.android.internal.telephony.SubscriptionInfoUpdater;
-import com.android.internal.telephony.data.DataConfigManager;
-import com.android.internal.telephony.data.PhoneSwitcher;
 import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataAllowedReasonType;
 import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
 import com.android.internal.telephony.dataconnection.DataEnabledSettings.DataEnabledChangedReason;
@@ -142,6 +141,7 @@
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Set;
+import java.util.UUID;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -211,14 +211,14 @@
     public static final int RELEASE_TYPE_HANDOVER = 3;
 
     /** The extras for handover completion message */
-    public static final String DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST = "extra_network_request";
-    public static final String DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE = "extra_transport_type";
-    public static final String DATA_COMPLETE_MSG_EXTRA_SUCCESS = "extra_success";
+    static final String DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST = "extra_network_request";
+    static final String DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE = "extra_transport_type";
+    static final String DATA_COMPLETE_MSG_EXTRA_SUCCESS = "extra_success";
     /**
      * The flag indicates whether after handover failure, the data connection should remain on the
      * original transport.
      */
-    public static final String DATA_COMPLETE_MSG_EXTRA_HANDOVER_FAILURE_FALLBACK =
+    static final String DATA_COMPLETE_MSG_EXTRA_HANDOVER_FAILURE_FALLBACK =
             "extra_handover_failure_fallback";
 
     private final String mLogTag;
@@ -336,8 +336,8 @@
 
     private AsyncChannel mReplyAc = new AsyncChannel();
 
-    private final LocalLog mDataRoamingLeakageLog = new LocalLog(32);
-    private final LocalLog mApnSettingsInitializationLog = new LocalLog(32);
+    private final LocalLog mDataRoamingLeakageLog = new LocalLog(50);
+    private final LocalLog mApnSettingsInitializationLog = new LocalLog(50);
 
     /* 5G connection reevaluation watchdog alarm constants */
     private long mWatchdogTimeMs = 1000 * 60 * 60;
@@ -352,11 +352,14 @@
     private boolean mNrSaSub6Unmetered = false;
     private boolean mNrNsaRoamingUnmetered = false;
 
-    // it effect the PhysicalLinkStatusChanged
+    // it effect the PhysicalLinkStateChanged
     private boolean mLteEndcUsingUserDataForRrcDetection = false;
 
+    // stats per data call recovery event
+    private DataStallRecoveryStats mDataStallRecoveryStats;
+
     /* List of SubscriptionPlans, updated when initialized and when plans are changed. */
-    private List<SubscriptionPlan> mSubscriptionPlans = new ArrayList<>();
+    private List<SubscriptionPlan> mSubscriptionPlans = null;
     /* List of network types an unmetered override applies to, set by onSubscriptionOverride
      * and cleared when the device is rebooted or the override expires. */
     private List<Integer> mUnmeteredNetworkTypes = null;
@@ -443,19 +446,6 @@
         }
     };
 
-    private class ThrottleStatusChangedCallback implements DataThrottler.Callback {
-        @Override
-        public void onThrottleStatusChanged(List<ThrottleStatus> throttleStatuses) {
-            for (ThrottleStatus status : throttleStatuses) {
-                if (status.getThrottleType() == ThrottleStatus.THROTTLE_TYPE_NONE) {
-                    setupDataOnConnectableApn(mApnContextsByType.get(status.getApnType()),
-                            Phone.REASON_DATA_UNTHROTTLED,
-                            RetryFailures.ALWAYS);
-                }
-            }
-        }
-    }
-
     private NetworkPolicyManager mNetworkPolicyManager;
     private final NetworkPolicyManager.SubscriptionCallback mSubscriptionCallback =
             new NetworkPolicyManager.SubscriptionCallback() {
@@ -487,7 +477,7 @@
         public void onSubscriptionPlansChanged(int subId, SubscriptionPlan[] plans) {
             if (mPhone == null || mPhone.getSubId() != subId) return;
 
-            mSubscriptionPlans = Arrays.asList(plans);
+            mSubscriptionPlans = plans == null ? null : Arrays.asList(plans);
             if (DBG) log("SubscriptionPlans changed: " + mSubscriptionPlans);
             reevaluateUnmeteredConnections();
         }
@@ -727,8 +717,6 @@
 
     private final DataThrottler mDataThrottler;
 
-    private final ThrottleStatusChangedCallback mThrottleStatusCallback;
-
     /**
      * Request network completion message map. Key is the APN type, value is the list of completion
      * messages to be sent. Using a list because there might be multiple network requests for
@@ -804,9 +792,6 @@
 
         mSettingsObserver = new SettingsObserver(mPhone.getContext(), this);
         registerSettingsObserver();
-
-        mThrottleStatusCallback = new ThrottleStatusChangedCallback();
-        mDataThrottler.registerForThrottleStatusChanges(mThrottleStatusCallback);
     }
 
     @VisibleForTesting
@@ -821,7 +806,6 @@
         mTransportType = 0;
         mDataServiceManager = null;
         mDataThrottler = null;
-        mThrottleStatusCallback = null;
     }
 
     public void registerServiceStateTrackerEvents() {
@@ -1409,7 +1393,7 @@
         if ((apnContext != null && requestApnType == ApnSetting.TYPE_DEFAULT
                 || requestApnType == ApnSetting.TYPE_ENTERPRISE
                 || requestApnType == ApnSetting.TYPE_IA)
-                && mPhone.getAccessNetworksManager().isInLegacyMode()
+                && mPhone.getTransportManager().isInLegacyMode()
                 && dataRat == ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN) {
             reasons.add(DataDisallowedReasonType.ON_IWLAN);
         }
@@ -1458,13 +1442,13 @@
         }
 
         if (apnContext != null) {
-            if (mPhone.getAccessNetworksManager().getPreferredTransport(
+            if (mPhone.getTransportManager().getPreferredTransport(
                     apnContext.getApnTypeBitmask())
                     == AccessNetworkConstants.TRANSPORT_TYPE_INVALID) {
                 // If QNS explicitly specified this APN type is not allowed on either cellular or
                 // IWLAN, we should not allow data setup.
                 reasons.add(DataDisallowedReasonType.DISABLED_BY_QNS);
-            } else if (mTransportType != mPhone.getAccessNetworksManager().getPreferredTransport(
+            } else if (mTransportType != mPhone.getTransportManager().getPreferredTransport(
                     apnContext.getApnTypeBitmask())) {
                 // If the latest preference has already switched to other transport, we should not
                 // allow data setup.
@@ -1474,7 +1458,7 @@
             // If the transport has been already switched to the other transport, we should not
             // allow the data setup. The only exception is the handover case, where we setup
             // handover data connection before switching the transport.
-            if (mTransportType != mPhone.getAccessNetworksManager().getCurrentTransport(
+            if (mTransportType != mPhone.getTransportManager().getCurrentTransport(
                     apnContext.getApnTypeBitmask()) && requestType != REQUEST_TYPE_HANDOVER) {
                 reasons.add(DataDisallowedReasonType.ON_OTHER_TRANSPORT);
             }
@@ -1624,14 +1608,14 @@
         if (dataConnectionReasons.contains(DataDisallowedReasonType.DISABLED_BY_QNS)
                 || dataConnectionReasons.contains(DataDisallowedReasonType.ON_OTHER_TRANSPORT)) {
             logStr += ", current transport=" + AccessNetworkConstants.transportTypeToString(
-                    mPhone.getAccessNetworksManager().getCurrentTransport(
+                    mPhone.getTransportManager().getCurrentTransport(
                             apnContext.getApnTypeBitmask()));
             logStr += ", preferred transport=" + AccessNetworkConstants.transportTypeToString(
-                    mPhone.getAccessNetworksManager().getPreferredTransport(
+                    mPhone.getTransportManager().getPreferredTransport(
                             apnContext.getApnTypeBitmask()));
         }
         if (DBG) log(logStr);
-        ApnContext.requestLog(apnContext, logStr);
+        apnContext.requestLog(logStr);
         if (!isDataAllowed) {
             StringBuilder str = new StringBuilder();
 
@@ -1664,7 +1648,7 @@
             }
 
             if (DBG) log(str.toString());
-            ApnContext.requestLog(apnContext, str.toString());
+            apnContext.requestLog(str.toString());
             if (requestType == REQUEST_TYPE_HANDOVER) {
                 // If fails due to latest preference already changed back to source transport, then
                 // just fallback (will not attempt handover anymore, and will not tear down the
@@ -1679,7 +1663,7 @@
         if (apnContext.getState() == DctConstants.State.FAILED) {
             String str = "trySetupData: make a FAILED ApnContext IDLE so its reusable";
             if (DBG) log(str);
-            ApnContext.requestLog(apnContext, str);
+            apnContext.requestLog(str);
             apnContext.setState(DctConstants.State.IDLE);
         }
         int radioTech = getDataRat();
@@ -1696,7 +1680,7 @@
             if (waitingApns.isEmpty()) {
                 String str = "trySetupData: X No APN found retValue=false";
                 if (DBG) log(str);
-                ApnContext.requestLog(apnContext, str);
+                apnContext.requestLog(str);
                 if (requestType == REQUEST_TYPE_HANDOVER) {
                     sendHandoverCompleteMessages(apnContext.getApnTypeBitmask(), false,
                             false);
@@ -1846,7 +1830,7 @@
         String str = "cleanUpConnectionInternal: detach=" + detach + " reason="
                 + apnContext.getReason();
         if (VDBG) log(str + " apnContext=" + apnContext);
-        ApnContext.requestLog(apnContext, str);
+        apnContext.requestLog(str);
         if (detach) {
             if (apnContext.isDisconnected()) {
                 // The request is detach and but ApnContext is not connected.
@@ -1870,7 +1854,7 @@
                         str = "cleanUpConnectionInternal: tearing down"
                                 + (disconnectAll ? " all" : "") + " using gen#" + generation;
                         if (DBG) log(str + "apnContext=" + apnContext);
-                        ApnContext.requestLog(apnContext, str);
+                        apnContext.requestLog(str);
                         Pair<ApnContext, Integer> pair = new Pair<>(apnContext, generation);
                         Message msg = obtainMessage(DctConstants.EVENT_DISCONNECT_DONE, pair);
 
@@ -1886,8 +1870,7 @@
                     // apn is connected but no reference to the data connection.
                     // Should not be happen, but reset the state in case.
                     apnContext.setState(DctConstants.State.IDLE);
-                    ApnContext.requestLog(
-                            apnContext, "cleanUpConnectionInternal: connected, bug no dc");
+                    apnContext.requestLog("cleanUpConnectionInternal: connected, bug no dc");
                 }
             }
         } else {
@@ -2013,6 +1996,14 @@
         ArrayList<ApnSetting> dunCandidates = new ArrayList<ApnSetting>();
         ArrayList<ApnSetting> retDunSettings = new ArrayList<ApnSetting>();
 
+        // Places to look for tether APN in order: TETHER_DUN_APN setting (to be deprecated soon),
+        // APN database
+        String apnData = Settings.Global.getString(mResolver, Settings.Global.TETHER_DUN_APN);
+        if (!TextUtils.isEmpty(apnData)) {
+            dunCandidates.addAll(ApnSetting.arrayFromString(apnData));
+            if (VDBG) log("fetchDunApns: dunCandidates from Setting: " + dunCandidates);
+        }
+
         if (dunCandidates.isEmpty()) {
             if (!ArrayUtils.isEmpty(mAllApnSettings)) {
                 for (ApnSetting apn : mAllApnSettings) {
@@ -2147,8 +2138,7 @@
             log("setupData: apnContext=" + apnContext + ", requestType="
                     + requestTypeToString(requestType));
         }
-        ApnContext.requestLog(
-                apnContext, "setupData. requestType=" + requestTypeToString(requestType));
+        apnContext.requestLog("setupData. requestType=" + requestTypeToString(requestType));
         ApnSetting apnSetting;
         DataConnection dataConnection = null;
 
@@ -2311,10 +2301,8 @@
             if (DBG) log("setInitialAttachApn: X There in no available apn.");
         } else {
             if (DBG) log("setInitialAttachApn: X selected APN=" + apnSetting);
-            mDataServiceManager.setInitialAttachApn(new DataProfile.Builder()
-                    .setApnSetting(apnSetting)
-                    .setPreferred(apnSetting.equals(getPreferredApn()))
-                    .build(),
+            mDataServiceManager.setInitialAttachApn(createDataProfile(apnSetting,
+                    apnSetting.equals(getPreferredApn())),
                     mPhone.getServiceState().getDataRoamingFromRegistration(), null);
         }
     }
@@ -2373,7 +2361,6 @@
      * @return true if only single DataConnection is allowed
      */
     private boolean isOnlySingleDcAllowed(int rilRadioTech) {
-        int networkType = ServiceState.rilRadioTechnologyToNetworkType(rilRadioTech);
         // Default single dc rats with no knowledge of carrier
         int[] singleDcRats = null;
         // get the carrier specific value, if it exists, from CarrierConfigManager.
@@ -2394,17 +2381,12 @@
             onlySingleDcAllowed = true;
         }
         if (singleDcRats != null) {
-            for (int i = 0; i < singleDcRats.length && !onlySingleDcAllowed; i++) {
-                if (networkType == singleDcRats[i]) {
-                    onlySingleDcAllowed = true;
-                }
+            for (int i=0; i < singleDcRats.length && onlySingleDcAllowed == false; i++) {
+                if (rilRadioTech == singleDcRats[i]) onlySingleDcAllowed = true;
             }
         }
 
-        if (DBG) {
-            log("isOnlySingleDcAllowed(" + TelephonyManager.getNetworkTypeName(networkType) + "): "
-                    + onlySingleDcAllowed);
-        }
+        if (DBG) log("isOnlySingleDcAllowed(" + rilRadioTech + "): " + onlySingleDcAllowed);
         return onlySingleDcAllowed;
     }
 
@@ -2495,9 +2477,11 @@
         registerSettingsObserver();
         SubscriptionPlan[] plans = mNetworkPolicyManager.getSubscriptionPlans(
                 mPhone.getSubId(), mPhone.getContext().getOpPackageName());
-        mSubscriptionPlans = plans == null ? Collections.emptyList() : Arrays.asList(plans);
-        if (DBG) log("SubscriptionPlans initialized: " + mSubscriptionPlans);
-        reevaluateUnmeteredConnections();
+        if (plans != null) {
+            mSubscriptionPlans = Arrays.asList(plans);
+            if (DBG) log("SubscriptionPlans initialized: " + mSubscriptionPlans);
+            reevaluateUnmeteredConnections();
+        }
         mConfigReady = true;
     }
 
@@ -2585,6 +2569,9 @@
                 @ApnType int apnTypes = apnSetting.getApnTypeBitmask();
                 mDataThrottler.setRetryTime(apnTypes, RetryManager.NO_SUGGESTED_RETRY_DELAY,
                         REQUEST_TYPE_NORMAL);
+                // After data unthrottled, we should see if it's possible to bring up the data
+                // again.
+                setupDataOnAllConnectableApns(Phone.REASON_DATA_UNTHROTTLED, RetryFailures.ALWAYS);
             } else {
                 loge("EVENT_APN_UNTHROTTLED: Invalid APN passed: " + apn);
             }
@@ -2593,16 +2580,6 @@
         }
     }
 
-    private void onTrafficDescriptorsUpdated() {
-        for (ApnContext apnContext : mPrioritySortedApnContexts) {
-            if (apnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE
-                    && apnContext.getApnSetting().getPermanentFailed()) {
-                setupDataOnConnectableApn(
-                        apnContext, Phone.REASON_TRAFFIC_DESCRIPTORS_UPDATED, RetryFailures.ALWAYS);
-            }
-        }
-    }
-
     private DataConnection checkForCompatibleDataConnection(ApnContext apnContext,
             ApnSetting nextApn) {
         int apnType = apnContext.getApnTypeBitmask();
@@ -2766,14 +2743,14 @@
         String str = "onEnableApn: apnType=" + ApnSetting.getApnTypeString(apnType)
                 + ", request type=" + requestTypeToString(requestType);
         if (DBG) log(str);
-        ApnContext.requestLog(apnContext, str);
+        apnContext.requestLog(str);
 
         if (!apnContext.isDependencyMet()) {
             apnContext.setReason(Phone.REASON_DATA_DEPENDENCY_UNMET);
             apnContext.setEnabled(true);
             str = "onEnableApn: dependency is not met.";
             if (DBG) log(str);
-            ApnContext.requestLog(apnContext, str);
+            apnContext.requestLog(str);
             if (onHandoverCompleteMsg != null) {
                 sendHandoverCompleteMsg(onHandoverCompleteMsg, false, mTransportType, false);
             }
@@ -2850,7 +2827,7 @@
         String str = "onDisableApn: apnType=" + ApnSetting.getApnTypeString(apnType)
                 + ", release type=" + releaseTypeToString(releaseType);
         if (DBG) log(str);
-        ApnContext.requestLog(apnContext, str);
+        apnContext.requestLog(str);
 
         if (apnContext.isReady()) {
             cleanup = (releaseType == RELEASE_TYPE_DETACH
@@ -2869,7 +2846,7 @@
                     str = "Clean up the connection. Apn type = " + apnContext.getApnType()
                             + ", state = " + apnContext.getState();
                     if (DBG) log(str);
-                    ApnContext.requestLog(apnContext, str);
+                    apnContext.requestLog(str);
                     cleanup = true;
                 }
             } else {
@@ -3499,10 +3476,7 @@
         for (ApnSetting apn : mAllApnSettings) {
             if (apn.getApnSetId() == Telephony.Carriers.MATCH_ALL_APN_SET_ID
                     || preferredApnSetId == apn.getApnSetId()) {
-                DataProfile dp = new DataProfile.Builder()
-                        .setApnSetting(apn)
-                        .setPreferred(apn.equals(getPreferredApn()))
-                        .build();
+                DataProfile dp = createDataProfile(apn, apn.equals(getPreferredApn()));
                 if (!dataProfileList.contains(dp)) {
                     dataProfileList.add(dp);
                 }
@@ -3562,6 +3536,10 @@
             mPreferredApn = null;
         } else {
             mPreferredApn = getPreferredApn();
+            if (mPreferredApn != null && !mPreferredApn.getOperatorNumeric().equals(operator)) {
+                mPreferredApn = null;
+                setPreferredApn(-1);
+            }
             if (DBG) log("createAllApnList: mPreferredApn=" + mPreferredApn);
         }
 
@@ -3614,45 +3592,25 @@
         int networkTypeBitmask = (dest.getNetworkTypeBitmask() == 0
                 || src.getNetworkTypeBitmask() == 0)
                 ? 0 : (dest.getNetworkTypeBitmask() | src.getNetworkTypeBitmask());
-        return new ApnSetting.Builder()
-                .setId(id)
-                .setOperatorNumeric(dest.getOperatorNumeric())
-                .setEntryName(dest.getEntryName())
-                .setApnName(dest.getApnName())
-                .setProxyAddress(proxy)
-                .setProxyPort(port)
-                .setMmsc(mmsc)
-                .setMmsProxyAddress(mmsProxy)
-                .setMmsProxyPort(mmsPort)
-                .setUser(dest.getUser())
-                .setPassword(dest.getPassword())
-                .setAuthType(dest.getAuthType())
-                .setApnTypeBitmask(resultApnType)
-                .setProtocol(protocol)
-                .setRoamingProtocol(roamingProtocol)
-                .setCarrierEnabled(dest.isEnabled())
-                .setNetworkTypeBitmask(networkTypeBitmask)
-                .setProfileId(dest.getProfileId())
-                .setModemCognitive(dest.isPersistent() || src.isPersistent())
-                .setMaxConns(dest.getMaxConns())
-                .setWaitTime(dest.getWaitTime())
-                .setMaxConnsTime(dest.getMaxConnsTime())
-                .setMtuV4(dest.getMtuV4())
-                .setMtuV6(dest.getMtuV6())
-                .setMvnoType(dest.getMvnoType())
-                .setMvnoMatchData(dest.getMvnoMatchData())
-                .setApnSetId(dest.getApnSetId())
-                .setCarrierId(dest.getCarrierId())
-                .setSkip464Xlat(dest.getSkip464Xlat())
-                .build();
+
+        return ApnSetting.makeApnSetting(id, dest.getOperatorNumeric(), dest.getEntryName(),
+            dest.getApnName(), proxy, port, mmsc, mmsProxy, mmsPort, dest.getUser(),
+            dest.getPassword(), dest.getAuthType(), resultApnType, protocol, roamingProtocol,
+            dest.isEnabled(), networkTypeBitmask, dest.getProfileId(),
+            (dest.isPersistent() || src.isPersistent()), dest.getMaxConns(),
+            dest.getWaitTime(), dest.getMaxConnsTime(), dest.getMtu(), dest.getMvnoType(),
+            dest.getMvnoMatchData(), dest.getApnSetId(), dest.getCarrierId(),
+            dest.getSkip464Xlat());
     }
 
     private DataConnection createDataConnection() {
         if (DBG) log("createDataConnection E");
 
         int id = mUniqueIdGenerator.getAndIncrement();
+        boolean doAllocatePduSessionId =
+                mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
         DataConnection dataConnection = DataConnection.makeDataConnection(mPhone, id, this,
-                mDataServiceManager, mDcTesterFailBringUpAll, mDcc);
+                mDataServiceManager, mDcTesterFailBringUpAll, mDcc, doAllocatePduSessionId);
         mDataConnections.put(id, dataConnection);
         if (DBG) log("createDataConnection() X id=" + id + " dc=" + dataConnection);
         return dataConnection;
@@ -3725,9 +3683,7 @@
                 log("buildWaitingApns: Preferred APN:" + operator + ":"
                         + mPreferredApn.getOperatorNumeric() + ":" + mPreferredApn);
             }
-
-            if (TextUtils.equals(mPreferredApn.getOperatorNumeric(), operator)
-                    || mPreferredApn.getCarrierId() == mPhone.getCarrierId()) {
+            if (mPreferredApn.getOperatorNumeric().equals(operator)) {
                 if (mPreferredApn.canSupportNetworkType(
                         ServiceState.rilRadioTechnologyToNetworkType(radioTech))) {
                     // Create a new instance of ApnSetting for ENTERPRISE because each
@@ -4243,9 +4199,6 @@
                 String apn = (String) ar.result;
                 onApnUnthrottled(apn);
                 break;
-            case DctConstants.EVENT_TRAFFIC_DESCRIPTORS_UPDATED:
-                onTrafficDescriptorsUpdated();
-                break;
             default:
                 Rlog.e("DcTracker", "Unhandled event=" + msg);
                 break;
@@ -4307,18 +4260,15 @@
             }
         }
         if (useLte) {
-            Pair<Integer, Integer> ltePair =
-                    temp.get(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_LTE);
+            Pair<Integer, Integer> ltePair = temp.get(DctConstants.RAT_NAME_LTE);
             if (ltePair != null) {
-                if (temp.containsKey(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_NR_NSA)) {
-                    temp.put(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_NR_NSA, new Pair<>(
-                            temp.get(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_NR_NSA).first,
-                            ltePair.second));
+                if (temp.containsKey(DctConstants.RAT_NAME_NR_NSA)) {
+                    temp.put(DctConstants.RAT_NAME_NR_NSA, new Pair<>(
+                            temp.get(DctConstants.RAT_NAME_NR_NSA).first, ltePair.second));
                 }
-                if (temp.containsKey(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE)) {
-                    temp.put(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE, new Pair<>(
-                            temp.get(DataConfigManager.DATA_CONFIG_NETWORK_TYPE_NR_NSA_MMWAVE)
-                                    .first, ltePair.second));
+                if (temp.containsKey(DctConstants.RAT_NAME_NR_NSA_MMWAVE)) {
+                    temp.put(DctConstants.RAT_NAME_NR_NSA_MMWAVE, new Pair<>(
+                            temp.get(DctConstants.RAT_NAME_NR_NSA_MMWAVE).first, ltePair.second));
                 }
             }
         }
@@ -4416,7 +4366,7 @@
         int rat = mPhone.getDisplayInfoController().getTelephonyDisplayInfo().getNetworkType();
         // congested override and either network is specified or unknown and all networks specified
         boolean isCongested = mCongestedOverride && (mCongestedNetworkTypes.contains(rat)
-                || mCongestedNetworkTypes.containsAll(Arrays.stream(
+                || mUnmeteredNetworkTypes.containsAll(Arrays.stream(
                 TelephonyManager.getAllNetworkTypes()).boxed().collect(Collectors.toSet())));
         for (DataConnection dataConnection : mDataConnections.values()) {
             dataConnection.onCongestednessChanged(isCongested);
@@ -4438,10 +4388,27 @@
     }
 
     private void setDataConnectionUnmetered(boolean isUnmetered) {
-        if (!isUnmetered || isTempNotMeteredSupportedByCarrier()) {
+        // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
+        // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
+        // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few
+        // devices and carriers.
+        if (!isUnmetered || (isUnmetered && tempNotMeteredPossible())) {
             for (DataConnection dataConnection : mDataConnections.values()) {
                 dataConnection.onMeterednessChanged(isUnmetered);
             }
+        } else {
+            // isUnmetered=true but TEMP_NOT_METERED is not possible
+            String message = "Unexpected temp not metered detected. carrier supported="
+                    + isTempNotMeteredSupportedByCarrier() + ", device 5G capable="
+                    + isDevice5GCapable() + ", camped on 5G=" + isCampedOn5G()
+                    + ", timer active=" + mPhone.getDisplayInfoController().is5GHysteresisActive()
+                    + ", display info="
+                    + mPhone.getDisplayInfoController().getTelephonyDisplayInfo()
+                    + ", subscription plans=" + mSubscriptionPlans
+                    + ", Service state=" + mPhone.getServiceState();
+            loge(message);
+            AnomalyReporter.reportAnomaly(
+                    UUID.fromString("9151f0fc-01df-4afb-b744-9c4529055250"), message);
         }
     }
 
@@ -4466,7 +4433,7 @@
     }
 
     private boolean isNetworkTypeUnmeteredViaSubscriptionPlan(@NetworkType int networkType) {
-        if (mSubscriptionPlans.isEmpty()) {
+        if (mSubscriptionPlans == null || mSubscriptionPlans.size() == 0) {
             // safe return false if unable to get subscription plans or plans don't exist
             return false;
         }
@@ -4563,6 +4530,18 @@
         return false;
     }
 
+    // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
+    // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
+    // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few devices
+    // and carriers.
+    private boolean isDevice5GCapable() {
+        return (mPhone.getRadioAccessFamily() & TelephonyManager.NETWORK_TYPE_BITMASK_NR) != 0;
+    }
+
+    // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
+    // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
+    // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few devices
+    // and carriers.
     private boolean isTempNotMeteredSupportedByCarrier() {
         CarrierConfigManager configManager =
                 mPhone.getContext().getSystemService(CarrierConfigManager.class);
@@ -4577,6 +4556,38 @@
         return false;
     }
 
+    // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
+    // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
+    // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few devices
+    // and carriers.
+    private boolean isCampedOn5G() {
+        TelephonyDisplayInfo displayInfo = mPhone.getDisplayInfoController()
+                .getTelephonyDisplayInfo();
+        int overrideNetworkType = displayInfo.getOverrideNetworkType();
+        NetworkRegistrationInfo nri =  mPhone.getServiceState().getNetworkRegistrationInfo(
+                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        int networkType = nri == null ? TelephonyManager.NETWORK_TYPE_UNKNOWN
+                : nri.getAccessNetworkTechnology();
+
+        boolean isNrSa = networkType == TelephonyManager.NETWORK_TYPE_NR;
+        boolean isNrNsa = (networkType == TelephonyManager.NETWORK_TYPE_LTE
+                || networkType == TelephonyManager.NETWORK_TYPE_LTE_CA)
+                && (overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA
+                || overrideNetworkType == TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED);
+        boolean is5GHysteresisActive = mPhone.getDisplayInfoController().is5GHysteresisActive();
+
+        // True if device is on NR SA or NR NSA, or neither but 5G hysteresis is active
+        return isNrSa || isNrNsa || is5GHysteresisActive;
+    }
+
+    // TODO: Remove this after b/176119724 is fixed. This is just a workaround to prevent
+    // NET_CAPABILITY_TEMPORARILY_NOT_METERED incorrectly set on devices that are not supposed
+    // to use 5G unmetered network. Currently TEMPORARILY_NOT_METERED can only happen on few devices
+    // and carriers.
+    private boolean tempNotMeteredPossible() {
+        return isDevice5GCapable() && isTempNotMeteredSupportedByCarrier() && isCampedOn5G();
+    }
+
     protected void log(String s) {
         Rlog.d(mLogTag, s);
     }
@@ -4679,7 +4690,6 @@
             for (Entry<String, ApnContext> entry : apnCtxsSet) {
                 entry.getValue().dump(fd, pw, args);
             }
-            ApnContext.dumpLocalLog(fd, pw, args);
             pw.println(" ***************************************");
         } else {
             pw.println(" mApnContexts=null");
@@ -4871,7 +4881,7 @@
         }
     }
 
-    protected void stopNetStatPoll() {
+    private void stopNetStatPoll() {
         mNetStatPollEnabled = false;
         removeCallbacks(mPollNetStat);
         if (DBG) {
@@ -5463,6 +5473,50 @@
         mWatchdog = false;
     }
 
+    private static DataProfile createDataProfile(ApnSetting apn, boolean isPreferred) {
+        return createDataProfile(apn, apn.getProfileId(), isPreferred);
+    }
+
+    @VisibleForTesting
+    public static DataProfile createDataProfile(ApnSetting apn, int profileId,
+                                                boolean isPreferred) {
+        int profileType;
+
+        int networkTypeBitmask = apn.getNetworkTypeBitmask();
+
+        if (networkTypeBitmask == 0) {
+            profileType = DataProfile.TYPE_COMMON;
+        } else if ((networkTypeBitmask & TelephonyManager.NETWORK_STANDARDS_FAMILY_BITMASK_3GPP2)
+                == networkTypeBitmask) {
+            profileType = DataProfile.TYPE_3GPP2;
+        } else if ((networkTypeBitmask & TelephonyManager.NETWORK_STANDARDS_FAMILY_BITMASK_3GPP)
+                == networkTypeBitmask) {
+            profileType = DataProfile.TYPE_3GPP;
+        } else {
+            profileType = DataProfile.TYPE_COMMON;
+        }
+
+        return new DataProfile.Builder()
+                .setProfileId(profileId)
+                .setApn(apn.getApnName())
+                .setProtocolType(apn.getProtocol())
+                .setAuthType(apn.getAuthType())
+                .setUserName(apn.getUser() == null ? "" : apn.getUser())
+                .setPassword(apn.getPassword() == null ? "" : apn.getPassword())
+                .setType(profileType)
+                .setMaxConnectionsTime(apn.getMaxConnsTime())
+                .setMaxConnections(apn.getMaxConns())
+                .setWaitTime(apn.getWaitTime())
+                .enable(apn.isEnabled())
+                .setSupportedApnTypesBitmask(apn.getApnTypeBitmask())
+                .setRoamingProtocolType(apn.getRoamingProtocol())
+                .setBearerBitmask(networkTypeBitmask)
+                .setMtu(apn.getMtu())
+                .setPersistent(apn.isPersistent())
+                .setPreferred(isPreferred)
+                .build();
+    }
+
     private void onDataServiceBindingChanged(boolean bound) {
         if (!bound) {
             if (mTransportType == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
@@ -5533,7 +5587,7 @@
                     bandwidths = b.getStringArray(CarrierConfigManager.KEY_BANDWIDTH_STRING_ARRAY);
                 }
                 useLte = b.getBoolean(CarrierConfigManager
-                        .KEY_BANDWIDTH_NR_NSA_USE_LTE_VALUE_FOR_UPLINK_BOOL);
+                        .KEY_BANDWIDTH_NR_NSA_USE_LTE_VALUE_FOR_UPSTREAM_BOOL);
                 mWatchdogTimeMs = b.getLong(CarrierConfigManager.KEY_5G_WATCHDOG_TIME_MS_LONG);
                 mNrNsaAllUnmetered = b.getBoolean(CarrierConfigManager.KEY_UNMETERED_NR_NSA_BOOL);
                 mNrNsaMmwaveUnmetered = b.getBoolean(
@@ -5559,24 +5613,24 @@
     }
 
     /**
-     * Register for physical link status (i.e. RRC state) changed event.
+     * Register for physical link state (i.e. RRC state) changed event.
      * if {@link CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL} is true,
      * then physical link state is focusing on "internet data connection" instead of RRC state.
      *
      * @param h The handler
      * @param what The event
      */
-    public void registerForPhysicalLinkStatusChanged(Handler h, int what) {
-        mDcc.registerForPhysicalLinkStatusChanged(h, what);
+    public void registerForPhysicalLinkStateChanged(Handler h, int what) {
+        mDcc.registerForPhysicalLinkStateChanged(h, what);
     }
 
     /**
-     * Unregister from physical link status (i.e. RRC state) changed event.
+     * Unregister from physical link state (i.e. RRC state) changed event.
      *
      * @param h The previously registered handler
      */
-    public void unregisterForPhysicalLinkStatusChanged(Handler h) {
-        mDcc.unregisterForPhysicalLinkStatusChanged(h);
+    public void unregisterForPhysicalLinkStateChanged(Handler h) {
+        mDcc.unregisterForPhysicalLinkStateChanged(h);
     }
 
     // We use a specialized equals function in Apn setting when checking if an active
diff --git a/src/java/com/android/internal/telephony/data/KeepaliveStatus.java b/src/java/com/android/internal/telephony/dataconnection/KeepaliveStatus.java
similarity index 85%
rename from src/java/com/android/internal/telephony/data/KeepaliveStatus.java
rename to src/java/com/android/internal/telephony/dataconnection/KeepaliveStatus.java
index 818de96..8b0ec4f 100644
--- a/src/java/com/android/internal/telephony/data/KeepaliveStatus.java
+++ b/src/java/com/android/internal/telephony/dataconnection/KeepaliveStatus.java
@@ -14,9 +14,8 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony.dataconnection;
 
-import android.annotation.IntDef;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -27,15 +26,9 @@
  * {@hide}
  */
 public class KeepaliveStatus implements Parcelable {
-    /** This should match the HAL {@code KeepaliveStatus.aidl}. */
-    @IntDef(prefix = {"STATUS_REASON_"},
-            value = {
-                    STATUS_ACTIVE,
-                    STATUS_INACTIVE,
-                    STATUS_PENDING,
-            })
-    public @interface KeepaliveStatusCode {}
+    private static final String LOG_TAG = "KeepaliveStatus";
 
+    /** This should match the HAL Radio::1_1::KeepaliveStatusCode */
     public static final int STATUS_ACTIVE = 0;
     public static final int STATUS_INACTIVE = 1;
     public static final int STATUS_PENDING = 2;
@@ -54,7 +47,7 @@
      * A status code indicating whether this Keepalive session is
      * active, inactive, or pending activation
      */
-    public final @KeepaliveStatusCode int statusCode;
+    public final int statusCode;
 
     /** An error code indicating a lower layer failure, if any */
     public final int errorCode;
@@ -65,7 +58,7 @@
         errorCode = error;
     }
 
-    public KeepaliveStatus(int handle, @KeepaliveStatusCode int code) {
+    public KeepaliveStatus(int handle, int code) {
         sessionHandle = handle;
         statusCode = code;
         errorCode = ERROR_NONE;
diff --git a/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java b/src/java/com/android/internal/telephony/dataconnection/LinkBandwidthEstimator.java
similarity index 90%
rename from src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java
rename to src/java/com/android/internal/telephony/dataconnection/LinkBandwidthEstimator.java
index 919bbc3..833cf86 100644
--- a/src/java/com/android/internal/telephony/data/LinkBandwidthEstimator.java
+++ b/src/java/com/android/internal/telephony/dataconnection/LinkBandwidthEstimator.java
@@ -14,11 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony.dataconnection;
 
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 
-import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
@@ -36,7 +35,6 @@
 import android.os.RegistrantList;
 import android.preference.PreferenceManager;
 import android.telephony.AccessNetworkConstants;
-import android.telephony.Annotation.DataActivityType;
 import android.telephony.CellIdentity;
 import android.telephony.CellIdentityGsm;
 import android.telephony.CellIdentityLte;
@@ -50,7 +48,6 @@
 import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.util.LocalLog;
 import android.util.Pair;
 import android.view.Display;
@@ -68,8 +65,6 @@
 import java.io.PrintWriter;
 import java.util.Map;
 import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.Executor;
 
 /**
  * Link Bandwidth Estimator based on the byte counts in TrafficStats and the time reported in modem
@@ -138,7 +133,6 @@
     // Used to derive byte count threshold from avg BW
     private static final int LOW_BW_TO_AVG_BW_RATIO_NUM = 3;
     private static final int LOW_BW_TO_AVG_BW_RATIO_DEN = 8;
-    private static final int MAX_BW_TO_STATIC_BW_RATIO = 15;
     private static final int BYTE_DELTA_THRESHOLD_MIN_KB = 10;
     private static final int MAX_ERROR_PERCENT = 100 * 100;
     private static final String[] AVG_BW_PER_RAT = {
@@ -195,42 +189,6 @@
     private long mLastPlmnOrRatChangeTimeMs;
     private long mLastDrsOrRatChangeTimeMs;
 
-    private int mDataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
-
-    /** Link bandwidth estimator callbacks. */
-    private final @NonNull Set<LinkBandwidthEstimatorCallback> mLinkBandwidthEstimatorCallbacks =
-            new ArraySet<>();
-
-    /**
-     * The link bandwidth estimator callback. Note this is only used for passing information
-     * internally in the data stack, should not be used externally.
-     */
-    public static class LinkBandwidthEstimatorCallback extends DataCallback {
-        /**
-         * Constructor
-         *
-         * @param executor The executor of the callback.
-         */
-        public LinkBandwidthEstimatorCallback(@NonNull @CallbackExecutor Executor executor) {
-            super(executor);
-        }
-
-        /**
-         * Called when data activity changed.
-         *
-         * @param dataActivity The data activity.
-         */
-        public void onDataActivityChanged(@DataActivityType int dataActivity) {}
-
-        /**
-         * Called when bandwidth changed.
-         *
-         * @param uplinkBandwidthKbps Uplink bandwidth estimate in Kbps.
-         * @param downlinkBandwidthKbps Downlink bandwidth estimate in Kbps.
-         */
-        public void onBandwidthChanged(int uplinkBandwidthKbps, int downlinkBandwidthKbps) {}
-    }
-
     private static void initAvgBwPerRatTable() {
         for (String config : AVG_BW_PER_RAT) {
             int rxKbps = 14;
@@ -357,10 +315,7 @@
      * @param h handler to notify
      * @param what what code of message when delivered
      * @param obj placed in Message.obj
-     *
-     * @deprecated Use {@link #registerCallback(LinkBandwidthEstimatorCallback)}.
      */
-    @Deprecated //TODO: Remove once old data stack is removed.
     public void registerForBandwidthChanged(Handler h, int what, Object obj) {
         Registrant r = new Registrant(h, what, obj);
         mBandwidthChangedRegistrants.add(r);
@@ -369,32 +324,10 @@
     /**
      * Unregisters for bandwidth estimation change.
      * @param h handler to notify
-     *
-     * @deprecated Use {@link #unregisterCallback(LinkBandwidthEstimatorCallback)}.
      */
-    @Deprecated //TODO: Remove once old data stack is removed.
     public void unregisterForBandwidthChanged(Handler h) {
         mBandwidthChangedRegistrants.remove(h);
     }
-
-    /**
-     * Register the callback for receiving information from {@link LinkBandwidthEstimator}.
-     *
-     * @param callback The callback.
-     */
-    public void registerCallback(@NonNull LinkBandwidthEstimatorCallback callback) {
-        mLinkBandwidthEstimatorCallbacks.add(callback);
-    }
-
-    /**
-     * Unregister the callback.
-     *
-     * @param callback The previously registered callback.
-     */
-    public void unregisterCallback(@NonNull LinkBandwidthEstimatorCallback callback) {
-        mLinkBandwidthEstimatorCallbacks.remove(callback);
-    }
-
     /**
      * @return True if one the device's screen (e.g. main screen, wifi display, HDMI display etc...)
      * is on.
@@ -523,23 +456,6 @@
             return;
         }
 
-        int dataActivity;
-        if (txBytesDelta > 0 && rxBytesDelta > 0) {
-            dataActivity = TelephonyManager.DATA_ACTIVITY_INOUT;
-        } else if (rxBytesDelta > 0) {
-            dataActivity = TelephonyManager.DATA_ACTIVITY_IN;
-        } else if (txBytesDelta > 0) {
-            dataActivity = TelephonyManager.DATA_ACTIVITY_OUT;
-        } else {
-            dataActivity = TelephonyManager.DATA_ACTIVITY_NONE;
-        }
-
-        if (mDataActivity != dataActivity) {
-            mDataActivity = dataActivity;
-            mLinkBandwidthEstimatorCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                    () -> callback.onDataActivityChanged(dataActivity)));
-        }
-
         long timeSinceLastFilterUpdateMs = currTimeMs - mFilterUpdateTimeMs;
         // Update filter
         if (timeSinceLastFilterUpdateMs >= FILTER_UPDATE_MAX_INTERVAL_MS) {
@@ -690,8 +606,7 @@
                 return;
             }
             long linkBandwidthLongKbps = bytesDelta * 8 / timeDeltaMs * 1000 / 1024;
-            if (linkBandwidthLongKbps > (long) mStaticBwKbps * MAX_BW_TO_STATIC_BW_RATIO
-                    || linkBandwidthLongKbps < 0) {
+            if (linkBandwidthLongKbps > Integer.MAX_VALUE || linkBandwidthLongKbps < 0) {
                 return;
             }
             int linkBandwidthKbps = (int) linkBandwidthLongKbps;
@@ -776,45 +691,6 @@
             return -1;
         }
 
-        private int getAvgUsedBandwidthAdjacentThreeLevelKbps() {
-            String dataRatName = getDataRatName(mDataRat);
-            NetworkBandwidth network = lookupNetwork(mPlmn, dataRatName);
-
-            int bandwidthAtLow = getAvgUsedBandwidthAtLevel(network, mSignalLevel - 1);
-            int bandwidthAtHigh = getAvgUsedBandwidthAtLevel(network, mSignalLevel + 1);
-            if (bandwidthAtLow > 0 && bandwidthAtHigh > 0) {
-                return (bandwidthAtLow + bandwidthAtHigh) / 2;
-            }
-
-            int count = 0;
-            long value = 0;
-            for (int i = -1; i <= 1; i++) {
-                int currLevel = mSignalLevel + i;
-                if (currLevel < 0 || currLevel >= NUM_SIGNAL_LEVEL) {
-                    continue;
-                }
-                count += network.getCount(mLink, currLevel);
-                value += network.getValue(mLink, currLevel);
-            }
-
-            if (count >= BW_STATS_COUNT_THRESHOLD) {
-                return (int) (value / count);
-            }
-            return -1;
-        }
-
-        private int getAvgUsedBandwidthAtLevel(NetworkBandwidth network,
-                int signalLevel) {
-            if (signalLevel < 0 || signalLevel >= NUM_SIGNAL_LEVEL) {
-                return -1;
-            }
-            int count = network.getCount(mLink, signalLevel);
-            if (count >= BW_STATS_COUNT_THRESHOLD) {
-                return (int) (network.getValue(mLink, signalLevel) / count);
-            }
-            return -1;
-        }
-
         private int getCurrentCount() {
             String dataRatName = getDataRatName(mDataRat);
             NetworkBandwidth network = lookupNetwork(mPlmn, dataRatName);
@@ -827,10 +703,6 @@
             if (mAvgUsedKbps > 0) {
                 return mAvgUsedKbps;
             }
-            mAvgUsedKbps = getAvgUsedBandwidthAdjacentThreeLevelKbps();
-            if (mAvgUsedKbps > 0) {
-                return mAvgUsedKbps;
-            }
             // Fall back to static value
             return mStaticBwKbps;
         }
@@ -933,8 +805,6 @@
         Pair<Integer, Integer> bandwidthInfo =
                 new Pair<Integer, Integer>(linkBandwidthTxKps, linkBandwidthRxKps);
         mBandwidthChangedRegistrants.notifyRegistrants(new AsyncResult(null, bandwidthInfo, null));
-        mLinkBandwidthEstimatorCallbacks.forEach(callback -> callback.invokeFromExecutor(
-                () -> callback.onBandwidthChanged(linkBandwidthTxKps, linkBandwidthRxKps)));
     }
 
     private void handleSignalStrengthChanged(SignalStrength signalStrength) {
@@ -962,13 +832,6 @@
     }
 
     /**
-     * @return The data activity.
-     */
-    public @DataActivityType int getDataActivity() {
-        return mDataActivity;
-    }
-
-    /**
      * Get a string based on current RAT
      */
     public String getDataRatName(int rat) {
diff --git a/src/java/com/android/internal/telephony/dataconnection/QosCallbackTracker.java b/src/java/com/android/internal/telephony/dataconnection/QosCallbackTracker.java
new file mode 100644
index 0000000..795ed14
--- /dev/null
+++ b/src/java/com/android/internal/telephony/dataconnection/QosCallbackTracker.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony.dataconnection;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.LinkAddress;
+import android.net.QosSession;
+import android.telephony.data.EpsQos;
+import android.telephony.data.NrQos;
+import android.telephony.data.EpsBearerQosSessionAttributes;
+import android.telephony.data.NrQosSessionAttributes;
+import android.telephony.data.QosBearerFilter;
+import android.telephony.data.QosBearerSession;
+
+import com.android.telephony.Rlog;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Matches filters with qos sessions and send corresponding available and lost events.
+ *
+ * Note: This class is <b>NOT</b> thread-safe
+ *
+ * {@hide}
+ */
+public class QosCallbackTracker {
+    @NonNull private final String mTag;
+    @NonNull private final DcNetworkAgent mDcNetworkAgent;
+    @NonNull private final Map<Integer, QosBearerSession> mQosBearerSessions;
+
+    // We perform an exact match on the address
+    @NonNull private final Map<Integer, IFilter> mCallbacksToFilter;
+
+    /**
+     * Construct a new tracker
+     * @param dcNetworkAgent the network agent to send events to
+     */
+    public QosCallbackTracker(@NonNull final DcNetworkAgent dcNetworkAgent) {
+        mQosBearerSessions = new HashMap<>();
+        mCallbacksToFilter = new HashMap<>();
+        mDcNetworkAgent = dcNetworkAgent;
+        mTag = "QosCallbackTracker" + "-" + mDcNetworkAgent.getNetwork().getNetId();
+    }
+
+    /**
+     * Add new filter that is to receive events
+     *
+     * @param callbackId the associated callback id
+     * @param filter provides the matching logic
+     */
+    public void addFilter(final int callbackId, final IFilter filter) {
+        logd("addFilter: callbackId=" + callbackId);
+        // Called from mDcNetworkAgent
+        mCallbacksToFilter.put(callbackId, filter);
+
+        //On first change. Check all sessions and send.
+        for (final QosBearerSession session : mQosBearerSessions.values()) {
+            if (doFiltersMatch(session, filter)) {
+                sendSessionAvailable(callbackId, session, filter);
+            }
+        }
+    }
+
+    /**
+     * Remove the filter with the associated callback id
+     *
+     * @param callbackId the qos callback id
+     */
+    public void removeFilter(final int callbackId) {
+        logd("removeFilter: callbackId=" + callbackId);
+        mCallbacksToFilter.remove(callbackId);
+    }
+
+    /**
+     * Update the list of qos sessions and send out corresponding events
+     *
+     * @param sessions the new list of qos sessions
+     */
+    public void updateSessions(@NonNull final List<QosBearerSession> sessions) {
+        logd("updateSessions: sessions size=" + sessions.size());
+        final List<QosBearerSession> sessionsToAdd = new ArrayList<>();
+        final Map<Integer, QosBearerSession> incomingSessions = new HashMap<>();
+        for (final QosBearerSession incomingSession : sessions) {
+            incomingSessions.put(incomingSession.getQosBearerSessionId(), incomingSession);
+
+            final QosBearerSession existingSession = mQosBearerSessions.get(
+                    incomingSession.getQosBearerSessionId());
+            for (final int callbackId : mCallbacksToFilter.keySet()) {
+                final IFilter filter = mCallbacksToFilter.get(callbackId);
+
+                final boolean incomingSessionMatch = doFiltersMatch(incomingSession, filter);
+                final boolean existingSessionMatch =
+                        existingSession != null && doFiltersMatch(existingSession, filter);
+
+                if (!existingSessionMatch && incomingSessionMatch) {
+                    // The filter matches now and didn't match earlier
+                    sendSessionAvailable(callbackId, incomingSession, filter);
+                }
+
+                if (existingSessionMatch && incomingSessionMatch) {
+                    // The same sessions matches the same filter, but if the qos changed,
+                    // the callback still needs to be notified
+                    if (!incomingSession.getQos().equals(existingSession.getQos())) {
+                        sendSessionAvailable(callbackId, incomingSession, filter);
+                    }
+                }
+            }
+            sessionsToAdd.add(incomingSession);
+        }
+
+        final List<Integer> sessionsToRemove = new ArrayList<>();
+        // Find sessions that no longer exist
+        for (final QosBearerSession existingSession : mQosBearerSessions.values()) {
+            if (!incomingSessions.containsKey(existingSession.getQosBearerSessionId())) {
+                for (final int callbackId : mCallbacksToFilter.keySet()) {
+                    final IFilter filter = mCallbacksToFilter.get(callbackId);
+                    // The filter matches which means it was previously available, and now is lost
+                    if (doFiltersMatch(existingSession, filter)) {
+                        sendSessionLost(callbackId, existingSession);
+                    }
+                }
+                sessionsToRemove.add(existingSession.getQosBearerSessionId());
+            }
+        }
+
+        // Add in the new or existing sessions with updated information
+        for (final QosBearerSession sessionToAdd : sessionsToAdd) {
+            mQosBearerSessions.put(sessionToAdd.getQosBearerSessionId(), sessionToAdd);
+        }
+
+        // Remove any old sessions
+        for (final int sessionToRemove : sessionsToRemove) {
+            mQosBearerSessions.remove(sessionToRemove);
+        }
+    }
+
+    private boolean doFiltersMatch(
+            final QosBearerSession qosBearerSession, final IFilter filter) {
+        return getMatchingQosBearerFilter(qosBearerSession, filter) != null;
+    }
+
+    private boolean matchesByLocalAddress(
+        QosBearerFilter sessionFilter, final IFilter filter) {
+        for (final LinkAddress qosAddress : sessionFilter.getLocalAddresses()) {
+            return filter.matchesLocalAddress(qosAddress.getAddress(),
+                  sessionFilter.getLocalPortRange().getStart(),
+                  sessionFilter.getLocalPortRange().getEnd());
+        }
+        return false;
+    }
+
+    private boolean matchesByRemoteAddress(
+            QosBearerFilter sessionFilter, final IFilter filter) {
+        for (final LinkAddress qosAddress : sessionFilter.getRemoteAddresses()) {
+            return filter.matchesRemoteAddress(qosAddress.getAddress(),
+                  sessionFilter.getRemotePortRange().getStart(),
+                  sessionFilter.getRemotePortRange().getEnd());
+        }
+        return false;
+    }
+
+    private boolean matchesByRemoteAndLocalAddress(
+            QosBearerFilter sessionFilter, final IFilter filter) {
+        for (final LinkAddress remoteAddress : sessionFilter.getRemoteAddresses()) {
+            for (final LinkAddress localAddress : sessionFilter.getLocalAddresses()) {
+                return filter.matchesRemoteAddress(remoteAddress.getAddress(),
+                        sessionFilter.getRemotePortRange().getStart(),
+                        sessionFilter.getRemotePortRange().getEnd())
+                        && filter.matchesLocalAddress(localAddress.getAddress(),
+                              sessionFilter.getLocalPortRange().getStart(),
+                              sessionFilter.getLocalPortRange().getEnd());
+            }
+        }
+        return false;
+    }
+
+    private QosBearerFilter getFilterByPrecedence(
+            QosBearerFilter qosFilter, QosBearerFilter sessionFilter) {
+        // Find for the highest precedence filter, lower the value is the higher the precedence
+        return qosFilter == null || sessionFilter.getPrecedence() < qosFilter.getPrecedence()
+                ? sessionFilter : qosFilter;
+    }
+
+    private QosBearerFilter getMatchingQosBearerFilter(
+            final QosBearerSession qosBearerSession, final IFilter filter) {
+        QosBearerFilter qosFilter = null;
+
+        for (final QosBearerFilter sessionFilter : qosBearerSession.getQosBearerFilterList()) {
+           if (!sessionFilter.getLocalAddresses().isEmpty()
+                   && !sessionFilter.getRemoteAddresses().isEmpty()
+                   && sessionFilter.getLocalPortRange().isValid()
+                   && sessionFilter.getRemotePortRange().isValid()) {
+               if (matchesByRemoteAndLocalAddress(sessionFilter, filter)) {
+                   qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
+               }
+           } else if (!sessionFilter.getRemoteAddresses().isEmpty()
+                   && sessionFilter.getRemotePortRange().isValid()) {
+               if (matchesByRemoteAddress(sessionFilter, filter)) {
+                   qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
+               }
+           } else if (!sessionFilter.getLocalAddresses().isEmpty()
+                   && sessionFilter.getLocalPortRange().isValid()) {
+               if (matchesByLocalAddress(sessionFilter, filter)) {
+                   qosFilter = getFilterByPrecedence(qosFilter, sessionFilter);
+               }
+           }
+        }
+        return qosFilter;
+    }
+
+    private void sendSessionAvailable(final int callbackId,
+            @NonNull final QosBearerSession session, @NonNull IFilter filter) {
+        QosBearerFilter qosBearerFilter = getMatchingQosBearerFilter(session, filter);
+        List<InetSocketAddress> remoteAddresses = new ArrayList<>();
+        if(qosBearerFilter.getRemoteAddresses().size() > 0) {
+            remoteAddresses.add(
+                  new InetSocketAddress(qosBearerFilter.getRemoteAddresses().get(0).getAddress(),
+                  qosBearerFilter.getRemotePortRange().getStart()));
+        }
+
+        if (session.getQos() instanceof EpsQos) {
+            EpsQos qos = (EpsQos) session.getQos();
+            EpsBearerQosSessionAttributes epsBearerAttr =
+                    new EpsBearerQosSessionAttributes(qos.getQci(),
+                            qos.getUplinkBandwidth().getMaxBitrateKbps(),
+                            qos.getDownlinkBandwidth().getMaxBitrateKbps(),
+                            qos.getDownlinkBandwidth().getGuaranteedBitrateKbps(),
+                            qos.getUplinkBandwidth().getGuaranteedBitrateKbps(),
+                            remoteAddresses);
+            mDcNetworkAgent.notifyQosSessionAvailable(
+                    callbackId, session.getQosBearerSessionId(), epsBearerAttr);
+        } else {
+            NrQos qos = (NrQos) session.getQos();
+            NrQosSessionAttributes nrQosAttr =
+                    new NrQosSessionAttributes(qos.get5Qi(), qos.getQfi(),
+                            qos.getUplinkBandwidth().getMaxBitrateKbps(),
+                            qos.getDownlinkBandwidth().getMaxBitrateKbps(),
+                            qos.getDownlinkBandwidth().getGuaranteedBitrateKbps(),
+                            qos.getUplinkBandwidth().getGuaranteedBitrateKbps(),
+                            qos.getAveragingWindow(), remoteAddresses);
+            mDcNetworkAgent.notifyQosSessionAvailable(
+                    callbackId, session.getQosBearerSessionId(), nrQosAttr);
+        }
+
+        logd("sendSessionAvailable, callbackId=" + callbackId);
+    }
+
+    private void sendSessionLost(final int callbackId, @NonNull final QosBearerSession session) {
+        mDcNetworkAgent.notifyQosSessionLost(callbackId, session.getQosBearerSessionId(),
+                session.getQos() instanceof EpsQos ?
+                QosSession.TYPE_EPS_BEARER : QosSession.TYPE_NR_BEARER);
+        logd("sendSessionLost, callbackId=" + callbackId);
+    }
+
+    public interface IFilter {
+        public boolean matchesLocalAddress(InetAddress address, int startPort, int endPort);
+        public boolean matchesRemoteAddress(InetAddress address, int startPort, int endPort);
+    }
+
+    /**
+     * Log with debug level
+     *
+     * @param s is string log
+     */
+    private void logd(String s) {
+        Rlog.d(mTag, s);
+    }
+}
diff --git a/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java b/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
similarity index 73%
rename from src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
rename to src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
index 85f0ae1..279da92 100644
--- a/src/java/com/android/internal/telephony/data/TelephonyNetworkFactory.java
+++ b/src/java/com/android/internal/telephony/dataconnection/TelephonyNetworkFactory.java
@@ -14,7 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony.dataconnection;
+
+import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
 
 import android.net.NetworkCapabilities;
 import android.net.NetworkFactory;
@@ -33,11 +35,8 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
+import com.android.internal.telephony.PhoneSwitcher;
 import com.android.internal.telephony.SubscriptionController;
-import com.android.internal.telephony.dataconnection.ApnContext;
-import com.android.internal.telephony.dataconnection.DataConnection;
-import com.android.internal.telephony.dataconnection.DcTracker;
 import com.android.internal.telephony.dataconnection.DcTracker.ReleaseNetworkType;
 import com.android.internal.telephony.dataconnection.DcTracker.RequestNetworkType;
 import com.android.internal.telephony.dataconnection.TransportManager.HandoverParams;
@@ -50,15 +49,11 @@
 import java.util.HashMap;
 import java.util.Map;
 
-/**
- * Telephony network factory is responsible for dispatching network requests from the connectivity
- * service to the data network controller.
- */
 public class TelephonyNetworkFactory extends NetworkFactory {
     public final String LOG_TAG;
     protected static final boolean DBG = true;
 
-    private static final int REQUEST_LOG_SIZE = 256;
+    private static final int REQUEST_LOG_SIZE = 40;
 
     private static final int ACTION_NO_OP   = 0;
     private static final int ACTION_REQUEST = 1;
@@ -81,13 +76,13 @@
 
     // Key: network request. Value: the transport of DcTracker it applies to,
     // AccessNetworkConstants.TRANSPORT_TYPE_INVALID if not applied.
-    private final Map<TelephonyNetworkRequest, Integer> mNetworkRequests = new HashMap<>();
+    private final Map<NetworkRequest, Integer> mNetworkRequests = new HashMap<>();
 
     private final Map<Message, HandoverParams> mPendingHandovers = new HashMap<>();
 
     private final Phone mPhone;
 
-    private AccessNetworksManager mAccessNetworksManager;
+    private final TransportManager mTransportManager;
 
     private int mSubscriptionId;
 
@@ -99,10 +94,10 @@
         super(looper, phone.getContext(), "TelephonyNetworkFactory[" + phone.getPhoneId()
                 + "]", null);
         mPhone = phone;
+        mTransportManager = mPhone.getTransportManager();
         mInternalHandler = new InternalHandler(looper);
 
         mSubscriptionController = SubscriptionController.getInstance();
-        mAccessNetworksManager = mPhone.getAccessNetworksManager();
 
         setCapabilityFilter(makeNetworkFilter(mSubscriptionController, mPhone.getPhoneId()));
         setScoreFilter(TELEPHONY_NETWORK_SCORE);
@@ -112,12 +107,10 @@
 
         mPhoneSwitcher.registerForActivePhoneSwitch(mInternalHandler, EVENT_ACTIVE_PHONE_SWITCH,
                 null);
-        if (!phone.isUsingNewDataStack()) {
-            mPhone.getTransportManager().registerForHandoverNeededEvent(mInternalHandler,
-                    EVENT_DATA_HANDOVER_NEEDED);
-        }
+        mTransportManager.registerForHandoverNeededEvent(mInternalHandler,
+                EVENT_DATA_HANDOVER_NEEDED);
 
-        mSubscriptionId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
+        mSubscriptionId = INVALID_SUBSCRIPTION_ID;
         SubscriptionManager.from(mPhone.getContext()).addOnSubscriptionsChangedListener(
                 mSubscriptionsChangedListener);
 
@@ -157,28 +150,19 @@
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_IA)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_RCS)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_XCAP)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
                 .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_MCX)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
-                .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_1)
-                .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_2)
-                .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_3)
-                .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_4)
-                .addEnterpriseId(NetworkCapabilities.NET_ENTERPRISE_ID_5)
                 .setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
                 .setSubscriptionId(subscriptionId).build());
         return builder.build();
     }
 
     private class InternalHandler extends Handler {
-        InternalHandler(Looper looper) {
+        public InternalHandler(Looper looper) {
             super(looper);
         }
 
@@ -231,20 +215,9 @@
         }
     }
 
-    private int getTransportTypeFromNetworkRequest(TelephonyNetworkRequest networkRequest) {
-        if (PhoneFactory.getDefaultPhone().isUsingNewDataStack()) {
-            int transport = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
-            int capability = networkRequest.getApnTypeNetworkCapability();
-            if (capability >= 0) {
-                transport = mAccessNetworksManager
-                        .getPreferredTransportByNetworkCapability(capability);
-            }
-            return transport;
-        } else {
-            int apnType = ApnContext.getApnTypeFromNetworkRequest(
-                    networkRequest.getNativeNetworkRequest());
-            return mAccessNetworksManager.getCurrentTransport(apnType);
-        }
+    private int getTransportTypeFromNetworkRequest(NetworkRequest networkRequest) {
+        int apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest);
+        return mTransportManager.getCurrentTransport(apnType);
     }
 
     /**
@@ -256,37 +229,21 @@
      * @param onHandoverCompleteMsg When request type is handover, this message will be sent when
      * handover is completed. For normal request, this should be null.
      */
-    private void requestNetworkInternal(TelephonyNetworkRequest networkRequest,
+    private void requestNetworkInternal(NetworkRequest networkRequest,
             @RequestNetworkType int requestType, int transport, Message onHandoverCompleteMsg) {
-        NetworkRequestsStats.addNetworkRequest(networkRequest.getNativeNetworkRequest(),
-                mSubscriptionId);
-
-        if (mPhone.isUsingNewDataStack()) {
-            mPhone.getDataNetworkController().addNetworkRequest(networkRequest);
-        } else {
-            if (mPhone.getDcTracker(transport) != null) {
-                mPhone.getDcTracker(transport).requestNetwork(
-                        networkRequest.getNativeNetworkRequest(), requestType,
-                        onHandoverCompleteMsg);
-            }
+        NetworkRequestsStats.addNetworkRequest(networkRequest, mSubscriptionId);
+        if (mPhone.getDcTracker(transport) != null) {
+            mPhone.getDcTracker(transport).requestNetwork(networkRequest, requestType,
+                    onHandoverCompleteMsg);
         }
     }
 
-    private void releaseNetworkInternal(TelephonyNetworkRequest networkRequest) {
-        mPhone.getDataNetworkController().removeNetworkRequest(networkRequest);
-    }
-
-    // TODO: Clean this up after old data stack removed.
-    private void releaseNetworkInternal(TelephonyNetworkRequest networkRequest,
+    private void releaseNetworkInternal(NetworkRequest networkRequest,
                                         @ReleaseNetworkType int releaseType,
                                         int transport) {
-        if (mPhone.isUsingNewDataStack()) {
-            mPhone.getDataNetworkController().removeNetworkRequest(networkRequest);
-        } else {
-            if (mPhone.getDcTracker(transport) != null) {
-                mPhone.getDcTracker(transport).releaseNetwork(
-                        networkRequest.getNativeNetworkRequest(), releaseType);
-            }
+        NetworkRequestsStats.addNetworkRelease(networkRequest, mSubscriptionId);
+        if (mPhone.getDcTracker(transport) != null) {
+            mPhone.getDcTracker(transport).releaseNetwork(networkRequest, releaseType);
         }
     }
 
@@ -302,9 +259,8 @@
 
     // apply or revoke requests if our active-ness changes
     private void onActivePhoneSwitch() {
-        logl("onActivePhoneSwitch");
-        for (Map.Entry<TelephonyNetworkRequest, Integer> entry : mNetworkRequests.entrySet()) {
-            TelephonyNetworkRequest networkRequest = entry.getKey();
+        for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) {
+            NetworkRequest networkRequest = entry.getKey();
             boolean applied = entry.getValue() != AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
 
             boolean shouldApply = mPhoneSwitcher.shouldApplyNetworkRequest(
@@ -320,12 +276,8 @@
                 requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_NORMAL,
                         getTransportTypeFromNetworkRequest(networkRequest), null);
             } else if (action == ACTION_RELEASE) {
-                if (mPhone.isUsingNewDataStack()) {
-                    releaseNetworkInternal(networkRequest);
-                } else {
-                    releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_DETACH,
-                            getTransportTypeFromNetworkRequest(networkRequest));
-                }
+                releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_DETACH,
+                        getTransportTypeFromNetworkRequest(networkRequest));
             }
 
             mNetworkRequests.put(networkRequest,
@@ -339,7 +291,7 @@
         final int newSubscriptionId = mSubscriptionController.getSubIdUsingPhoneId(
                 mPhone.getPhoneId());
         if (mSubscriptionId != newSubscriptionId) {
-            if (DBG) logl("onSubIdChange " + mSubscriptionId + "->" + newSubscriptionId);
+            if (DBG) log("onSubIdChange " + mSubscriptionId + "->" + newSubscriptionId);
             mSubscriptionId = newSubscriptionId;
             setCapabilityFilter(makeNetworkFilter(mSubscriptionId));
         }
@@ -353,8 +305,7 @@
     }
 
     private void onNeedNetworkFor(Message msg) {
-        TelephonyNetworkRequest networkRequest =
-                new TelephonyNetworkRequest((NetworkRequest) msg.obj, mPhone);
+        NetworkRequest networkRequest = (NetworkRequest) msg.obj;
         boolean shouldApply = mPhoneSwitcher.shouldApplyNetworkRequest(
                 networkRequest, mPhone.getPhoneId());
 
@@ -378,8 +329,7 @@
     }
 
     private void onReleaseNetworkFor(Message msg) {
-        TelephonyNetworkRequest networkRequest =
-                new TelephonyNetworkRequest((NetworkRequest) msg.obj, mPhone);
+        NetworkRequest networkRequest = (NetworkRequest) msg.obj;
         boolean applied = mNetworkRequests.get(networkRequest)
                 != AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
 
@@ -388,20 +338,16 @@
         logl("onReleaseNetworkFor " + networkRequest + " applied " + applied);
 
         if (applied) {
-            if (mPhone.isUsingNewDataStack()) {
-                releaseNetworkInternal(networkRequest);
-            } else {
-                // Most of the time, the network request only exists in one of the DcTracker, but in
-                // the middle of handover, the network request temporarily exists in both
-                // DcTrackers. If connectivity service releases the network request while handover
-                // is ongoing, we need to remove network requests from both DcTrackers.
-                // Note that this part will be refactored in T, where we won't even have DcTracker
-                // at all.
-                releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL,
-                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-                releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL,
-                        AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-            }
+            // Most of the time, the network request only exists in one of the DcTracker, but in the
+            // middle of handover, the network request temporarily exists in both DcTrackers. If
+            // connectivity service releases the network request while handover is ongoing, we need
+            // to remove network requests from both DcTrackers.
+            // Note that this part will be refactored in T, where we won't even have DcTracker at
+            // all.
+            releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL,
+                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+            releaseNetworkInternal(networkRequest, DcTracker.RELEASE_TYPE_NORMAL,
+                    AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
         }
     }
 
@@ -410,19 +356,18 @@
         log("onDataHandoverNeeded: apnType=" + ApnSetting.getApnTypeString(apnType)
                 + ", target transport="
                 + AccessNetworkConstants.transportTypeToString(targetTransport));
-        if (mAccessNetworksManager.getCurrentTransport(apnType) == targetTransport) {
+        if (mTransportManager.getCurrentTransport(apnType) == targetTransport) {
             log("APN type " + ApnSetting.getApnTypeString(apnType) + " is already on "
                     + AccessNetworkConstants.transportTypeToString(targetTransport));
             return;
         }
 
         boolean handoverPending = false;
-        for (Map.Entry<TelephonyNetworkRequest, Integer> entry : mNetworkRequests.entrySet()) {
-            TelephonyNetworkRequest networkRequest = entry.getKey();
+        for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) {
+            NetworkRequest networkRequest = entry.getKey();
             int currentTransport = entry.getValue();
             boolean applied = currentTransport != AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
-            if (ApnContext.getApnTypeFromNetworkRequest(
-                    networkRequest.getNativeNetworkRequest()) == apnType
+            if (ApnContext.getApnTypeFromNetworkRequest(networkRequest) == apnType
                     && applied
                     && currentTransport != targetTransport) {
                 DcTracker dcTracker = mPhone.getDcTracker(currentTransport);
@@ -433,8 +378,7 @@
                         Message onCompleteMsg = mInternalHandler.obtainMessage(
                                 EVENT_DATA_HANDOVER_COMPLETED);
                         onCompleteMsg.getData().putParcelable(
-                                DcTracker.DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST,
-                                networkRequest.getNativeNetworkRequest());
+                                DcTracker.DATA_COMPLETE_MSG_EXTRA_NETWORK_REQUEST, networkRequest);
                         mPendingHandovers.put(onCompleteMsg, handoverParams);
                         requestNetworkInternal(networkRequest, DcTracker.REQUEST_TYPE_HANDOVER,
                                 targetTransport, onCompleteMsg);
@@ -470,20 +414,21 @@
         }
     }
 
-    private void onDataHandoverSetupCompleted(NetworkRequest request, boolean success,
+    private void onDataHandoverSetupCompleted(NetworkRequest networkRequest, boolean success,
                                               int targetTransport, boolean fallback,
                                               HandoverParams handoverParams) {
-        log("onDataHandoverSetupCompleted: " + request + ", success=" + success
+        log("onDataHandoverSetupCompleted: " + networkRequest + ", success=" + success
                 + ", targetTransport="
                 + AccessNetworkConstants.transportTypeToString(targetTransport)
                 + ", fallback=" + fallback);
 
-        TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(request, mPhone);
         // At this point, handover setup has been completed on the target transport.
         // If it succeeded, or it failed without falling back to the original transport,
         // we should release the request from the original transport.
         if (!fallback) {
-            int originTransport = DataUtils.getSourceTransport(targetTransport);
+            int originTransport = (targetTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                    ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
+                    : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
             int releaseType = success
                     ? DcTracker.RELEASE_TYPE_HANDOVER
                     // If handover fails, we need to tear down the existing connection, so the
@@ -527,30 +472,17 @@
         mLocalLog.log(s);
     }
 
-    /**
-     * Dump the state of telephony network factory
-     *
-     * @param fd File descriptor
-     * @param writer Print writer
-     * @param args Arguments
-     */
     public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
         final IndentingPrintWriter pw = new IndentingPrintWriter(writer, "  ");
-        pw.println("TelephonyNetworkFactory-" + mPhone.getPhoneId());
-        pw.increaseIndent();
         pw.println("Network Requests:");
         pw.increaseIndent();
-        for (Map.Entry<TelephonyNetworkRequest, Integer> entry : mNetworkRequests.entrySet()) {
-            TelephonyNetworkRequest nr = entry.getKey();
+        for (HashMap.Entry<NetworkRequest, Integer> entry : mNetworkRequests.entrySet()) {
+            NetworkRequest nr = entry.getKey();
             int transport = entry.getValue();
             pw.println(nr + (transport != AccessNetworkConstants.TRANSPORT_TYPE_INVALID
                     ? (" applied on " + transport) : " not applied"));
         }
-        pw.decreaseIndent();
-        pw.print("Local logs:");
-        pw.increaseIndent();
         mLocalLog.dump(fd, pw, args);
         pw.decreaseIndent();
-        pw.decreaseIndent();
     }
 }
diff --git a/src/java/com/android/internal/telephony/dataconnection/TransportManager.java b/src/java/com/android/internal/telephony/dataconnection/TransportManager.java
index 63358f4..805ca66 100644
--- a/src/java/com/android/internal/telephony/dataconnection/TransportManager.java
+++ b/src/java/com/android/internal/telephony/dataconnection/TransportManager.java
@@ -16,24 +16,44 @@
 
 package com.android.internal.telephony.dataconnection;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.StringDef;
+import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
 import android.os.RegistrantList;
+import android.os.SystemProperties;
 import android.telephony.AccessNetworkConstants;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.Annotation.ApnType;
 import android.telephony.CarrierConfigManager;
 import android.telephony.data.ApnSetting;
+import android.util.IndentingPrintWriter;
 import android.util.LocalLog;
+import android.util.SparseArray;
 import android.util.SparseIntArray;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.data.AccessNetworksManager;
-import com.android.internal.telephony.data.TelephonyNetworkFactory;
+import com.android.internal.telephony.RIL;
+import com.android.internal.telephony.dataconnection.AccessNetworksManager.QualifiedNetworks;
+import com.android.internal.telephony.util.ArrayUtils;
 import com.android.telephony.Rlog;
 
-import java.util.concurrent.TimeUnit;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayDeque;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.stream.Collectors;
 
 /**
  * This class represents the transport manager which manages available transports (i.e. WWAN or
@@ -78,22 +98,87 @@
 public class TransportManager extends Handler {
     private final String mLogTag;
 
+    // Key is the access network, value is the transport.
+    private static final Map<Integer, Integer> ACCESS_NETWORK_TRANSPORT_TYPE_MAP;
+
+    static {
+        ACCESS_NETWORK_TRANSPORT_TYPE_MAP = new HashMap<>();
+        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.GERAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.UTRAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.EUTRAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.CDMA2000,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.NGRAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        ACCESS_NETWORK_TRANSPORT_TYPE_MAP.put(AccessNetworkType.IWLAN,
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
+    }
+
     private static final int EVENT_QUALIFIED_NETWORKS_CHANGED = 1;
 
-    private static final int EVENT_EVALUATE_TRANSPORT_PREFERENCE = 2;
+    private static final int EVENT_UPDATE_AVAILABLE_NETWORKS = 2;
 
-    // Delay the re-evaluation if transport fall back. QNS will need to quickly change the
-    // preference back to the original transport to avoid another handover request.
-    private static final long FALL_BACK_REEVALUATE_DELAY_MILLIS = TimeUnit.SECONDS.toMillis(3);
+    public static final String SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE =
+            "ro.telephony.iwlan_operation_mode";
+
+    @Retention(RetentionPolicy.SOURCE)
+    @StringDef(prefix = {"IWLAN_OPERATION_MODE_"},
+            value = {
+                    IWLAN_OPERATION_MODE_DEFAULT,
+                    IWLAN_OPERATION_MODE_LEGACY,
+                    IWLAN_OPERATION_MODE_AP_ASSISTED})
+    public @interface IwlanOperationMode {}
+
+    /**
+     * IWLAN default mode. On device that has IRadio 1.4 or above, it means
+     * {@link #IWLAN_OPERATION_MODE_AP_ASSISTED}. On device that has IRadio 1.3 or below, it means
+     * {@link #IWLAN_OPERATION_MODE_LEGACY}.
+     */
+    public static final String IWLAN_OPERATION_MODE_DEFAULT = "default";
+
+    /**
+     * IWLAN legacy mode. IWLAN is completely handled by the modem, and when the device is on
+     * IWLAN, modem reports IWLAN as a RAT.
+     */
+    public static final String IWLAN_OPERATION_MODE_LEGACY = "legacy";
+
+    /**
+     * IWLAN application processor assisted mode. IWLAN is handled by the bound IWLAN data service
+     * and network service separately.
+     */
+    public static final String IWLAN_OPERATION_MODE_AP_ASSISTED = "AP-assisted";
 
     private final Phone mPhone;
 
-    private final LocalLog mLocalLog = new LocalLog(64);
+    private final LocalLog mLocalLog = new LocalLog(100);
+
+    /** The available transports. Must be one or more of AccessNetworkConstants.TransportType.XXX */
+    private final int[] mAvailableTransports;
 
     @Nullable
     private AccessNetworksManager mAccessNetworksManager;
 
     /**
+     * Current available networks. The key is the APN type, and the value is the available network
+     * list in the preferred order.
+     */
+    private final SparseArray<int[]> mCurrentAvailableNetworks;
+
+    /**
+     * The queued available networks list.
+     */
+    private final ArrayDeque<List<QualifiedNetworks>> mQueuedNetworksList;
+
+    /**
+     * The current transport of the APN type. The key is the APN type, and the value is the
+     * transport.
+     */
+    private final Map<Integer, Integer> mCurrentTransports;
+
+    /**
      * The pending handover list. This is a list of APNs that are being handover to the new
      * transport. The entry will be removed once handover is completed. The key
      * is the APN type, and the value is the target transport that the APN is handovered to.
@@ -138,24 +223,39 @@
 
     public TransportManager(Phone phone) {
         mPhone = phone;
+        mCurrentAvailableNetworks = new SparseArray<>();
+        mCurrentTransports = new ConcurrentHashMap<>();
         mPendingHandoverApns = new SparseIntArray();
         mHandoverNeededEventRegistrants = new RegistrantList();
+        mQueuedNetworksList = new ArrayDeque<>();
         mLogTag = TransportManager.class.getSimpleName() + "-" + mPhone.getPhoneId();
-        mAccessNetworksManager = mPhone.getAccessNetworksManager();
-        mAccessNetworksManager.registerForQualifiedNetworksChanged(this,
-                EVENT_QUALIFIED_NETWORKS_CHANGED);
+
+        if (isInLegacyMode()) {
+            log("operates in legacy mode.");
+            // For legacy mode, WWAN is the only transport to handle all data connections, even
+            // the IWLAN ones.
+            mAvailableTransports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN};
+        } else {
+            log("operates in AP-assisted mode.");
+            mAccessNetworksManager = new AccessNetworksManager(phone);
+            mAccessNetworksManager.registerForQualifiedNetworksChanged(this,
+                    EVENT_QUALIFIED_NETWORKS_CHANGED);
+            mAvailableTransports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                    AccessNetworkConstants.TRANSPORT_TYPE_WLAN};
+        }
     }
 
     @Override
     public void handleMessage(Message msg) {
         switch (msg.what) {
             case EVENT_QUALIFIED_NETWORKS_CHANGED:
-                if (!hasMessages(EVENT_EVALUATE_TRANSPORT_PREFERENCE)) {
-                    sendEmptyMessage(EVENT_EVALUATE_TRANSPORT_PREFERENCE);
-                }
+                AsyncResult ar = (AsyncResult) msg.obj;
+                List<QualifiedNetworks> networks = (List<QualifiedNetworks>) ar.result;
+                mQueuedNetworksList.add(networks);
+                sendEmptyMessage(EVENT_UPDATE_AVAILABLE_NETWORKS);
                 break;
-            case EVENT_EVALUATE_TRANSPORT_PREFERENCE:
-                evaluateTransportPreference();
+            case EVENT_UPDATE_AVAILABLE_NETWORKS:
+                updateAvailableNetworks();
                 break;
             default:
                 loge("Unexpected event " + msg.what);
@@ -163,6 +263,56 @@
         }
     }
 
+    private boolean isHandoverNeeded(QualifiedNetworks newNetworks) {
+        int apnType = newNetworks.apnType;
+        int[] newNetworkList = newNetworks.qualifiedNetworks;
+        int[] currentNetworkList = mCurrentAvailableNetworks.get(apnType);
+
+        if (ArrayUtils.isEmpty(currentNetworkList)
+                && ACCESS_NETWORK_TRANSPORT_TYPE_MAP.get(newNetworkList[0])
+                == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
+            // This is a special case that when first time boot up in airplane mode with wifi on,
+            // qualified network service reports IWLAN as the preferred network. Although there
+            // is no live data connection on cellular, there might be network requests which were
+            // already sent to cellular DCT. In this case, we still need to handover the network
+            // request to the new transport.
+            return true;
+        }
+
+        // If the current network list is empty, but the new network list is not, then we can
+        // directly setup data on the new network. If the current network list is not empty, but
+        // the new network is, then we can tear down the data directly. Therefore if one of the
+        // list is empty, then we don't need to do handover.
+        if (ArrayUtils.isEmpty(newNetworkList) || ArrayUtils.isEmpty(currentNetworkList)) {
+            return false;
+        }
+
+
+        if (mPendingHandoverApns.get(newNetworks.apnType)
+                == ACCESS_NETWORK_TRANSPORT_TYPE_MAP.get(newNetworkList[0])) {
+            log("Handover not needed. There is already an ongoing handover.");
+            return false;
+        }
+
+        // The list is networks in the preferred order. For now we only pick the first element
+        // because it's the most preferred. In the future we should also consider the rest in the
+        // list, for example, the first one violates carrier/user policy.
+        return !ACCESS_NETWORK_TRANSPORT_TYPE_MAP.get(newNetworkList[0])
+                .equals(getCurrentTransport(newNetworks.apnType));
+    }
+
+    private static boolean areNetworksValid(QualifiedNetworks networks) {
+        if (networks.qualifiedNetworks == null || networks.qualifiedNetworks.length == 0) {
+            return false;
+        }
+        for (int network : networks.qualifiedNetworks) {
+            if (!ACCESS_NETWORK_TRANSPORT_TYPE_MAP.containsKey(network)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     /**
      * Set the current transport of apn type.
      *
@@ -170,68 +320,143 @@
      * @param transport The transport. Must be WWAN or WLAN.
      */
     private synchronized void setCurrentTransport(@ApnType int apnType, int transport) {
-        mAccessNetworksManager.setCurrentTransport(apnType, transport);
+        Integer previousTransport = mCurrentTransports.put(apnType, transport);
+        if (previousTransport == null || previousTransport != transport) {
+            logl("setCurrentTransport: apnType=" + ApnSetting.getApnTypeString(apnType)
+                    + ", transport=" + AccessNetworkConstants.transportTypeToString(transport));
+        }
     }
 
     private boolean isHandoverPending() {
         return mPendingHandoverApns.size() > 0;
     }
 
-    /**
-     * Evaluate the preferred transport for each APN type to see if handover is needed.
-     */
-    private void evaluateTransportPreference() {
-        // Simultaneously handover is not supported today. Preference will be re-evaluated after
-        // handover completed.
-        if (isHandoverPending()) return;
-        logl("evaluateTransportPreference");
-        for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) {
-            int targetTransport = mAccessNetworksManager.getPreferredTransport(apnType);
-            if (targetTransport != mAccessNetworksManager.getCurrentTransport(apnType)) {
-                logl("Handover started for APN type: "
-                        + ApnSetting.getApnTypeString(apnType)
-                        + ", target transport: "
-                        + AccessNetworkConstants.transportTypeToString(targetTransport));
-                mPendingHandoverApns.put(apnType, targetTransport);
-                mHandoverNeededEventRegistrants.notifyResult(
-                        new HandoverParams(apnType, targetTransport,
-                                (success, fallback) -> {
-                                    // The callback for handover completed.
-                                    if (success) {
-                                        logl("Handover succeeded for APN type "
-                                                + ApnSetting.getApnTypeString(apnType));
-                                    } else {
-                                        logl("APN type "
-                                                + ApnSetting.getApnTypeString(apnType)
-                                                + " handover to "
-                                                + AccessNetworkConstants.transportTypeToString(
-                                                targetTransport) + " failed"
-                                                + ", fallback=" + fallback);
-                                    }
+    private void updateAvailableNetworks() {
+        if (isHandoverPending()) {
+            log("There's ongoing handover. Will update networks once handover completed.");
+            return;
+        }
 
-                                    long delay = 0;
-                                    if (fallback) {
-                                        // No need to change the preference because we should
-                                        // fallback. Re-evaluate after few seconds to give QNS
-                                        // some time to change the preference back to the original
-                                        // transport.
-                                        delay = FALL_BACK_REEVALUATE_DELAY_MILLIS;
-                                    } else {
-                                        // If handover succeeds or failed without falling back
-                                        // to the original transport, we should move to the new
-                                        // transport (even if it is failed).
-                                        setCurrentTransport(apnType, targetTransport);
-                                    }
-                                    mPendingHandoverApns.delete(apnType);
-                                    sendEmptyMessageDelayed(EVENT_EVALUATE_TRANSPORT_PREFERENCE,
-                                            delay);
-                                }));
+        if (mQueuedNetworksList.size() == 0) {
+            log("Nothing in the available network list queue.");
+            return;
+        }
 
-                // Return here instead of processing the next APN type. The next APN type for
-                // handover will be evaluate again once current handover is completed.
-                return;
+        List<QualifiedNetworks> networksList = mQueuedNetworksList.remove();
+        logl("updateAvailableNetworks: " + networksList);
+        for (QualifiedNetworks networks : networksList) {
+            if (areNetworksValid(networks)) {
+                if (isHandoverNeeded(networks)) {
+                    // If handover is needed, perform the handover works. For now we only pick the
+                    // first element because it's the most preferred. In the future we should also
+                    // consider the rest in the list, for example, the first one violates
+                    // carrier/user policy.
+                    int targetTransport = ACCESS_NETWORK_TRANSPORT_TYPE_MAP.get(
+                            networks.qualifiedNetworks[0]);
+                    logl("Handover needed for APN type: "
+                            + ApnSetting.getApnTypeString(networks.apnType)
+                            + ", target transport: "
+                            + AccessNetworkConstants.transportTypeToString(targetTransport));
+                    mPendingHandoverApns.put(networks.apnType, targetTransport);
+                    mHandoverNeededEventRegistrants.notifyResult(
+                            new HandoverParams(networks.apnType, targetTransport,
+                                    (success, fallback) -> {
+                                        // The callback for handover completed.
+                                        if (success) {
+                                            logl("Handover succeeded.");
+                                        } else {
+                                            logl("APN type "
+                                                    + ApnSetting.getApnTypeString(networks.apnType)
+                                                    + " handover to "
+                                                    + AccessNetworkConstants.transportTypeToString(
+                                                    targetTransport) + " failed."
+                                                    + ", fallback=" + fallback);
+                                        }
+                                        if (success || !fallback) {
+                                            // If handover succeeds or failed without falling back
+                                            // to the original transport, we should move to the new
+                                            // transport (even if it is failed).
+                                            setCurrentTransport(networks.apnType, targetTransport);
+                                        }
+                                        mPendingHandoverApns.delete(networks.apnType);
+
+                                        // If there are still pending available network changes, we
+                                        // need to process the rest.
+                                        if (mQueuedNetworksList.size() > 0) {
+                                            sendEmptyMessage(EVENT_UPDATE_AVAILABLE_NETWORKS);
+                                        }
+                                    }));
+                }
+                mCurrentAvailableNetworks.put(networks.apnType, networks.qualifiedNetworks);
+            } else {
+                loge("Invalid networks received: " + networks);
             }
         }
+
+        // If there are still pending available network changes, we need to process the rest.
+        if (mQueuedNetworksList.size() > 0) {
+            sendEmptyMessage(EVENT_UPDATE_AVAILABLE_NETWORKS);
+        }
+    }
+
+    /**
+     * @return The available transports. Note that on legacy devices, the only available transport
+     * would be WWAN only. If the device is configured as AP-assisted mode, the available transport
+     * will always be WWAN and WLAN (even if the device is not camped on IWLAN).
+     * See {@link #isInLegacyMode()} for mode details.
+     */
+    public synchronized @NonNull int[] getAvailableTransports() {
+        return mAvailableTransports;
+    }
+
+    /**
+     * @return {@code true} if the device operates in legacy mode, otherwise {@code false}.
+     */
+    public boolean isInLegacyMode() {
+        // Get IWLAN operation mode from the system property. If the system property is configured
+        // to default or not configured, the mode is tied to IRadio version. For 1.4 or above, it's
+        // AP-assisted mode, for 1.3 or below, it's legacy mode.
+        String mode = SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE);
+
+        if (mode.equals(IWLAN_OPERATION_MODE_AP_ASSISTED)) {
+            return false;
+        } else if (mode.equals(IWLAN_OPERATION_MODE_LEGACY)) {
+            return true;
+        }
+
+        return mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_1_4);
+    }
+
+    /**
+     * Get the transport based on the APN type.
+     *
+     * @param apnType APN type
+     * @return The transport type
+     */
+    public int getCurrentTransport(@ApnType int apnType) {
+        // In legacy mode, always route to cellular.
+        if (isInLegacyMode()) {
+            return AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
+        }
+
+        // If we can't find the corresponding transport, always route to cellular.
+        return mCurrentTransports.get(apnType) == null
+                ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN : mCurrentTransports.get(apnType);
+    }
+
+    /**
+     * Check if there is any APN type of network preferred on IWLAN.
+     *
+     * @return {@code true} if there is any APN preferred on IWLAN, otherwise {@code false}.
+     */
+    public boolean isAnyApnPreferredOnIwlan() {
+        for (int i = 0; i < mCurrentAvailableNetworks.size(); i++) {
+            int[] networkList = mCurrentAvailableNetworks.valueAt(i);
+            if (networkList.length > 0 && networkList[0] == AccessNetworkType.IWLAN) {
+                return true;
+            }
+        }
+        return false;
     }
 
     /**
@@ -264,6 +489,98 @@
         }
     }
 
+    /**
+     * Get the latest preferred transport. Note that the current transport only changed after
+     * handover is completed, and there might be queued update network requests not processed yet.
+     * This method is used to get the latest preference sent from qualified networks service.
+     *
+     * @param apnType APN type
+     * @return The preferred transport. {@link AccessNetworkConstants#TRANSPORT_TYPE_INVALID} if
+     * unknown, unavailable, or QNS explicitly specifies data connection of the APN type should not
+     * be brought up on either cellular or IWLAN.
+     */
+    public @TransportType int getPreferredTransport(@ApnType int apnType) {
+        // Since the latest updates from QNS is stored at the end of the queue, so if we want to
+        // check what's the latest, we should iterate the queue reversely.
+        Iterator<List<QualifiedNetworks>> it = mQueuedNetworksList.descendingIterator();
+        while (it.hasNext()) {
+            List<QualifiedNetworks> networksList = it.next();
+            for (QualifiedNetworks networks : networksList) {
+                if (networks.apnType == apnType) {
+                    if (networks.qualifiedNetworks.length > 0) {
+                        return ACCESS_NETWORK_TRANSPORT_TYPE_MAP.get(networks.qualifiedNetworks[0]);
+                    }
+                    // This is the case that QNS explicitly specifies no data allowed on neither
+                    // cellular nor IWLAN.
+                    return AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+                }
+            }
+        }
+
+        // if not found in the queue, see if it's in the current available networks.
+        int[] currentNetworkList = mCurrentAvailableNetworks.get(apnType);
+        if (currentNetworkList != null) {
+            if (currentNetworkList.length > 0) {
+                return ACCESS_NETWORK_TRANSPORT_TYPE_MAP.get(currentNetworkList[0]);
+            }
+            // This is the case that QNS explicitly specifies no data allowed on neither
+            // cellular nor IWLAN.
+            return AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
+        }
+
+        // If no input from QNS, for example in legacy mode, the default preferred transport should
+        // be cellular.
+        return AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
+    }
+
+
+    /**
+     * Dump the state of transport manager
+     *
+     * @param fd File descriptor
+     * @param printwriter Print writer
+     * @param args Arguments
+     */
+    public void dump(FileDescriptor fd, PrintWriter printwriter, String[] args) {
+        IndentingPrintWriter pw = new IndentingPrintWriter(printwriter, "  ");
+        pw.println(mLogTag);
+        pw.increaseIndent();
+        pw.println("mAvailableTransports=[" + Arrays.stream(mAvailableTransports)
+                .mapToObj(AccessNetworkConstants::transportTypeToString)
+                .collect(Collectors.joining(",")) + "]");
+        pw.println("mCurrentAvailableNetworks=");
+        pw.increaseIndent();
+        for (int i = 0; i < mCurrentAvailableNetworks.size(); i++) {
+            pw.println("APN type "
+                    + ApnSetting.getApnTypeString(mCurrentAvailableNetworks.keyAt(i))
+                    + ": [" + Arrays.stream(mCurrentAvailableNetworks.valueAt(i))
+                    .mapToObj(AccessNetworkType::toString)
+                    .collect(Collectors.joining(",")) + "]");
+        }
+        pw.decreaseIndent();
+        pw.println("mQueuedNetworksList=" + mQueuedNetworksList);
+        pw.println("mPendingHandoverApns=" + mPendingHandoverApns);
+        pw.println("mCurrentTransports=");
+        pw.increaseIndent();
+        for (Map.Entry<Integer, Integer> entry : mCurrentTransports.entrySet()) {
+            pw.println("APN type " + ApnSetting.getApnTypeString(entry.getKey())
+                    + ": " + AccessNetworkConstants.transportTypeToString(entry.getValue()));
+        }
+        pw.decreaseIndent();
+        pw.println("isInLegacy=" + isInLegacyMode());
+        pw.println("IWLAN operation mode="
+                + SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE));
+        if (mAccessNetworksManager != null) {
+            mAccessNetworksManager.dump(fd, pw, args);
+        }
+        pw.println("Local logs=");
+        pw.increaseIndent();
+        mLocalLog.dump(fd, pw, args);
+        pw.decreaseIndent();
+        pw.decreaseIndent();
+        pw.flush();
+    }
+
     private void logl(String s) {
         log(s);
         mLocalLog.log(s);
diff --git a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
index 276d82a..fb892e4 100644
--- a/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
+++ b/src/java/com/android/internal/telephony/emergency/EmergencyNumberTracker.java
@@ -30,7 +30,6 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.ServiceState;
-import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.emergency.EmergencyNumber;
 import android.telephony.emergency.EmergencyNumber.EmergencyCallRouting;
@@ -113,11 +112,11 @@
     private List<EmergencyNumber> mEmergencyNumberListFromTestMode = new ArrayList<>();
     private List<EmergencyNumber> mEmergencyNumberList = new ArrayList<>();
 
-    private final LocalLog mEmergencyNumberListDatabaseLocalLog = new LocalLog(16);
-    private final LocalLog mEmergencyNumberListRadioLocalLog = new LocalLog(16);
-    private final LocalLog mEmergencyNumberListPrefixLocalLog = new LocalLog(16);
-    private final LocalLog mEmergencyNumberListTestModeLocalLog = new LocalLog(16);
-    private final LocalLog mEmergencyNumberListLocalLog = new LocalLog(16);
+    private final LocalLog mEmergencyNumberListDatabaseLocalLog = new LocalLog(20);
+    private final LocalLog mEmergencyNumberListRadioLocalLog = new LocalLog(20);
+    private final LocalLog mEmergencyNumberListPrefixLocalLog = new LocalLog(20);
+    private final LocalLog mEmergencyNumberListTestModeLocalLog = new LocalLog(20);
+    private final LocalLog mEmergencyNumberListLocalLog = new LocalLog(20);
 
     /** Event indicating the update for the emergency number list from the radio. */
     private static final int EVENT_UNSOL_EMERGENCY_NUMBER_LIST = 1;
@@ -263,23 +262,6 @@
         return false;
     }
 
-    /**
-     * Checks if it's sim absent to decide whether to apply sim-absent emergency numbers from 3gpp
-     */
-    @VisibleForTesting
-    public boolean isSimAbsent() {
-        for (Phone phone: PhoneFactory.getPhones()) {
-            int slotId = SubscriptionController.getInstance().getSlotIndex(phone.getSubId());
-            // If slot id is invalid, it means that there is no sim card.
-            if (slotId != SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
-                // If there is at least one sim active, sim is not absent; it returns false
-                logd("found sim in slotId: " + slotId + " subid: " + phone.getSubId());
-                return false;
-            }
-        }
-        return true;
-    }
-
     private void initializeDatabaseEmergencyNumberList() {
         // If country iso has been cached when listener is set, don't need to cache the initial
         // country iso and initial database.
@@ -451,16 +433,17 @@
     }
 
     private void cacheEmergencyDatabaseByCountry(String countryIso) {
-        int assetsDatabaseVersion;
+        BufferedInputStream inputStream = null;
+        ProtobufEccData.AllInfo allEccMessages = null;
+        int assetsDatabaseVersion = INVALID_DATABASE_VERSION;
 
         // Read the Asset emergency number database
         List<EmergencyNumber> updatedAssetEmergencyNumberList = new ArrayList<>();
-        // try-with-resource. The 2 streams are auto closeable.
-        try (BufferedInputStream inputStream = new BufferedInputStream(
-                mPhone.getContext().getAssets().open(EMERGENCY_NUMBER_DB_ASSETS_FILE));
-             GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream)) {
-            ProtobufEccData.AllInfo allEccMessages = ProtobufEccData.AllInfo.parseFrom(
-                    readInputStreamToByteArray(gzipInputStream));
+        try {
+            inputStream = new BufferedInputStream(
+                    mPhone.getContext().getAssets().open(EMERGENCY_NUMBER_DB_ASSETS_FILE));
+            allEccMessages = ProtobufEccData.AllInfo.parseFrom(readInputStreamToByteArray(
+                    new GZIPInputStream(inputStream)));
             assetsDatabaseVersion = allEccMessages.revision;
             logd(countryIso + " asset emergency database is loaded. Ver: " + assetsDatabaseVersion
                     + " Phone Id: " + mPhone.getPhoneId());
@@ -475,7 +458,16 @@
             EmergencyNumber.mergeSameNumbersInEmergencyNumberList(updatedAssetEmergencyNumberList);
         } catch (IOException ex) {
             logw("Cache asset emergency database failure: " + ex);
-            return;
+        } finally {
+            // close quietly by catching non-runtime exceptions.
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (RuntimeException rethrown) {
+                    throw rethrown;
+                } catch (Exception ignored) {
+                }
+            }
         }
 
         // Cache OTA emergency number database
@@ -485,6 +477,7 @@
         if (otaDatabaseVersion == INVALID_DATABASE_VERSION
                 && assetsDatabaseVersion == INVALID_DATABASE_VERSION) {
             loge("No database available. Phone Id: " + mPhone.getPhoneId());
+            return;
         } else if (assetsDatabaseVersion > otaDatabaseVersion) {
             logd("Using Asset Emergency database. Version: " + assetsDatabaseVersion);
             mCurrentDatabaseVersion = assetsDatabaseVersion;
@@ -495,32 +488,27 @@
     }
 
     private int cacheOtaEmergencyNumberDatabase() {
+        FileInputStream fileInputStream = null;
+        BufferedInputStream inputStream = null;
         ProtobufEccData.AllInfo allEccMessages = null;
         int otaDatabaseVersion = INVALID_DATABASE_VERSION;
 
         // Read the OTA emergency number database
         List<EmergencyNumber> updatedOtaEmergencyNumberList = new ArrayList<>();
-
-        File file;
-        // If OTA File partition is not available, try to reload the default one.
-        if (mOverridedOtaDbParcelFileDescriptor == null) {
-            file = new File(Environment.getDataDirectory(), EMERGENCY_NUMBER_DB_OTA_FILE_PATH);
-        } else {
-            try {
-                file = ParcelFileDescriptor.getFile(mOverridedOtaDbParcelFileDescriptor
-                        .getFileDescriptor()).getAbsoluteFile();
-            } catch (IOException ex) {
-                loge("Cache ota emergency database IOException: " + ex);
-                return INVALID_DATABASE_VERSION;
+        try {
+            // If OTA File partition is not available, try to reload the default one.
+            if (mOverridedOtaDbParcelFileDescriptor == null) {
+                fileInputStream = new FileInputStream(
+                        new File(Environment.getDataDirectory(),
+                                EMERGENCY_NUMBER_DB_OTA_FILE_PATH));
+            } else {
+                File file = ParcelFileDescriptor
+                        .getFile(mOverridedOtaDbParcelFileDescriptor.getFileDescriptor());
+                fileInputStream = new FileInputStream(new File(file.getAbsolutePath()));
             }
-        }
-
-        // try-with-resource. Those 3 streams are all auto closeable.
-        try (FileInputStream fileInputStream = new FileInputStream(file);
-             BufferedInputStream inputStream = new BufferedInputStream(fileInputStream);
-             GZIPInputStream gzipInputStream = new GZIPInputStream(inputStream)) {
-            allEccMessages = ProtobufEccData.AllInfo.parseFrom(
-                    readInputStreamToByteArray(gzipInputStream));
+            inputStream = new BufferedInputStream(fileInputStream);
+            allEccMessages = ProtobufEccData.AllInfo.parseFrom(readInputStreamToByteArray(
+                    new GZIPInputStream(inputStream)));
             String countryIso = getLastKnownEmergencyCountryIso();
             logd(countryIso + " ota emergency database is loaded. Ver: " + otaDatabaseVersion);
             otaDatabaseVersion = allEccMessages.revision;
@@ -535,7 +523,24 @@
             EmergencyNumber.mergeSameNumbersInEmergencyNumberList(updatedOtaEmergencyNumberList);
         } catch (IOException ex) {
             loge("Cache ota emergency database IOException: " + ex);
-            return INVALID_DATABASE_VERSION;
+        } finally {
+            // Close quietly by catching non-runtime exceptions.
+            if (inputStream != null) {
+                try {
+                    inputStream.close();
+                } catch (RuntimeException rethrown) {
+                    throw rethrown;
+                } catch (Exception ignored) {
+                }
+            }
+            if (fileInputStream != null) {
+                try {
+                    fileInputStream.close();
+                } catch (RuntimeException rethrown) {
+                    throw rethrown;
+                } catch (Exception ignored) {
+                }
+            }
         }
 
         // Use a valid database that has higher version.
@@ -714,16 +719,7 @@
         if (number == null) {
             return false;
         }
-
-        // Do not treat SIP address as emergency number
-        if (PhoneNumberUtils.isUriNumber(number)) {
-            return false;
-        }
-
-        // Strip the separators from the number before comparing it
-        // to the list.
-        number = PhoneNumberUtils.extractNetworkPortionAlt(number);
-
+        number = PhoneNumberUtils.stripSeparators(number);
         if (!mEmergencyNumberListFromRadio.isEmpty()) {
             for (EmergencyNumber num : mEmergencyNumberList) {
                 // According to com.android.i18n.phonenumbers.ShortNumberInfo, in
@@ -738,25 +734,18 @@
                 }
                 if (exactMatch) {
                     if (num.getNumber().equals(number)) {
-                        logd("Found in mEmergencyNumberList [exact match] ");
                         return true;
                     }
                 } else {
                     if (number.startsWith(num.getNumber())) {
-                        logd("Found in mEmergencyNumberList [not exact match] ");
                         return true;
                     }
                 }
             }
             return false;
         } else {
-            boolean inEccList = isEmergencyNumberFromEccList(number, exactMatch);
-            boolean inEmergencyNumberDb = isEmergencyNumberFromDatabase(number);
-            boolean inEmergencyNumberTestList = isEmergencyNumberForTest(number);
-            logd("Search results - inRilEccList:" + inEccList
-                    + " inEmergencyNumberDb:" + inEmergencyNumberDb + " inEmergencyNumberTestList: "
-                    + inEmergencyNumberTestList);
-            return inEccList || inEmergencyNumberDb || inEmergencyNumberTestList;
+            return isEmergencyNumberFromEccList(number, exactMatch)
+                    || isEmergencyNumberFromDatabase(number) || isEmergencyNumberForTest(number);
         }
     }
 
@@ -870,7 +859,7 @@
                 emergencyNumberList.add(getLabeledEmergencyNumberForEcclist(emergencyNum));
             }
         }
-        emergencyNumbers = ((isSimAbsent()) ? "112,911,000,08,110,118,119,999" : "112,911");
+        emergencyNumbers = ((slotId < 0) ? "112,911,000,08,110,118,119,999" : "112,911");
         for (String emergencyNum : emergencyNumbers.split(",")) {
             emergencyNumberList.add(getLabeledEmergencyNumberForEcclist(emergencyNum));
         }
@@ -956,9 +945,6 @@
         // If the number passed in is null, just return false:
         if (number == null) return false;
 
-        /// M: preprocess number for emergency check @{
-        // Move following logic to isEmergencyNumber()
-
         // If the number passed in is a SIP address, return false, since the
         // concept of "emergency numbers" is only meaningful for calls placed
         // over the cell network.
@@ -966,76 +952,73 @@
         // since the whole point of extractNetworkPortionAlt() is to filter out
         // any non-dialable characters (which would turn 'abc911def@example.com'
         // into '911', for example.))
-        //if (PhoneNumberUtils.isUriNumber(number)) {
-        //    return false;
-        //}
+        if (PhoneNumberUtils.isUriNumber(number)) {
+            return false;
+        }
 
         // Strip the separators from the number before comparing it
         // to the list.
-        //number = PhoneNumberUtils.extractNetworkPortionAlt(number);
-        /// @}
+        number = PhoneNumberUtils.extractNetworkPortionAlt(number);
 
         String emergencyNumbers = "";
         int slotId = SubscriptionController.getInstance().getSlotIndex(mPhone.getSubId());
 
-        String ecclist = null;
+        // retrieve the list of emergency numbers
+        // check read-write ecclist property first
+        String ecclist = (slotId <= 0) ? "ril.ecclist" : ("ril.ecclist" + slotId);
+
+        emergencyNumbers = SystemProperties.get(ecclist, "");
+
         String countryIso = getLastKnownEmergencyCountryIso();
+        logd("slotId:" + slotId + " country:" + countryIso + " emergencyNumbers: "
+                +  emergencyNumbers);
 
-        if (!mPhone.getHalVersion().greaterOrEqual(new HalVersion(1, 4))) {
-            //only use ril ecc list for older devices with HAL < 1.4
-            // check read-write ecclist property first
-            ecclist = (slotId <= 0) ? "ril.ecclist" : ("ril.ecclist" + slotId);
-            emergencyNumbers = SystemProperties.get(ecclist, "");
+        if (TextUtils.isEmpty(emergencyNumbers)) {
+            // then read-only ecclist property since old RIL only uses this
+            emergencyNumbers = SystemProperties.get("ro.ril.ecclist");
+        }
 
-            logd("slotId:" + slotId + " country:" + countryIso + " emergencyNumbers: "
-                + emergencyNumbers);
-
-            if (TextUtils.isEmpty(emergencyNumbers)) {
-                // then read-only ecclist property since old RIL only uses this
-                emergencyNumbers = SystemProperties.get("ro.ril.ecclist");
-            }
-
-            if (!TextUtils.isEmpty(emergencyNumbers)) {
-                // searches through the comma-separated list for a match,
-                // return true if one is found.
-                for (String emergencyNum : emergencyNumbers.split(",")) {
-                    // According to com.android.i18n.phonenumbers.ShortNumberInfo, in
-                    // these countries, if extra digits are added to an emergency number,
-                    // it no longer connects to the emergency service.
-                    if (useExactMatch || countryIso.equals("br") || countryIso.equals("cl")
+        if (!TextUtils.isEmpty(emergencyNumbers)) {
+            // searches through the comma-separated list for a match,
+            // return true if one is found.
+            for (String emergencyNum : emergencyNumbers.split(",")) {
+                // According to com.android.i18n.phonenumbers.ShortNumberInfo, in
+                // these countries, if extra digits are added to an emergency number,
+                // it no longer connects to the emergency service.
+                if (useExactMatch || countryIso.equals("br") || countryIso.equals("cl")
                         || countryIso.equals("ni")) {
-                        if (number.equals(emergencyNum)) {
-                            return true;
-                        } else {
-                            for (String prefix : mEmergencyNumberPrefix) {
-                                if (number.equals(prefix + emergencyNum)) {
-                                    return true;
-                                }
+                    if (number.equals(emergencyNum)) {
+                        return true;
+                    } else {
+                        for (String prefix : mEmergencyNumberPrefix) {
+                            if (number.equals(prefix + emergencyNum)) {
+                                return true;
                             }
                         }
+                    }
+                } else {
+                    if (number.startsWith(emergencyNum)) {
+                        return true;
                     } else {
-                        if (number.startsWith(emergencyNum)) {
-                            return true;
-                        } else {
-                            for (String prefix : mEmergencyNumberPrefix) {
-                                if (number.startsWith(prefix + emergencyNum)) {
-                                    return true;
-                                }
+                        for (String prefix : mEmergencyNumberPrefix) {
+                            if (number.startsWith(prefix + emergencyNum)) {
+                                return true;
                             }
                         }
                     }
                 }
-                // no matches found against the list!
-                return false;
             }
+            // no matches found against the list!
+            return false;
         }
 
         logd("System property doesn't provide any emergency numbers."
                 + " Use embedded logic for determining ones.");
 
+        // If slot id is invalid, means that there is no sim card.
         // According spec 3GPP TS22.101, the following numbers should be
         // ECC numbers when SIM/USIM is not present.
-        emergencyNumbers = ((isSimAbsent()) ? "112,911,000,08,110,118,119,999" : "112,911");
+        emergencyNumbers = ((slotId < 0) ? "112,911,000,08,110,118,119,999" : "112,911");
 
         for (String emergencyNum : emergencyNumbers.split(",")) {
             if (useExactMatch) {
@@ -1061,34 +1044,32 @@
             }
         }
 
-        if(isSimAbsent()) {
-            // No ecclist system property, so use our own list.
-            if (countryIso != null) {
-                ShortNumberInfo info = ShortNumberInfo.getInstance();
-                if (useExactMatch) {
-                    if (info.isEmergencyNumber(number, countryIso.toUpperCase())) {
-                        return true;
-                    } else {
-                        for (String prefix : mEmergencyNumberPrefix) {
-                            if (info.isEmergencyNumber(prefix + number, countryIso.toUpperCase())) {
-                                return true;
-                            }
-                        }
-                    }
-                    return false;
+        // No ecclist system property, so use our own list.
+        if (countryIso != null) {
+            ShortNumberInfo info = ShortNumberInfo.getInstance();
+            if (useExactMatch) {
+                if (info.isEmergencyNumber(number, countryIso.toUpperCase())) {
+                    return true;
                 } else {
-                    if (info.connectsToEmergencyNumber(number, countryIso.toUpperCase())) {
-                        return true;
-                    } else {
-                        for (String prefix : mEmergencyNumberPrefix) {
-                            if (info.connectsToEmergencyNumber(prefix + number,
-                                    countryIso.toUpperCase())) {
-                                return true;
-                            }
+                    for (String prefix : mEmergencyNumberPrefix) {
+                        if (info.isEmergencyNumber(prefix + number, countryIso.toUpperCase())) {
+                            return true;
                         }
                     }
-                    return false;
                 }
+                return false;
+            } else {
+                if (info.connectsToEmergencyNumber(number, countryIso.toUpperCase())) {
+                    return true;
+                } else {
+                    for (String prefix : mEmergencyNumberPrefix) {
+                        if (info.connectsToEmergencyNumber(prefix + number,
+                                countryIso.toUpperCase())) {
+                            return true;
+                        }
+                    }
+                }
+                return false;
             }
         }
 
diff --git a/src/java/com/android/internal/telephony/euicc/EuiccCardController.java b/src/java/com/android/internal/telephony/euicc/EuiccCardController.java
index f337141..3016ca1 100644
--- a/src/java/com/android/internal/telephony/euicc/EuiccCardController.java
+++ b/src/java/com/android/internal/telephony/euicc/EuiccCardController.java
@@ -40,13 +40,10 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.SubscriptionController;
-import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UiccSlot;
 import com.android.internal.telephony.uicc.euicc.EuiccCard;
 import com.android.internal.telephony.uicc.euicc.EuiccCardErrorException;
-import com.android.internal.telephony.uicc.euicc.EuiccPort;
 import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback;
 
 import java.io.FileDescriptor;
@@ -200,77 +197,19 @@
         }
     }
 
-    private UiccSlot getUiccSlotForEmbeddedCard(String cardId) {
-        int slotId = mUiccController.getUiccSlotForCardId(cardId);
-        UiccSlot slot = mUiccController.getUiccSlot(slotId);
-        if (slot == null) {
-            loge("UiccSlot is null. slotId : " + slotId + " cardId : " + cardId);
-            return null;
-        }
-        if (!slot.isEuicc()) {
-            loge("UiccSlot is not embedded slot : " + slotId + " cardId : " + cardId);
-            return null;
-        }
-        return slot;
-    }
-
     private EuiccCard getEuiccCard(String cardId) {
-        UiccSlot slot = getUiccSlotForEmbeddedCard(cardId);
-        if (slot == null) {
-            return null;
+        UiccController controller = UiccController.getInstance();
+        int slotId = controller.getUiccSlotForCardId(cardId);
+        if (slotId != UiccController.INVALID_SLOT_ID) {
+            UiccSlot slot = controller.getUiccSlot(slotId);
+            if (slot.isEuicc()) {
+                return (EuiccCard) controller.getUiccCardForSlot(slotId);
+            }
         }
-        UiccCard card = slot.getUiccCard();
-        if (card == null) {
-            loge("UiccCard is null. cardId : " + cardId);
-            return null;
-        }
-        return (EuiccCard) card;
-    }
-
-    private EuiccPort getEuiccPortFromIccId(String cardId, String iccid) {
-        UiccSlot slot = getUiccSlotForEmbeddedCard(cardId);
-        if (slot == null) {
-            return null;
-        }
-        UiccCard card = slot.getUiccCard();
-        if (card == null) {
-            loge("UiccCard is null. cardId : " + cardId);
-            return null;
-        }
-        int portIndex = slot.getPortIndexFromIccId(iccid);
-        UiccPort port = card.getUiccPort(portIndex);
-        if (port == null) {
-            loge("UiccPort is null. cardId : " + cardId + " portIndex : " + portIndex);
-            return null;
-        }
-        return (EuiccPort) port;
-    }
-
-    private EuiccPort getFirstActiveEuiccPort(String cardId) {
-        EuiccCard card = getEuiccCard(cardId);
-        if (card == null) {
-            return null;
-        }
-        if (card.getUiccPortList().length > 0 ) {
-            return (EuiccPort) card.getUiccPortList()[0]; // return first active port.
-        }
-        loge("No active ports exists. cardId : " + cardId);
+        loge("EuiccCard is null. CardId : " + cardId);
         return null;
     }
 
-    private EuiccPort getEuiccPort(String cardId, int portIndex) {
-        EuiccCard card = getEuiccCard(cardId);
-        if (card == null) {
-            return null;
-        }
-        UiccPort port = card.getUiccPort(portIndex);
-        if (port == null) {
-            loge("UiccPort is null. cardId : " + cardId + " portIndex : " + portIndex);
-            return null;
-        }
-        return (EuiccPort) port;
-    }
-
     private int getResultCode(Throwable e) {
         if (e instanceof EuiccCardErrorException) {
             return ((EuiccCardErrorException) e).getErrorCode();
@@ -292,8 +231,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -324,7 +263,7 @@
             }
         };
 
-        port.getAllProfiles(cardCb, mEuiccMainThreadHandler);
+        card.getAllProfiles(cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -341,8 +280,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -372,91 +311,7 @@
                     }
                 };
 
-        port.getProfile(iccid, cardCb, mEuiccMainThreadHandler);
-    }
-
-    @Override
-    public void getEnabledProfile(String callingPackage, String cardId, int portIndex,
-            IGetProfileCallback callback) {
-        try {
-            checkCallingPackage(callingPackage);
-        } catch (SecurityException se) {
-            try {
-                callback.onComplete(EuiccCardManager.RESULT_CALLER_NOT_ALLOWED, null);
-            } catch (RemoteException re) {
-                loge("callback onComplete failure after checkCallingPackage.", re);
-            }
-            return;
-        }
-
-        String iccId = null;
-        boolean isValidSlotPort = false;
-        // get the iccid whether or not the port is active
-        for (UiccSlot slot : mUiccController.getUiccSlots()) {
-            if (slot.getEid().equals(cardId)) {
-                // find the matching slot. first validate if the passing port index is valid.
-                if (slot.isValidPortIndex(portIndex)) {
-                    isValidSlotPort = true;
-                    iccId = slot.getIccId(portIndex);
-                }
-            }
-        }
-        if(!isValidSlotPort) {
-            try {
-                callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
-            } catch (RemoteException exception) {
-                loge("getEnabledProfile callback failure due to invalid port slot.",
-                        exception);
-            }
-            return;
-        }
-        // if there is no iccid enabled on this port, return null.
-        if (TextUtils.isEmpty(iccId)) {
-            try {
-                callback.onComplete(EuiccCardManager.RESULT_PROFILE_NOT_FOUND, null);
-            } catch (RemoteException exception) {
-                loge("getEnabledProfile callback failure.", exception);
-            }
-            return;
-        }
-
-        EuiccPort port = getEuiccPort(cardId, portIndex);
-        if (port == null) {
-            // If the port is inactive, send the APDU on the first active port
-            port = getFirstActiveEuiccPort(cardId);
-            if (port == null) {
-                try {
-                    callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
-                } catch (RemoteException exception) {
-                    loge("getEnabledProfile callback failure.", exception);
-                }
-                return;
-            }
-        }
-
-        AsyncResultCallback<EuiccProfileInfo> cardCb = new AsyncResultCallback<EuiccProfileInfo>() {
-            @Override
-            public void onResult(EuiccProfileInfo result) {
-                try {
-                    callback.onComplete(EuiccCardManager.RESULT_OK, result);
-                } catch (RemoteException exception) {
-                    loge("getEnabledProfile callback failure.", exception);
-                }
-            }
-
-            @Override
-            public void onException(Throwable e) {
-                try {
-                    loge("getEnabledProfile callback onException: ", e);
-                    callback.onComplete(getResultCode(e), null);
-                } catch (RemoteException exception) {
-                    loge("getEnabledProfile callback failure.", exception);
-                }
-            }
-        };
-
-        port.getProfile(iccId, cardCb, mEuiccMainThreadHandler);
-
+        card.getProfile(iccid, cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -473,8 +328,8 @@
             return;
         }
 
-        EuiccPort port = getEuiccPortFromIccId(cardId, iccid);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND);
             } catch (RemoteException exception) {
@@ -504,12 +359,12 @@
             }
         };
 
-        port.disableProfile(iccid, refresh, cardCb, mEuiccMainThreadHandler);
+        card.disableProfile(iccid, refresh, cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
-    public void switchToProfile(String callingPackage, String cardId, String iccid, int portIndex,
-            boolean refresh, ISwitchToProfileCallback callback) {
+    public void switchToProfile(String callingPackage, String cardId, String iccid, boolean refresh,
+            ISwitchToProfileCallback callback) {
         try {
             checkCallingPackage(callingPackage);
         } catch (SecurityException se) {
@@ -521,12 +376,12 @@
             return;
         }
 
-        EuiccPort port = getEuiccPort(cardId, portIndex);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
-                loge("switchToProfile callback failure for portIndex :" + portIndex, exception);
+                loge("switchToProfile callback failure.", exception);
             }
             return;
         }
@@ -556,7 +411,7 @@
                     }
                 };
 
-                port.switchToProfile(iccid, refresh, switchCb, mEuiccMainThreadHandler);
+                card.switchToProfile(iccid, refresh, switchCb, mEuiccMainThreadHandler);
             }
 
             @Override
@@ -570,7 +425,7 @@
             }
         };
 
-        port.getProfile(iccid, profileCb, mEuiccMainThreadHandler);
+        card.getProfile(iccid, profileCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -587,8 +442,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND);
             } catch (RemoteException exception) {
@@ -618,7 +473,7 @@
             }
         };
 
-        port.setNickname(iccid, nickname, cardCb, mEuiccMainThreadHandler);
+        card.setNickname(iccid, nickname, cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -635,8 +490,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND);
             } catch (RemoteException exception) {
@@ -670,7 +525,7 @@
             }
         };
 
-        port.deleteProfile(iccid, cardCb, mEuiccMainThreadHandler);
+        card.deleteProfile(iccid, cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -687,8 +542,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND);
             } catch (RemoteException exception) {
@@ -722,7 +577,7 @@
             }
         };
 
-        port.resetMemory(options, cardCb, mEuiccMainThreadHandler);
+        card.resetMemory(options, cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -739,8 +594,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -770,7 +625,7 @@
             }
         };
 
-        port.getDefaultSmdpAddress(cardCb, mEuiccMainThreadHandler);
+        card.getDefaultSmdpAddress(cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -787,8 +642,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -818,7 +673,7 @@
             }
         };
 
-        port.getSmdsAddress(cardCb, mEuiccMainThreadHandler);
+        card.getSmdsAddress(cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -835,8 +690,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND);
             } catch (RemoteException exception) {
@@ -866,7 +721,7 @@
             }
         };
 
-        port.setDefaultSmdpAddress(address, cardCb, mEuiccMainThreadHandler);
+        card.setDefaultSmdpAddress(address, cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -883,8 +738,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -915,7 +770,7 @@
             }
         };
 
-        port.getRulesAuthTable(cardCb, mEuiccMainThreadHandler);
+        card.getRulesAuthTable(cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -932,8 +787,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -963,7 +818,7 @@
             }
         };
 
-        port.getEuiccChallenge(cardCb, mEuiccMainThreadHandler);
+        card.getEuiccChallenge(cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -980,8 +835,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -1011,7 +866,7 @@
             }
         };
 
-        port.getEuiccInfo1(cardCb, mEuiccMainThreadHandler);
+        card.getEuiccInfo1(cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -1028,8 +883,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -1059,7 +914,7 @@
             }
         };
 
-        port.getEuiccInfo2(cardCb, mEuiccMainThreadHandler);
+        card.getEuiccInfo2(cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -1077,8 +932,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -1108,7 +963,7 @@
             }
         };
 
-        port.authenticateServer(matchingId, serverSigned1, serverSignature1, euiccCiPkIdToBeUsed,
+        card.authenticateServer(matchingId, serverSigned1, serverSignature1, euiccCiPkIdToBeUsed,
                 serverCertificate, cardCb, mEuiccMainThreadHandler);
     }
 
@@ -1127,8 +982,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -1158,7 +1013,7 @@
             }
         };
 
-        port.prepareDownload(hashCc, smdpSigned2, smdpSignature2, smdpCertificate, cardCb,
+        card.prepareDownload(hashCc, smdpSigned2, smdpSignature2, smdpCertificate, cardCb,
                 mEuiccMainThreadHandler);
     }
 
@@ -1176,8 +1031,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -1211,7 +1066,7 @@
             }
         };
 
-        port.loadBoundProfilePackage(boundProfilePackage, cardCb, mEuiccMainThreadHandler);
+        card.loadBoundProfilePackage(boundProfilePackage, cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -1228,8 +1083,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -1259,7 +1114,7 @@
             }
         };
 
-        port.cancelSession(transactionId, reason, cardCb, mEuiccMainThreadHandler);
+        card.cancelSession(transactionId, reason, cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -1276,8 +1131,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -1308,7 +1163,7 @@
             }
         };
 
-        port.listNotifications(events, cardCb, mEuiccMainThreadHandler);
+        card.listNotifications(events, cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -1325,8 +1180,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -1357,7 +1212,7 @@
                     }
                 };
 
-        port.retrieveNotificationList(events, cardCb, mEuiccMainThreadHandler);
+        card.retrieveNotificationList(events, cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -1374,8 +1229,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND, null);
             } catch (RemoteException exception) {
@@ -1406,7 +1261,7 @@
                     }
                 };
 
-        port.retrieveNotification(seqNumber, cardCb, mEuiccMainThreadHandler);
+        card.retrieveNotification(seqNumber, cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
@@ -1423,8 +1278,8 @@
             return;
         }
 
-        EuiccPort port = getFirstActiveEuiccPort(cardId);
-        if (port == null) {
+        EuiccCard card = getEuiccCard(cardId);
+        if (card == null) {
             try {
                 callback.onComplete(EuiccCardManager.RESULT_EUICC_NOT_FOUND);
             } catch (RemoteException exception) {
@@ -1455,7 +1310,7 @@
                     }
                 };
 
-        port.removeNotificationFromList(seqNumber, cardCb, mEuiccMainThreadHandler);
+        card.removeNotificationFromList(seqNumber, cardCb, mEuiccMainThreadHandler);
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/euicc/EuiccConnector.java b/src/java/com/android/internal/telephony/euicc/EuiccConnector.java
index 974acf9..f143552 100644
--- a/src/java/com/android/internal/telephony/euicc/EuiccConnector.java
+++ b/src/java/com/android/internal/telephony/euicc/EuiccConnector.java
@@ -57,11 +57,9 @@
 import android.service.euicc.IRetainSubscriptionsForFactoryResetCallback;
 import android.service.euicc.ISwitchToSubscriptionCallback;
 import android.service.euicc.IUpdateSubscriptionNicknameCallback;
-import android.telephony.AnomalyReporter;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.UiccCardInfo;
-import android.telephony.UiccSlotInfo;
 import android.telephony.euicc.DownloadableSubscription;
 import android.telephony.euicc.EuiccInfo;
 import android.telephony.euicc.EuiccManager;
@@ -72,8 +70,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.PackageChangeReceiver;
-import com.android.internal.telephony.uicc.IccUtils;
-import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.internal.util.IState;
 import com.android.internal.util.State;
@@ -84,7 +80,6 @@
 import java.util.List;
 import java.util.Objects;
 import java.util.Set;
-import java.util.UUID;
 
 /**
  * State machine which maintains the binding to the EuiccService implementation and issues commands.
@@ -240,7 +235,6 @@
         boolean mSwitchAfterDownload;
         boolean mForceDeactivateSim;
         DownloadCommandCallback mCallback;
-        int mPortIndex;
         Bundle mResolvedBundle;
     }
 
@@ -292,7 +286,6 @@
         @Nullable String mIccid;
         boolean mForceDeactivateSim;
         SwitchCommandCallback mCallback;
-        boolean mUsePortIndex;
     }
 
     /** Callback class for {@link #switchToSubscription}. */
@@ -457,16 +450,15 @@
 
     /** Asynchronously download the given subscription. */
     @VisibleForTesting(visibility = PACKAGE)
-    public void downloadSubscription(int cardId, int portIndex,
-            DownloadableSubscription subscription, boolean switchAfterDownload,
-            boolean forceDeactivateSim, Bundle resolvedBundle, DownloadCommandCallback callback) {
+    public void downloadSubscription(int cardId, DownloadableSubscription subscription,
+            boolean switchAfterDownload, boolean forceDeactivateSim,
+            Bundle resolvedBundle, DownloadCommandCallback callback) {
         DownloadRequest request = new DownloadRequest();
         request.mSubscription = subscription;
         request.mSwitchAfterDownload = switchAfterDownload;
         request.mForceDeactivateSim = forceDeactivateSim;
         request.mResolvedBundle = resolvedBundle;
         request.mCallback = callback;
-        request.mPortIndex = portIndex;
         sendMessage(CMD_DOWNLOAD_SUBSCRIPTION, cardId, 0 /* arg2 */, request);
     }
 
@@ -501,14 +493,13 @@
 
     /** Asynchronously switch to the given subscription. */
     @VisibleForTesting(visibility = PACKAGE)
-    public void switchToSubscription(int cardId, int portIndex, @Nullable String iccid,
-            boolean forceDeactivateSim, SwitchCommandCallback callback, boolean usePortIndex) {
+    public void switchToSubscription(int cardId, @Nullable String iccid, boolean forceDeactivateSim,
+            SwitchCommandCallback callback) {
         SwitchRequest request = new SwitchRequest();
         request.mIccid = iccid;
         request.mForceDeactivateSim = forceDeactivateSim;
         request.mCallback = callback;
-        request.mUsePortIndex = usePortIndex;
-        sendMessage(CMD_SWITCH_TO_SUBSCRIPTION, cardId, portIndex, request);
+        sendMessage(CMD_SWITCH_TO_SUBSCRIPTION, cardId, 0 /* arg2 */, request);
     }
 
     /** Asynchronously update the nickname of the given subscription. */
@@ -767,7 +758,6 @@
                         case CMD_DOWNLOAD_SUBSCRIPTION: {
                             DownloadRequest request = (DownloadRequest) message.obj;
                             mEuiccService.downloadSubscription(slotId,
-                                    request.mPortIndex,
                                     request.mSubscription,
                                     request.mSwitchAfterDownload,
                                     request.mForceDeactivateSim,
@@ -848,9 +838,7 @@
                         }
                         case CMD_SWITCH_TO_SUBSCRIPTION: {
                             SwitchRequest request = (SwitchRequest) message.obj;
-                            final int portIndex = message.arg2;
-                            mEuiccService.switchToSubscription(slotId, portIndex,
-                                    request.mIccid,
+                            mEuiccService.switchToSubscription(slotId, request.mIccid,
                                     request.mForceDeactivateSim,
                                     new ISwitchToSubscriptionCallback.Stub() {
                                         @Override
@@ -861,8 +849,7 @@
                                                 onCommandEnd(callback);
                                             });
                                         }
-                                    },
-                                    request.mUsePortIndex);
+                                    });
                             break;
                         }
                         case CMD_UPDATE_SUBSCRIPTION_NICKNAME: {
@@ -1048,27 +1035,17 @@
         }
         TelephonyManager tm = (TelephonyManager)
                 mContext.getSystemService(Context.TELEPHONY_SERVICE);
-        UiccSlotInfo[] slotInfos = tm.getUiccSlotsInfo();
-        if (slotInfos == null || slotInfos.length == 0) {
-            Log.e(TAG, "UiccSlotInfo is null or empty");
+        List<UiccCardInfo> infos = tm.getUiccCardsInfo();
+        if (infos == null || infos.size() == 0) {
             return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
         }
-        String cardIdString = UiccController.getInstance().convertToCardString(cardId);
-        for (int slotIndex = 0; slotIndex < slotInfos.length; slotIndex++) {
-            // Report Anomaly in case UiccSlotInfo is not.
-            if (slotInfos[slotIndex] == null) {
-                AnomalyReporter.reportAnomaly(
-                        UUID.fromString("4195b83d-6cee-4999-a02f-d0b9f7079b9d"),
-                        "EuiccConnector: Found UiccSlotInfo Null object.");
-            }
-            String retrievedCardId = slotInfos[slotIndex] != null
-                    ? slotInfos[slotIndex].getCardId() : null;
-            if (IccUtils.compareIgnoreTrailingFs(cardIdString, retrievedCardId)) {
-                return slotIndex;
+        int slotId = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
+        for (UiccCardInfo info : infos) {
+            if (info.getCardId() == cardId) {
+                slotId = info.getSlotIndex();
             }
         }
-        Log.i(TAG, "No UiccSlotInfo found for cardId: " + cardId);
-        return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
+        return slotId;
     }
 
     /** Call this at the beginning of the execution of any command. */
@@ -1226,9 +1203,6 @@
         IState state = getCurrentState();
         Log.wtf(TAG, "Unhandled message " + msg.what + " in state "
                 + (state == null ? "null" : state.getName()));
-        AnomalyReporter.reportAnomaly(
-                UUID.fromString("0db20514-5fa1-4e62-a7b7-2acf5f92c957"),
-                "EuiccConnector: Found unhandledMessage " + String.valueOf(msg.what));
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/euicc/EuiccController.java b/src/java/com/android/internal/telephony/euicc/EuiccController.java
index 965dd22..4ac3176 100644
--- a/src/java/com/android/internal/telephony/euicc/EuiccController.java
+++ b/src/java/com/android/internal/telephony/euicc/EuiccController.java
@@ -21,7 +21,6 @@
 import android.annotation.Nullable;
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
-import android.app.compat.CompatChanges;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -36,15 +35,12 @@
 import android.service.euicc.GetDefaultDownloadableSubscriptionListResult;
 import android.service.euicc.GetDownloadableSubscriptionMetadataResult;
 import android.service.euicc.GetEuiccProfileInfoListResult;
-import android.telephony.AnomalyReporter;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
 import android.telephony.TelephonyManager;
 import android.telephony.UiccAccessRule;
 import android.telephony.UiccCardInfo;
-import android.telephony.UiccPortInfo;
-import android.telephony.UiccSlotInfo;
 import android.telephony.euicc.DownloadableSubscription;
 import android.telephony.euicc.EuiccCardManager.ResetOption;
 import android.telephony.euicc.EuiccInfo;
@@ -56,22 +52,14 @@
 import android.util.Pair;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.CarrierPrivilegesTracker;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.euicc.EuiccConnector.OtaStatusChangedCallback;
-import com.android.internal.telephony.uicc.IccUtils;
-import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.uicc.UiccPort;
-import com.android.internal.telephony.uicc.UiccSlot;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.Collections;
 import java.util.List;
 import java.util.Stack;
-import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
@@ -188,11 +176,6 @@
             PendingIntent callbackIntent =
                     resolutionIntent.getParcelableExtra(
                             EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_RESOLUTION_CALLBACK_INTENT);
-            boolean usePortIndex = resolutionIntent.getBooleanExtra(
-                    EuiccService.EXTRA_RESOLUTION_USE_PORT_INDEX, false);
-            resolutionExtras.putBoolean(EuiccService.EXTRA_RESOLUTION_USE_PORT_INDEX, usePortIndex);
-            Log.i(TAG, " continueOperation portIndex: " + resolutionExtras.getInt(
-                    EuiccService.EXTRA_RESOLUTION_PORT_INDEX) + " usePortIndex: " + usePortIndex);
             op.continueOperation(cardId, resolutionExtras, callbackIntent);
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -218,8 +201,7 @@
         long token = Binder.clearCallingIdentity();
         try {
             if (!callerCanReadPhoneStatePrivileged
-                    && !canManageSubscriptionOnTargetSim(cardId, callingPackage, false,
-                    TelephonyManager.INVALID_PORT_INDEX)) {
+                    && !canManageSubscriptionOnTargetSim(cardId, callingPackage)) {
                 throw new SecurityException(
                         "Must have carrier privileges on subscription to read EID for cardId="
                                 + cardId);
@@ -431,14 +413,13 @@
                     break;
                 case EuiccService.RESULT_MUST_DEACTIVATE_SIM:
                     resultCode = RESOLVABLE_ERROR;
-                    addResolutionIntentWithPort(extrasIntent,
+                    addResolutionIntent(extrasIntent,
                             EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                             mCallingPackage,
                             0 /* resolvableErrors */,
                             false /* confirmationCodeRetried */,
                             getOperationForDeactivateSim(),
-                            cardId,
-                            TelephonyManager.DEFAULT_PORT_INDEX,   false /* usePortIndex */);
+                            cardId);
                     break;
                 default:
                     resultCode = ERROR;
@@ -464,13 +445,8 @@
     public void downloadSubscription(int cardId, DownloadableSubscription subscription,
             boolean switchAfterDownload, String callingPackage, Bundle resolvedBundle,
             PendingIntent callbackIntent) {
-        // If switchAfterDownload is true, set portIndex as
-        // {@link android.telephony.TelephonyManager#INVALID_PORT_INDEX} to resolve the port index.
-        int portIndex = switchAfterDownload ? TelephonyManager.INVALID_PORT_INDEX
-                : TelephonyManager.DEFAULT_PORT_INDEX;
-        downloadSubscription(cardId, portIndex, subscription,
-                switchAfterDownload, callingPackage, false /* forceDeactivateSim */,
-                resolvedBundle, callbackIntent);
+        downloadSubscription(cardId, subscription, switchAfterDownload, callingPackage,
+                false /* forceDeactivateSim */, resolvedBundle, callbackIntent);
     }
 
     /**
@@ -552,45 +528,25 @@
         }
     }
 
-    void downloadSubscription(int cardId, int portIndex, DownloadableSubscription subscription,
+    void downloadSubscription(int cardId, DownloadableSubscription subscription,
             boolean switchAfterDownload, String callingPackage, boolean forceDeactivateSim,
             Bundle resolvedBundle, PendingIntent callbackIntent) {
         boolean callerCanWriteEmbeddedSubscriptions = callerCanWriteEmbeddedSubscriptions();
         mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-        // Don't try to resolve the port index for apps which are not targeting on T for backward
-        // compatibility. instead always use default port 0.
-        boolean shouldResolvePortIndex = isCompatChangeEnabled(callingPackage,
-                EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS);
 
         long token = Binder.clearCallingIdentity();
         try {
-            boolean isConsentNeededToResolvePortIndex = false;
-            if (switchAfterDownload && portIndex == TelephonyManager.INVALID_PORT_INDEX) {
-                // If switchAfterDownload is true, resolve the portIndex
-                portIndex = shouldResolvePortIndex ?
-                        getResolvedPortIndexForSubscriptionSwitch(cardId)
-                        : TelephonyManager.DEFAULT_PORT_INDEX;
-                isConsentNeededToResolvePortIndex = (portIndex
-                        == TelephonyManager.INVALID_PORT_INDEX);
-            }
-            Log.d(TAG, " downloadSubscription cardId: " + cardId + " switchAfterDownload: "
-                    + switchAfterDownload + " portIndex: " + portIndex
-                    + " forceDeactivateSim: " + forceDeactivateSim + " callingPackage: "
-                    + callingPackage
-                    + " isConsentNeededToResolvePortIndex: " + isConsentNeededToResolvePortIndex
-                    + " shouldResolvePortIndex:" + shouldResolvePortIndex);
-            if (!isConsentNeededToResolvePortIndex && callerCanWriteEmbeddedSubscriptions) {
+            if (callerCanWriteEmbeddedSubscriptions) {
                 // With WRITE_EMBEDDED_SUBSCRIPTIONS, we can skip profile-specific permission checks
                 // and move straight to the profile download.
-                downloadSubscriptionPrivileged(cardId, portIndex, token, subscription,
-                        switchAfterDownload, forceDeactivateSim, callingPackage, resolvedBundle,
-                        callbackIntent);
+                downloadSubscriptionPrivileged(cardId, token, subscription, switchAfterDownload,
+                        forceDeactivateSim, callingPackage, resolvedBundle, callbackIntent);
                 return;
             }
 
             // Without WRITE_EMBEDDED_SUBSCRIPTIONS, we first check whether the caller can manage
             // subscription on the target SIM (see comments below). If yes, the caller *must* be
-            // allowlisted per the metadata of the profile to be downloaded, so check the metadata;
+            // whitelisted per the metadata of the profile to be downloaded, so check the metadata;
             // If no, ask the user's consent before proceed.
             // On a multi-active SIM device, if the caller can manage the active subscription on the
             // target SIM, or there is no active subscription on the target SIM and the caller can
@@ -598,27 +554,22 @@
             // Otherwise, the user must provide consent. If it's a single-active SIM device,
             // determine whether the caller can manage the current profile; if so, we can perform
             // the download silently; if not, the user must provide consent.
-            if (!isConsentNeededToResolvePortIndex
-                    && canManageSubscriptionOnTargetSim(cardId, callingPackage, true,
-                    portIndex)) {
+            if (canManageSubscriptionOnTargetSim(cardId, callingPackage)) {
                 mConnector.getDownloadableSubscriptionMetadata(cardId, subscription,
                     forceDeactivateSim,
                     new DownloadSubscriptionGetMetadataCommandCallback(token, subscription,
                         switchAfterDownload, callingPackage, forceDeactivateSim,
-                        callbackIntent, false /* withUserConsent */, portIndex));
+                        callbackIntent, false /* withUserConsent */));
             } else {
-                Log.i(TAG, "Caller can't manage subscription on target SIM or "
-                        + " User consent is required for resolving port index. "
+                Log.i(TAG, "Caller can't manage subscription on target SIM. "
                         + "Ask user's consent first");
                 Intent extrasIntent = new Intent();
-                addResolutionIntentWithPort(extrasIntent,
-                        EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
+                addResolutionIntent(extrasIntent, EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                         callingPackage,
                         0 /* resolvableErrors */,
                         false /* confirmationCodeRetried */,
                         EuiccOperation.forDownloadNoPrivilegesOrDeactivateSimCheckMetadata(token,
-                                subscription, switchAfterDownload, callingPackage), cardId,
-                        portIndex, switchAfterDownload /* usePortIndex */);
+                                subscription, switchAfterDownload, callingPackage), cardId);
                 sendResult(callbackIntent, RESOLVABLE_ERROR, extrasIntent);
             }
         } finally {
@@ -630,17 +581,15 @@
         private final boolean mSwitchAfterDownload;
         private final boolean mForceDeactivateSim;
         private final boolean mWithUserConsent;
-        private final int mPortIndex;
 
         DownloadSubscriptionGetMetadataCommandCallback(long callingToken,
                 DownloadableSubscription subscription, boolean switchAfterDownload,
                 String callingPackage, boolean forceDeactivateSim,
-                PendingIntent callbackIntent, boolean withUserConsent, int portIndex) {
+                PendingIntent callbackIntent, boolean withUserConsent) {
             super(callingToken, subscription, callingPackage, callbackIntent);
             mSwitchAfterDownload = switchAfterDownload;
             mForceDeactivateSim = forceDeactivateSim;
             mWithUserConsent = withUserConsent;
-            mPortIndex = portIndex;
         }
 
         @Override
@@ -658,7 +607,7 @@
                 if (checkCarrierPrivilegeInMetadata(subscription, mCallingPackage)) {
                     // Caller can download this profile. Since we already have the user's consent,
                     // proceed to download.
-                    downloadSubscriptionPrivileged(cardId, mPortIndex,
+                    downloadSubscriptionPrivileged(cardId,
                             mCallingToken, subscription, mSwitchAfterDownload,  mForceDeactivateSim,
                             mCallingPackage, null /* resolvedBundle */,
                             mCallbackIntent);
@@ -671,15 +620,14 @@
                     // The caller can manage the target SIM. Ask the user's consent to deactivate
                     // the current SIM.
                     Intent extrasIntent = new Intent();
-                    addResolutionIntentWithPort(extrasIntent,
-                            EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
+                    addResolutionIntent(extrasIntent, EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                             mCallingPackage,
                             0 /* resolvableErrors */,
                             false /* confirmationCodeRetried */,
                             EuiccOperation.forDownloadNoPrivilegesOrDeactivateSimCheckMetadata(
                                     mCallingToken, mSubscription, mSwitchAfterDownload,
                                     mCallingPackage),
-                            cardId,  mPortIndex,  mSwitchAfterDownload /* usePortIndex */);
+                            cardId);
                     sendResult(mCallbackIntent, RESOLVABLE_ERROR, extrasIntent);
                     return;
                 }
@@ -693,7 +641,7 @@
                 if (checkCarrierPrivilegeInMetadata(subscription, mCallingPackage)) {
                     // Caller can download this profile per profile metadata. Also, caller can
                     // manage the subscription on the target SIM, which is already checked.
-                    downloadSubscriptionPrivileged(cardId, mPortIndex,
+                    downloadSubscriptionPrivileged(cardId,
                             mCallingToken, subscription, mSwitchAfterDownload, mForceDeactivateSim,
                             mCallingPackage, null /* resolvedBundle */,
                             mCallbackIntent);
@@ -706,27 +654,23 @@
     }
 
     // Already have user consent. Check metadata first before proceed to download.
-    void downloadSubscriptionPrivilegedCheckMetadata(int cardId, int portIndex,
-            final long callingToken, DownloadableSubscription subscription,
-            boolean switchAfterDownload, boolean forceDeactivateSim, final String callingPackage,
-            Bundle resolvedBundle, final PendingIntent callbackIntent) {
-        Log.d(TAG, " downloadSubscriptionPrivilegedCheckMetadata cardId: " + cardId
-                + " switchAfterDownload: " + switchAfterDownload + " portIndex: " + portIndex
-                + " forceDeactivateSim: " + forceDeactivateSim);
+    void downloadSubscriptionPrivilegedCheckMetadata(int cardId, final long callingToken,
+            DownloadableSubscription subscription, boolean switchAfterDownload,
+            boolean forceDeactivateSim, final String callingPackage, Bundle resolvedBundle,
+            final PendingIntent callbackIntent) {
         mConnector.getDownloadableSubscriptionMetadata(cardId, subscription, forceDeactivateSim,
                 new DownloadSubscriptionGetMetadataCommandCallback(callingToken, subscription,
                         switchAfterDownload, callingPackage, forceDeactivateSim, callbackIntent,
-                        true /* withUserConsent */, portIndex));
+                        true /* withUserConsent */));
     }
 
     // Continue to download subscription without checking anything.
-    void downloadSubscriptionPrivileged(int cardId, int portIndex, final long callingToken,
+    void downloadSubscriptionPrivileged(int cardId, final long callingToken,
             DownloadableSubscription subscription, boolean switchAfterDownload,
             boolean forceDeactivateSim, final String callingPackage, Bundle resolvedBundle,
             final PendingIntent callbackIntent) {
         mConnector.downloadSubscription(
                 cardId,
-                portIndex,
                 subscription,
                 switchAfterDownload,
                 forceDeactivateSim,
@@ -758,7 +702,7 @@
                                 break;
                             case EuiccService.RESULT_MUST_DEACTIVATE_SIM:
                                 resultCode = RESOLVABLE_ERROR;
-                                addResolutionIntentWithPort(extrasIntent,
+                                addResolutionIntent(extrasIntent,
                                         EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                                         callingPackage,
                                         0 /* resolvableErrors */,
@@ -766,8 +710,7 @@
                                         EuiccOperation.forDownloadDeactivateSim(
                                                 callingToken, subscription, switchAfterDownload,
                                                 callingPackage),
-                                        cardId,
-                                        portIndex, switchAfterDownload /* usePortIndex */);
+                                        cardId);
                                 break;
                             case EuiccService.RESULT_RESOLVABLE_ERRORS:
                                 // Same value as the deprecated
@@ -780,7 +723,7 @@
                                     retried = true;
                                 }
                                 if (result.getResolvableErrors() != 0) {
-                                    addResolutionIntentWithPort(extrasIntent,
+                                    addResolutionIntent(extrasIntent,
                                             EuiccService.ACTION_RESOLVE_RESOLVABLE_ERRORS,
                                             callingPackage,
                                             result.getResolvableErrors(),
@@ -788,10 +731,9 @@
                                             EuiccOperation.forDownloadResolvableErrors(
                                                 callingToken, subscription, switchAfterDownload,
                                                 callingPackage, result.getResolvableErrors()),
-                                            cardId,
-                                            portIndex, switchAfterDownload /* usePortIndex */);
+                                            cardId);
                                 }  else { // Deprecated case
-                                    addResolutionIntentWithPort(extrasIntent,
+                                    addResolutionIntent(extrasIntent,
                                             EuiccService.ACTION_RESOLVE_CONFIRMATION_CODE,
                                             callingPackage,
                                             0 /* resolvableErrors */,
@@ -799,8 +741,7 @@
                                             EuiccOperation.forDownloadConfirmationCode(
                                                 callingToken, subscription, switchAfterDownload,
                                                 callingPackage),
-                                            cardId,
-                                            portIndex, switchAfterDownload /* usePortIndex */);
+                                            cardId);
                                 }
                                 break;
                             default:
@@ -906,15 +847,14 @@
                     break;
                 case EuiccService.RESULT_MUST_DEACTIVATE_SIM:
                     resultCode = RESOLVABLE_ERROR;
-                    addResolutionIntentWithPort(extrasIntent,
+                    addResolutionIntent(extrasIntent,
                             EuiccService.ACTION_RESOLVE_DEACTIVATE_SIM,
                             mCallingPackage,
                             0 /* resolvableErrors */,
                             false /* confirmationCodeRetried */,
                             EuiccOperation.forGetDefaultListDeactivateSim(
                                     mCallingToken, mCallingPackage),
-                            cardId,
-                            TelephonyManager.DEFAULT_PORT_INDEX, false /* usePortIndex */);
+                            cardId);
                     break;
                 default:
                     resultCode = ERROR;
@@ -1015,31 +955,15 @@
     @Override
     public void switchToSubscription(int cardId, int subscriptionId, String callingPackage,
             PendingIntent callbackIntent) {
-        // convert PendingIntent to callback if no callback provided
-        switchToSubscription(cardId, subscriptionId, 0, false /* forceDeactivateSim */,
-                callingPackage, callbackIntent, false);
+        switchToSubscription(cardId,
+                subscriptionId, false /* forceDeactivateSim */, callingPackage, callbackIntent);
     }
 
-    @Override
-    public void switchToSubscriptionWithPort(int cardId, int subscriptionId, int portIndex,
+    void switchToSubscription(int cardId, int subscriptionId, boolean forceDeactivateSim,
             String callingPackage, PendingIntent callbackIntent) {
-        switchToSubscription(cardId, subscriptionId, portIndex, false /* forceDeactivateSim */,
-                callingPackage, callbackIntent, true);
-    }
-
-    void switchToSubscription(int cardId, int subscriptionId, int portIndex,
-            boolean forceDeactivateSim, String callingPackage, PendingIntent callbackIntent,
-            boolean usePortIndex) {
         boolean callerCanWriteEmbeddedSubscriptions = callerCanWriteEmbeddedSubscriptions();
         mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-        // Resolve the portIndex internally if apps targeting T and beyond are calling
-        // switchToSubscription API without portIndex.
-        boolean shouldResolvePortIndex = isCompatChangeEnabled(callingPackage,
-                EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS);
-        Log.d(TAG, " subId: " + subscriptionId + " portIndex: " + portIndex
-                + " forceDeactivateSim: " + forceDeactivateSim + " usePortIndex: " + usePortIndex
-                + " callingPackage: " + callingPackage + " shouldResolvePortIndex: "
-                + shouldResolvePortIndex);
+
         long token = Binder.clearCallingIdentity();
         try {
             if (callerCanWriteEmbeddedSubscriptions) {
@@ -1051,24 +975,9 @@
 
             final String iccid;
             boolean passConsent = false;
-            boolean isConsentNeededToResolvePortIndex = false;
             if (subscriptionId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-                if (!usePortIndex) {
-                    // Resolve the portIndex internally if apps are calling switchToSubscription
-                    // API without portIndex and subscription id is invalid.
-                    portIndex = getResolvedPortIndexForDisableSubscription(cardId, callingPackage,
-                            callerCanWriteEmbeddedSubscriptions);
-                    if (portIndex == TelephonyManager.INVALID_PORT_INDEX) {
-                        Log.e(TAG, "Disable is not permitted: no active subscription or cannot"
-                                + " manage subscription");
-                        sendResult(callbackIntent, ERROR, null /* extrasIntent */);
-                        return;
-                    }
-                    usePortIndex = true;
-                }
                 if (callerCanWriteEmbeddedSubscriptions
-                        || canManageActiveSubscriptionOnTargetSim(cardId, callingPackage,
-                        usePortIndex, portIndex)) {
+                        || canManageActiveSubscriptionOnTargetSim(cardId, callingPackage)) {
                     passConsent = true;
                 } else {
                     Log.e(TAG, "Not permitted to switch to empty subscription");
@@ -1092,36 +1001,14 @@
                         return;
                     }
 
-                    if (canManageSubscriptionOnTargetSim(cardId, callingPackage, usePortIndex,
-                            portIndex)) {
+                    if (canManageSubscriptionOnTargetSim(cardId, callingPackage)) {
                         passConsent = true;
                     }
                 }
                 iccid = sub.getIccId();
-                if (usePortIndex) {
-                    boolean hasValidPortIndex = isTargetPortIndexValid(cardId, portIndex);
-                    if (!hasValidPortIndex) {
-                        // Return permanent error.
-                        Log.e(TAG, "Not permitted to switch to invalid portIndex");
-                        Intent extrasIntent = new Intent();
-                        extrasIntent.putExtra(EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE,
-                                EuiccManager.ERROR_INVALID_PORT);
-                        sendResult(callbackIntent, ERROR, extrasIntent /* extrasIntent */);
-                        return;
-                    }
-                } else {
-                    // Resolve the portIndex internally if apps targeting T and beyond are calling
-                    // switchToSubscription API without portIndex.
-                    portIndex = shouldResolvePortIndex ?
-                            getResolvedPortIndexForSubscriptionSwitch(cardId)
-                            : TelephonyManager.DEFAULT_PORT_INDEX;
-                    isConsentNeededToResolvePortIndex = (portIndex
-                            == TelephonyManager.INVALID_PORT_INDEX);
-                    usePortIndex = true;
-                    Log.d(TAG, " Resolved portIndex: " + portIndex);
-                }
             }
-            if (!passConsent || isConsentNeededToResolvePortIndex) {
+
+            if (!passConsent) {
                 // Switch needs consent.
                 Intent extrasIntent = new Intent();
                 addResolutionIntent(extrasIntent,
@@ -1131,247 +1018,35 @@
                         false /* confirmationCodeRetried */,
                         EuiccOperation.forSwitchNoPrivileges(
                                 token, subscriptionId, callingPackage),
-                        cardId, portIndex, usePortIndex, subscriptionId);
+                        cardId);
                 sendResult(callbackIntent, RESOLVABLE_ERROR, extrasIntent);
                 return;
             }
 
-            switchToSubscriptionPrivileged(cardId, portIndex, token, subscriptionId, iccid,
-                    forceDeactivateSim, callingPackage, callbackIntent, usePortIndex);
+            switchToSubscriptionPrivileged(cardId, token, subscriptionId, iccid, forceDeactivateSim,
+                    callingPackage, callbackIntent);
         } finally {
             Binder.restoreCallingIdentity(token);
         }
     }
 
-    /**
-     * Returns the resolved portIndex or {@link TelephonyManager#INVALID_PORT_INDEX} if calling
-     * cannot manage any active subscription.
-     */
-    private int getResolvedPortIndexForDisableSubscription(int cardId, String callingPackage,
-            boolean callerCanWriteEmbeddedSubscriptions) {
-        List<SubscriptionInfo> subInfoList = mSubscriptionManager
-                .getActiveSubscriptionInfoList(/* userVisibleOnly */false);
-        if (subInfoList == null || subInfoList.size() == 0) {
-            // No active subscription on any SIM.
-            return TelephonyManager.INVALID_PORT_INDEX;
-        }
-        // Return the portIndex of the first active subscription managed by the calling app.
-        for (SubscriptionInfo subInfo : subInfoList) {
-            // If cardId == TelephonyManager.UNSUPPORTED_CARD_ID, we assume it does not support
-            // multiple eSIMs. There are older multi-active SIM devices which do not implement HAL
-            // 1.2 and if they have multiple eSIMs, we let it pass if the app can manage an active
-            // subscription on any eSIM. That's the best we can do here.
-            if ((cardId == TelephonyManager.UNSUPPORTED_CARD_ID || subInfo.getCardId() == cardId)
-                    && subInfo.isEmbedded()
-                    && (callerCanWriteEmbeddedSubscriptions
-                    || mSubscriptionManager.canManageSubscription(subInfo, callingPackage))) {
-                return subInfo.getPortIndex();
-            }
-        }
-        return TelephonyManager.INVALID_PORT_INDEX;
-    }
-
-    /**
-     * Returns the resolved portIndex or {@link TelephonyManager#INVALID_PORT_INDEX} if no port
-     * is available without user consent.
-     */
-    private int getResolvedPortIndexForSubscriptionSwitch(int cardId) {
-        int slotIndex = getSlotIndexFromCardId(cardId);
-        // Euicc Slot
-        UiccSlot slot = UiccController.getInstance().getUiccSlot(slotIndex);
-        if (slot == null) {
-            // Check is to make sure crash is avoided in case of slot is null.
-            Log.d(TAG, "Switch to inactive slot, return default port index. slotIndex: "
-                    + slotIndex);
-            return TelephonyManager.DEFAULT_PORT_INDEX;
-        }
-        if (!slot.isMultipleEnabledProfileSupported()) {
-            Log.d(TAG, "Multiple enabled profiles is not supported, return default port index");
-            return TelephonyManager.DEFAULT_PORT_INDEX;
-        }
-        boolean isPsimActive = getRemovableNonEuiccSlot() != null
-                && getRemovableNonEuiccSlot().isActive();
-        if (mTelephonyManager.getActiveModemCount() == 1) {
-            // SS Mode
-            if (isPsimActive) {
-                // In case of SS Mode and pSim is active, return default port index for
-                // two reasons.
-                // 1. If psim and esim share the same carrier privilege, then users wouldn't need
-                // to consent, the switch should be seamless.
-                // 2. If psim is active and empty or psim and esim doesn't share the same carrier
-                // privilege, then permission check dialog will be shown anyway.
-                return TelephonyManager.DEFAULT_PORT_INDEX;
-            }
-            // If esim port is active, return the active portIndex irrespective of whether port is
-            // empty or has active subscription.
-            for (int portIndex : slot.getPortList()) {
-                if (slot.isPortActive(portIndex)) {
-                    return portIndex;
-                }
-            }
-        } else {
-            // DSDS Mode
-            for (int portIndex : slot.getPortList()) {
-                if (slot.isPortActive(portIndex)) {
-                    SubscriptionInfo subscriptionInfo =
-                              mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(
-                                    slot.getPhoneIdFromPortIndex(portIndex));
-                    if (subscriptionInfo == null || subscriptionInfo.isOpportunistic()) {
-                            // If the port is active and empty/opportunistic, return the portIndex.
-                        return portIndex;
-                    }
-                }
-            }
-            // Check whether the pSim is active and empty
-            boolean isPsimEmpty = isPsimActive && !isRemovalNonEuiccSlotHasActiveSubscription();
-            if (isPsimEmpty) {
-                // This logic will execute only if below two conditions are true.
-                // 1. pSim is active and empty
-                // 2. eSim has active subscription
-                // Return the next available inactive eSim portIndex.
-                return getNextAvailableInActivePortIndex(slot);
-            }
-        }
-        return TelephonyManager.INVALID_PORT_INDEX;
-    }
-
-    /**
-     * Returns true if the target port index is valid.
-     * 1. Port index is valid if it is non-negative and less than the total port count.
-     * 2. In SS Mode, port index is invalid if the embedded slot already has an active port
-     * with different port index than the target port index.
-     * 3. In DSDS mode, port index is invalid if the pSim slot is active and the embedded slot
-     * already has an active empty port with different port index than the target port index.
-     */
-    private boolean isTargetPortIndexValid(int cardId, int targetPortIndex) {
-        if (targetPortIndex < 0) {
-            Log.e(TAG, "Invalid portIndex: " + targetPortIndex);
-            return false;
-        }
-        int slotIndex = getSlotIndexFromCardId(cardId);
-        UiccSlot slot = UiccController.getInstance().getUiccSlot(slotIndex);
-        if (slot == null || slot.getPortList().length == 0
-                || targetPortIndex >= slot.getPortList().length) {
-            Log.e(TAG, "Invalid portIndex");
-            return false;
-        }
-
-        if (mTelephonyManager.getActiveModemCount() == 1) {
-            // SS Mode
-            for (int portIndex : slot.getPortList()) {
-                if (slot.isPortActive(portIndex) && portIndex != targetPortIndex) {
-                    // if there is an active esim port, should not try to enable the
-                    // profile on other inactive port.
-                    Log.e(TAG, "In SS Mode, slot already has active port on portIndex " + portIndex
-                            + " , reject the switch request to portIndex " + targetPortIndex);
-                    return false;
-                }
-            }
-        } else if (mTelephonyManager.getActiveModemCount() > 1) {
-            // DSDS Mode
-            // If physical slot has active subscription and eSim has active port (without active
-            // subscription), should not try to enable the profile on other inactive port.
-            boolean isPsimActive = isRemovalNonEuiccSlotHasActiveSubscription();
-            if (isPsimActive) {
-                for (int portIndex : slot.getPortList()) {
-                    if (slot.isPortActive(portIndex)
-                            && mSubscriptionManager
-                            .getActiveSubscriptionInfoForSimSlotIndex(
-                                    slot.getPhoneIdFromPortIndex(portIndex)) == null
-                            && portIndex != targetPortIndex) {
-                        Log.e(TAG, "In DSDS Mode, pSim has active subscription, eSim has empty"
-                                + " active port on portIndex " + portIndex
-                                + " , reject the switch request to portIndex " + targetPortIndex);
-                        return false;
-                    }
-                }
-            }
-        }
-        return true;
-    }
-
-    private int getNextAvailableInActivePortIndex(UiccSlot slot) {
-        if (slot != null) {
-            for (int portIndex : slot.getPortList()) {
-                if (!slot.isPortActive(portIndex)) {
-                    return portIndex;
-                }
-            }
-        }
-        return TelephonyManager.INVALID_PORT_INDEX;
-    }
-
-    /**
-     * Gets the slot index from the card ID.
-     */
-    private int getSlotIndexFromCardId(int cardId) {
-        UiccSlotInfo[] slotInfos = mTelephonyManager.getUiccSlotsInfo();
-        if (slotInfos == null || slotInfos.length == 0) {
-            Log.e(TAG, "UiccSlotInfo is null or empty");
-            return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
-        }
-        String cardIdString = UiccController.getInstance().convertToCardString(cardId);
-        for (int slotIndex = 0; slotIndex < slotInfos.length; slotIndex++) {
-            if (slotInfos[slotIndex] == null) {
-                AnomalyReporter.reportAnomaly(
-                        UUID.fromString("e9517acf-e1a1-455f-9231-1b5515a0d0eb"),
-                        "EuiccController: Found UiccSlotInfo Null object.");
-            }
-            String retrievedCardId = slotInfos[slotIndex] != null
-                    ? slotInfos[slotIndex].getCardId() : null;
-            if (IccUtils.compareIgnoreTrailingFs(cardIdString, retrievedCardId)) {
-                return slotIndex;
-            }
-        }
-        Log.i(TAG, "No UiccSlotInfo found for cardId: " + cardId);
-        return SubscriptionManager.INVALID_SIM_SLOT_INDEX;
-    }
-
-    private boolean isRemovalNonEuiccSlotHasActiveSubscription() {
-        UiccSlot uiccSlot = getRemovableNonEuiccSlot();
-        if (uiccSlot != null) {
-            for (int portIndex : uiccSlot.getPortList()) {
-                if (uiccSlot.isPortActive(portIndex)
-                        && mSubscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(
-                                uiccSlot.getPhoneIdFromPortIndex(portIndex)) != null) {
-                    return true;
-                }
-            }
-        }
-        return false;
-    }
-
-    private UiccSlot getRemovableNonEuiccSlot() {
-        UiccSlot[] uiccSlots = UiccController.getInstance().getUiccSlots();
-        if (uiccSlots != null) {
-            for (int i = 0; i < uiccSlots.length; i++) {
-                if (uiccSlots[i] != null && uiccSlots[i].isRemovable()
-                        && !uiccSlots[i].isEuicc()) {
-                    return uiccSlots[i];
-                }
-            }
-        }
-        return null;
-    }
-
-    void switchToSubscriptionPrivileged(int cardId, int portIndex, final long callingToken,
-            int subscriptionId, boolean forceDeactivateSim, final String callingPackage,
-            final PendingIntent callbackIntent, boolean usePortIndex) {
+    void switchToSubscriptionPrivileged(int cardId, final long callingToken, int subscriptionId,
+            boolean forceDeactivateSim, final String callingPackage,
+            final PendingIntent callbackIntent) {
         String iccid = null;
         SubscriptionInfo sub = getSubscriptionForSubscriptionId(subscriptionId);
         if (sub != null) {
             iccid = sub.getIccId();
         }
-        switchToSubscriptionPrivileged(cardId, portIndex, callingToken, subscriptionId, iccid,
-                forceDeactivateSim, callingPackage, callbackIntent, usePortIndex);
+        switchToSubscriptionPrivileged(cardId, callingToken, subscriptionId, iccid,
+                forceDeactivateSim, callingPackage, callbackIntent);
     }
 
-    void switchToSubscriptionPrivileged(int cardId, int portIndex, final long callingToken,
-            int subscriptionId, @Nullable String iccid, boolean forceDeactivateSim,
-            final String callingPackage, final PendingIntent callbackIntent, boolean usePortIndex) {
+    void switchToSubscriptionPrivileged(int cardId, final long callingToken, int subscriptionId,
+            @Nullable String iccid, boolean forceDeactivateSim, final String callingPackage,
+            final PendingIntent callbackIntent) {
         mConnector.switchToSubscription(
                 cardId,
-                portIndex,
                 iccid,
                 forceDeactivateSim,
                 new EuiccConnector.SwitchCommandCallback() {
@@ -1392,13 +1067,14 @@
                                         false /* confirmationCodeRetried */,
                                         EuiccOperation.forSwitchDeactivateSim(
                                                 callingToken, subscriptionId, callingPackage),
-                                        cardId, portIndex, usePortIndex, subscriptionId);
+                                        cardId);
                                 break;
                             default:
                                 resultCode = ERROR;
                                 addExtrasToResultIntent(extrasIntent, result);
                                 break;
                         }
+
                         sendResult(callbackIntent, resultCode, extrasIntent);
                     }
 
@@ -1406,8 +1082,7 @@
                     public void onEuiccServiceUnavailable() {
                         sendResult(callbackIntent, ERROR, null /* extrasIntent */);
                     }
-                },
-                usePortIndex);
+                });
     }
 
     @Override
@@ -1600,22 +1275,11 @@
         }
     }
 
-    /** Add a resolution intent to the given extras intent with invalid subscriptionId */
-    public void addResolutionIntentWithPort(Intent extrasIntent, String resolutionAction,
-            String callingPackage, int resolvableErrors, boolean confirmationCodeRetried,
-            EuiccOperation op, int cardId, int portIndex, boolean usePortIndex) {
-        // use invalid subscriptionId in case of download/metadata flow
-        addResolutionIntent(extrasIntent, resolutionAction, callingPackage, resolvableErrors,
-                confirmationCodeRetried, op, cardId, portIndex,
-                usePortIndex /* usePortIndex */, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-    }
-
     /** Add a resolution intent to the given extras intent. */
     @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
     public void addResolutionIntent(Intent extrasIntent, String resolutionAction,
             String callingPackage, int resolvableErrors, boolean confirmationCodeRetried,
-            EuiccOperation op, int cardId, int portIndex, boolean usePortIndex,
-            int subscriptionId) {
+            EuiccOperation op, int cardId) {
         Intent intent = new Intent(EuiccManager.ACTION_RESOLVE_ERROR);
         intent.setPackage(RESOLUTION_ACTIVITY_PACKAGE_NAME);
         intent.setComponent(new ComponentName(
@@ -1625,9 +1289,6 @@
         intent.putExtra(EuiccService.EXTRA_RESOLUTION_CALLING_PACKAGE, callingPackage);
         intent.putExtra(EuiccService.EXTRA_RESOLVABLE_ERRORS, resolvableErrors);
         intent.putExtra(EuiccService.EXTRA_RESOLUTION_CARD_ID, cardId);
-        intent.putExtra(EuiccService.EXTRA_RESOLUTION_SUBSCRIPTION_ID, subscriptionId);
-        intent.putExtra(EuiccService.EXTRA_RESOLUTION_PORT_INDEX, portIndex);
-        intent.putExtra(EuiccService.EXTRA_RESOLUTION_USE_PORT_INDEX, usePortIndex);
         intent.putExtra(EuiccService.EXTRA_RESOLUTION_CONFIRMATION_CODE_RETRIED,
                 confirmationCodeRetried);
         intent.putExtra(EXTRA_OPERATION, op);
@@ -1808,10 +1469,7 @@
 
     // Checks whether the caller can manage the active embedded subscription on the SIM with the
     // given cardId.
-    // From Android T, if usePortIndex is true then should check if the calling app has carrier
-    // privilege over the subscription on the target port index.
-    private boolean canManageActiveSubscriptionOnTargetSim(int cardId, String callingPackage,
-            boolean usePortIndex, int targetPortIndex) {
+    private boolean canManageActiveSubscriptionOnTargetSim(int cardId, String callingPackage) {
         List<SubscriptionInfo> subInfoList = mSubscriptionManager
                 .getActiveSubscriptionInfoList(/* userVisibleOnly */false);
         if (subInfoList == null || subInfoList.size() == 0) {
@@ -1825,7 +1483,6 @@
             // subscription on any eSIM. That's the best we can do here.
             if ((cardId == TelephonyManager.UNSUPPORTED_CARD_ID || subInfo.getCardId() == cardId)
                     && subInfo.isEmbedded()
-                    && (!usePortIndex || subInfo.getPortIndex() == targetPortIndex)
                     && mSubscriptionManager.canManageSubscription(subInfo, callingPackage)) {
                 return true;
             }
@@ -1840,10 +1497,7 @@
     // other SIM. The target SIM should be an eUICC.
     // For a single-active subscription phone, checks whether the caller can manage any active
     // embedded subscription.
-    // From Android T, If embedded slot supports Multiple Enabled Profiles then should check if
-    // the calling app has carrier privilege over the subscription on the target port index.
-    private boolean canManageSubscriptionOnTargetSim(int cardId, String callingPackage,
-            boolean usePortIndex, int targetPortIndex) {
+    private boolean canManageSubscriptionOnTargetSim(int cardId, String callingPackage) {
         List<SubscriptionInfo> subInfoList = mSubscriptionManager
                 .getActiveSubscriptionInfoList(false /* userVisibleonly */);
         // No active subscription on any SIM.
@@ -1861,11 +1515,9 @@
                 return false;
             }
             boolean isEuicc = false;
-            boolean isMultipleEnabledProfilesSupported = false;
             for (UiccCardInfo info : cardInfos) {
                 if (info != null && info.getCardId() == cardId && info.isEuicc()) {
                     isEuicc = true;
-                    isMultipleEnabledProfilesSupported = info.isMultipleEnabledProfilesSupported();
                     break;
                 }
             }
@@ -1878,13 +1530,8 @@
             // false. If the caller can manage the active embedded subscription on the target SIM,
             // return true directly.
             for (SubscriptionInfo subInfo : subInfoList) {
-                // 1. subInfo.isEmbedded() can only be true for the target SIM.
-                // 2. Check whether the caller can manage subscription on the target portIndex
-                // (i.e. subInfo.getPortIndex() == targetPortIndex condition) only in case if
-                // isMultipleEnabledProfilesSupported and usePortIndex both are true.
-                if (subInfo.isEmbedded() && subInfo.getCardId() == cardId
-                        && (!isMultipleEnabledProfilesSupported || !usePortIndex
-                        || subInfo.getPortIndex() == targetPortIndex)) {
+                // subInfo.isEmbedded() can only be true for the target SIM.
+                if (subInfo.isEmbedded() && subInfo.getCardId() == cardId) {
                     return mSubscriptionManager.canManageSubscription(subInfo, callingPackage);
                 }
             }
@@ -1920,89 +1567,4 @@
                 Manifest.permission.WRITE_EMBEDDED_SUBSCRIPTIONS)
                 == PackageManager.PERMISSION_GRANTED;
     }
-
-    @Override
-    public boolean isSimPortAvailable(int cardId, int portIndex, String callingPackage) {
-        List<UiccCardInfo> cardInfos;
-        final long token = Binder.clearCallingIdentity();
-        try {
-            cardInfos = mTelephonyManager.getUiccCardsInfo();
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-        for (UiccCardInfo info : cardInfos) {
-            if (info == null || info.getCardId() != cardId) {
-                continue;
-            }
-            // Return false in case of non esim or passed port index is greater than
-            // the available ports.
-            if (!info.isEuicc() || (portIndex == TelephonyManager.INVALID_PORT_INDEX)
-                    || portIndex >= info.getPorts().size()) {
-                return false;
-            }
-            for (UiccPortInfo portInfo : info.getPorts()) {
-                if (portInfo == null || portInfo.getPortIndex() != portIndex) {
-                    continue;
-                }
-                // Return false if port is not active.
-                if (!portInfo.isActive()) {
-                    return false;
-                }
-                // A port is available if it has no profiles enabled on it or calling app has
-                // Carrier privilege over the profile installed on the selected port.
-                if (TextUtils.isEmpty(portInfo.getIccId())) {
-                    return true;
-                }
-                UiccPort uiccPort =
-                        UiccController.getInstance().getUiccPortForSlot(
-                                info.getPhysicalSlotIndex(), portIndex);
-                // Some eSim Vendors return boot profile iccid if no profile is installed.
-                // So in this case if profile is empty, port is available.
-                if (uiccPort != null
-                        && uiccPort.getUiccProfile() != null
-                        && uiccPort.getUiccProfile().isEmptyProfile()) {
-                    return true;
-                }
-                Phone phone = PhoneFactory.getPhone(portInfo.getLogicalSlotIndex());
-                if (phone == null) {
-                    Log.e(TAG, "Invalid logical slot: " + portInfo.getLogicalSlotIndex());
-                    return false;
-                }
-                CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
-                if (cpt == null) {
-                    Log.e(TAG, "No CarrierPrivilegesTracker");
-                    return false;
-                }
-                return (cpt.getCarrierPrivilegeStatusForPackage(callingPackage)
-                        == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS);
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public boolean hasCarrierPrivilegesForPackageOnAnyPhone(String callingPackage) {
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-        final long token = Binder.clearCallingIdentity();
-        try {
-            // checkCarrierPrivilegesForPackageAnyPhone API requires READ_PHONE_STATE permission,
-            // hence cannot call directly from EuiccManager switchToSubscription
-            return mTelephonyManager.checkCarrierPrivilegesForPackageAnyPhone(callingPackage)
-                    == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
-        } finally {
-            Binder.restoreCallingIdentity(token);
-        }
-    }
-
-    @Override
-    public boolean isCompatChangeEnabled(String callingPackage, long changeId) {
-        mAppOpsManager.checkPackage(Binder.getCallingUid(), callingPackage);
-        // Platform compat framework kills the callingPackage app to ensure that the change
-        // takes affect immediately. So the corresponding compat checking is moved to controller.
-        boolean changeEnabled = CompatChanges.isChangeEnabled(changeId, callingPackage,
-                Binder.getCallingUserHandle());
-        Log.i(TAG, "isCompatChangeEnabled changeId: " + changeId
-                + " changeEnabled: " + changeEnabled);
-        return changeEnabled;
-    }
 }
diff --git a/src/java/com/android/internal/telephony/euicc/EuiccOperation.java b/src/java/com/android/internal/telephony/euicc/EuiccOperation.java
index 82ee5f8..86f1dbf 100644
--- a/src/java/com/android/internal/telephony/euicc/EuiccOperation.java
+++ b/src/java/com/android/internal/telephony/euicc/EuiccOperation.java
@@ -23,7 +23,6 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.service.euicc.EuiccService;
-import android.telephony.TelephonyManager;
 import android.telephony.euicc.DownloadableSubscription;
 import android.telephony.euicc.EuiccManager;
 import android.text.TextUtils;
@@ -277,8 +276,6 @@
                 break;
             case ACTION_DOWNLOAD_DEACTIVATE_SIM:
                 resolvedDownloadDeactivateSim(cardId,
-                        resolutionExtras.getInt(EuiccService.EXTRA_RESOLUTION_PORT_INDEX,
-                                TelephonyManager.DEFAULT_PORT_INDEX),
                         resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
                         callbackIntent);
                 break;
@@ -289,8 +286,6 @@
                 break;
             case ACTION_DOWNLOAD_NO_PRIVILEGES_OR_DEACTIVATE_SIM_CHECK_METADATA:
                 resolvedDownloadNoPrivilegesOrDeactivateSimCheckMetadata(cardId,
-                        resolutionExtras.getInt(EuiccService.EXTRA_RESOLUTION_PORT_INDEX,
-                                TelephonyManager.DEFAULT_PORT_INDEX),
                         resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
                         callbackIntent);
                 break;
@@ -307,34 +302,16 @@
                         resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
                         callbackIntent);
                 break;
-            case ACTION_SWITCH_DEACTIVATE_SIM: {
-                // get portIndex from original operation
-                final int portIndex = resolutionExtras.getInt(
-                        EuiccService.EXTRA_RESOLUTION_PORT_INDEX,
-                        0);
-                // get whether legacy API was called from original operation
-                final boolean usePortIndex = resolutionExtras.getBoolean(
-                        EuiccService.EXTRA_RESOLUTION_USE_PORT_INDEX,
-                        false);
-                resolvedSwitchDeactivateSim(cardId, portIndex,
+            case ACTION_SWITCH_DEACTIVATE_SIM:
+                resolvedSwitchDeactivateSim(cardId,
                         resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
-                        callbackIntent, usePortIndex);
+                        callbackIntent);
                 break;
-            }
-            case ACTION_SWITCH_NO_PRIVILEGES: {
-                // get portIndex from original operation
-                final int portIndex = resolutionExtras.getInt(
-                        EuiccService.EXTRA_RESOLUTION_PORT_INDEX,
-                        0);
-                // get whether port index was passed in from original operation
-                final boolean usePortIndex = resolutionExtras.getBoolean(
-                        EuiccService.EXTRA_RESOLUTION_USE_PORT_INDEX,
-                        false);
-                resolvedSwitchNoPrivileges(cardId, portIndex,
+            case ACTION_SWITCH_NO_PRIVILEGES:
+                resolvedSwitchNoPrivileges(cardId,
                         resolutionExtras.getBoolean(EuiccService.EXTRA_RESOLUTION_CONSENT),
-                        callbackIntent, usePortIndex);
+                        callbackIntent);
                 break;
-            }
             default:
                 Log.wtf(TAG, "Unknown action: " + mAction);
                 break;
@@ -358,14 +335,13 @@
         }
     }
 
-    private void resolvedDownloadDeactivateSim(int cardId, int portIndex, boolean consent,
+    private void resolvedDownloadDeactivateSim(int cardId, boolean consent,
             PendingIntent callbackIntent) {
         if (consent) {
             // User has consented; perform the download, but this time, tell the LPA to deactivate
             // any required active SIMs.
             EuiccController.get().downloadSubscription(
                     cardId,
-                    portIndex,
                     mDownloadableSubscription,
                     mSwitchAfterDownload,
                     mCallingPackage,
@@ -388,12 +364,8 @@
                 // privilege prompt should also cover permission to deactivate an active SIM, as
                 // the privilege prompt makes it clear that we're switching from the current
                 // carrier.
-                // Action {@link #ACTION_DOWNLOAD_NO_PRIVILEGES} is no more used in platform,this
-                // method will never get called, pass {@link TelephonyManager#DEFAULT_PORT_INDEX}
-                // as portIndex.
                 EuiccController.get().downloadSubscriptionPrivileged(
                         cardId,
-                        TelephonyManager.DEFAULT_PORT_INDEX,
                         token,
                         mDownloadableSubscription,
                         mSwitchAfterDownload,
@@ -411,7 +383,7 @@
     }
 
     private void resolvedDownloadNoPrivilegesOrDeactivateSimCheckMetadata(int cardId,
-            int portIndex, boolean consent, PendingIntent callbackIntent) {
+            boolean consent, PendingIntent callbackIntent) {
         if (consent) {
             // User has consented; perform the download with full privileges.
             long token = Binder.clearCallingIdentity();
@@ -422,7 +394,6 @@
                 // carrier.
                 EuiccController.get().downloadSubscriptionPrivilegedCheckMetadata(
                         cardId,
-                        portIndex,
                         token,
                         mDownloadableSubscription,
                         mSwitchAfterDownload,
@@ -450,11 +421,8 @@
             fail(callbackIntent);
         } else {
             mDownloadableSubscription.setConfirmationCode(confirmationCode);
-            // Action {@link #ACTION_DOWNLOAD_CONFIRMATION_CODE} is not any more used from LPA with
-            // targetSDK >=Q, pass {@link TelephonyManager#DEFAULT_PORT_INDEX} as portIndex.
             EuiccController.get().downloadSubscription(
                     cardId,
-                    TelephonyManager.DEFAULT_PORT_INDEX,
                     mDownloadableSubscription,
                     mSwitchAfterDownload,
                     mCallingPackage,
@@ -489,8 +457,6 @@
             mDownloadableSubscription.setConfirmationCode(confirmationCode);
             EuiccController.get().downloadSubscription(
                     cardId,
-                    resolvedBundle.getInt(EuiccService.EXTRA_RESOLUTION_PORT_INDEX,
-                            TelephonyManager.DEFAULT_PORT_INDEX),
                     mDownloadableSubscription,
                     mSwitchAfterDownload,
                     mCallingPackage,
@@ -516,28 +482,25 @@
         }
     }
 
-    private void resolvedSwitchDeactivateSim(int cardId, int portIndex, boolean consent,
-            PendingIntent callbackIntent, boolean usePortIndex) {
+    private void resolvedSwitchDeactivateSim(int cardId, boolean consent,
+            PendingIntent callbackIntent) {
         if (consent) {
             // User has consented; perform the switch, but this time, tell the LPA to deactivate any
             // required active SIMs.
-            EuiccController euiccController = EuiccController.get();
-            euiccController.switchToSubscription(
+            EuiccController.get().switchToSubscription(
                     cardId,
                     mSubscriptionId,
-                    portIndex,
                     true /* forceDeactivateSim */,
                     mCallingPackage,
-                    callbackIntent,
-                    usePortIndex);
+                    callbackIntent);
         } else {
             // User has not consented; fail the operation.
             fail(callbackIntent);
         }
     }
 
-    private void resolvedSwitchNoPrivileges(int cardId, int portIndex, boolean consent,
-            PendingIntent callbackIntent, boolean usePortIndex) {
+    private void resolvedSwitchNoPrivileges(int cardId, boolean consent,
+            PendingIntent callbackIntent) {
         if (consent) {
             // User has consented; perform the switch with full privileges.
             long token = Binder.clearCallingIdentity();
@@ -548,16 +511,13 @@
                 // carrier. Also note that in practice, we'd need to deactivate the active SIM to
                 // even reach this point, because we cannot fetch the metadata needed to check the
                 // privileges without doing so.
-                EuiccController euiccController = EuiccController.get();
-                euiccController.switchToSubscriptionPrivileged(
+                EuiccController.get().switchToSubscriptionPrivileged(
                         cardId,
-                        portIndex,
                         token,
                         mSubscriptionId,
                         true /* forceDeactivateSim */,
                         mCallingPackage,
-                        callbackIntent,
-                        usePortIndex);
+                        callbackIntent);
             } finally {
                 Binder.restoreCallingIdentity(token);
             }
diff --git a/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java b/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java
index 0abd4ab..86e6463 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmInboundSmsHandler.java
@@ -67,8 +67,7 @@
                 sTestBroadcastReceiver = new GsmCbTestBroadcastReceiver();
                 IntentFilter filter = new IntentFilter();
                 filter.addAction(TEST_ACTION);
-                context.registerReceiver(sTestBroadcastReceiver, filter,
-                        Context.RECEIVER_EXPORTED);
+                context.registerReceiver(sTestBroadcastReceiver, filter);
             }
         }
     }
diff --git a/src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java b/src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
index 1f237b2..b3a8038 100644
--- a/src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/gsm/GsmSMSDispatcher.java
@@ -52,6 +52,9 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private GsmInboundSmsHandler mGsmInboundSmsHandler;
 
+    /** Status report received */
+    private static final int EVENT_NEW_SMS_STATUS_REPORT = 100;
+
     public GsmSMSDispatcher(Phone phone, SmsDispatchersController smsDispatchersController,
             GsmInboundSmsHandler gsmInboundSmsHandler) {
         super(phone, smsDispatchersController);
@@ -84,17 +87,21 @@
     @Override
     public void handleMessage(Message msg) {
         switch (msg.what) {
-            case EVENT_NEW_ICC_SMS:
-                // pass to InboundSmsHandler to process
-                mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, msg.obj);
-                break;
+        case EVENT_NEW_SMS_STATUS_REPORT:
+            handleStatusReport((AsyncResult) msg.obj);
+            break;
 
-            case EVENT_ICC_CHANGED:
-                onUpdateIccAvailability();
-                break;
+        case EVENT_NEW_ICC_SMS:
+        // pass to InboundSmsHandler to process
+        mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS, msg.obj);
+        break;
 
-            default:
-                super.handleMessage(msg);
+        case EVENT_ICC_CHANGED:
+            onUpdateIccAvailability();
+            break;
+
+        default:
+            super.handleMessage(msg);
         }
     }
 
@@ -124,15 +131,17 @@
         return SMSDispatcherUtil.calculateLengthGsm(messageBody, use7bitOnly);
     }
 
-    @Override
-    protected void handleStatusReport(Object o) {
-        if (o instanceof AsyncResult) {
-            byte[] pdu = (byte[]) ((AsyncResult) o).result;
-            mSmsDispatchersController.handleSmsStatusReport(SmsConstants.FORMAT_3GPP, pdu);
-            mCi.acknowledgeLastIncomingGsmSms(true, 0 /* cause */, null);
-        } else {
-            Rlog.e(TAG, "handleStatusReport() called for object type " + o.getClass().getName());
-        }
+    /**
+     * Called when a status report is received. This should correspond to a previously successful
+     * SEND.
+     *
+     * @param ar AsyncResult passed into the message handler. ar.result should be a byte array for
+     *           the status report PDU.
+     */
+    private void handleStatusReport(AsyncResult ar) {
+        byte[] pdu = (byte[]) ar.result;
+        mSmsDispatchersController.handleSmsStatusReport(SmsConstants.FORMAT_3GPP, pdu);
+        mCi.acknowledgeLastIncomingGsmSms(true, 0 /* cause */, null);
     }
 
     /** {@inheritDoc} */
diff --git a/src/java/com/android/internal/telephony/ims/ImsResolver.java b/src/java/com/android/internal/telephony/ims/ImsResolver.java
index c3331d9..188e695 100644
--- a/src/java/com/android/internal/telephony/ims/ImsResolver.java
+++ b/src/java/com/android/internal/telephony/ims/ImsResolver.java
@@ -47,11 +47,9 @@
 import android.telephony.ims.stub.ImsFeatureConfiguration;
 import android.text.TextUtils;
 import android.util.ArrayMap;
-import android.util.ArraySet;
 import android.util.LocalLog;
 import android.util.Log;
 import android.util.SparseArray;
-import android.util.SparseIntArray;
 
 import com.android.ims.ImsFeatureBinderRepository;
 import com.android.ims.ImsFeatureContainer;
@@ -139,9 +137,8 @@
     public static void make(Context context, String defaultMmTelPackageName,
             String defaultRcsPackageName, int numSlots, ImsFeatureBinderRepository repo) {
         if (sInstance == null) {
-            Looper looper = Looper.getMainLooper();
             sInstance = new ImsResolver(context, defaultMmTelPackageName, defaultRcsPackageName,
-                    numSlots, repo, looper);
+                    numSlots, repo);
         }
     }
 
@@ -287,10 +284,10 @@
                 return;
             }
 
-            Log.i(TAG, "Received Carrier Config Changed for SlotId: " + slotId + ", SubId: "
-                    + subId + ", sim state: " + slotSimState);
+            Log.i(TAG, "Received Carrier Config Changed for SlotId: " + slotId
+                    + ", sim state: " + slotSimState);
 
-            mHandler.obtainMessage(HANDLER_CONFIG_CHANGED, slotId, subId).sendToTarget();
+            mHandler.obtainMessage(HANDLER_CONFIG_CHANGED, slotId).sendToTarget();
         }
     };
 
@@ -439,104 +436,94 @@
     // Must synchronize on this object to access.
     private final Map<Integer, String> mDeviceServices = new ArrayMap<>();
     // Persistent Logging
-    private final LocalLog mEventLog = new LocalLog(32);
+    private final LocalLog mEventLog = new LocalLog(50);
 
     private boolean mBootCompletedHandlerRan = false;
     private boolean mCarrierConfigReceived = false;
 
     // Synchronize all events on a handler to ensure that the cache includes the most recent
     // version of the installed ImsServices.
-    private final Handler mHandler;
-    private class ResolverHandler extends Handler {
-
-        ResolverHandler(Looper looper) {
-            super(looper);
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case HANDLER_ADD_PACKAGE: {
-                    String packageName = (String) msg.obj;
-                    maybeAddedImsService(packageName);
-                    break;
-                }
-                case HANDLER_REMOVE_PACKAGE: {
-                    String packageName = (String) msg.obj;
-                    maybeRemovedImsService(packageName);
-                    break;
-                }
-                case HANDLER_BOOT_COMPLETE: {
-                    if (!mBootCompletedHandlerRan) {
-                        mBootCompletedHandlerRan = true;
-                        mEventLog.log("handling BOOT_COMPLETE");
-                        if (mCarrierConfigReceived) {
-                            mEventLog.log("boot complete - reeval");
-                            // Re-evaluate bound services for all slots after requerying
-                            //packagemanager
-                            maybeAddedImsService(null /*packageName*/);
-                        } else {
-                            mEventLog.log("boot complete - update cache");
-                            // Do not bind any ImsServices yet, just update the cache to include new
-                            // services. All will be re-evaluated after first carrier config changed
-                            updateInstalledServicesCache();
-                        }
-                    }
-                    break;
-                }
-                case HANDLER_CONFIG_CHANGED: {
-                    int slotId = msg.arg1;
-                    int subId = msg.arg2;
-                    // If the msim config has changed and there is a residual event for an invalid
-                    // slot,ignore.
-                    if (slotId >= mNumSlots) {
-                        Log.w(TAG, "HANDLER_CONFIG_CHANGED for invalid slotid=" + slotId);
-                        break;
-                    }
-                    mCarrierConfigReceived = true;
-                    carrierConfigChanged(slotId, subId);
-                    break;
-                }
-                case HANDLER_START_DYNAMIC_FEATURE_QUERY: {
-                    ImsServiceInfo info = (ImsServiceInfo) msg.obj;
-                    startDynamicQuery(info);
-                    break;
-                }
-                case HANDLER_DYNAMIC_FEATURE_CHANGE: {
-                    SomeArgs args = (SomeArgs) msg.obj;
-                    ComponentName name = (ComponentName) args.arg1;
-                    Set<ImsFeatureConfiguration.FeatureSlotPair> features =
-                            (Set<ImsFeatureConfiguration.FeatureSlotPair>) args.arg2;
-                    args.recycle();
-                    dynamicQueryComplete(name, features);
-                    break;
-                }
-                case HANDLER_OVERRIDE_IMS_SERVICE_CONFIG: {
-                    OverrideConfig config = (OverrideConfig) msg.obj;
-                    if (config.isCarrierService) {
-                        overrideCarrierService(config.slotId,
-                                config.featureTypeToPackageMap);
-                    } else {
-                        overrideDeviceService(config.featureTypeToPackageMap);
-                    }
-                    break;
-                }
-                case HANDLER_MSIM_CONFIGURATION_CHANGE: {
-                    AsyncResult result = (AsyncResult) msg.obj;
-                    handleMsimConfigChange((Integer) result.result);
-                    break;
-                }
-                case HANDLER_CLEAR_CARRIER_IMS_SERVICE_CONFIG: {
-                    clearCarrierServiceOverrides(msg.arg1);
-                    break;
-                }
-                default:
-                    break;
+    private final Handler mHandler = new Handler(Looper.getMainLooper(), (msg) -> {
+        switch (msg.what) {
+            case HANDLER_ADD_PACKAGE: {
+                String packageName = (String) msg.obj;
+                maybeAddedImsService(packageName);
+                break;
             }
+            case HANDLER_REMOVE_PACKAGE: {
+                String packageName = (String) msg.obj;
+                maybeRemovedImsService(packageName);
+                break;
+            }
+            case HANDLER_BOOT_COMPLETE: {
+                if (!mBootCompletedHandlerRan) {
+                    mBootCompletedHandlerRan = true;
+                    mEventLog.log("handling BOOT_COMPLETE");
+                    if (mCarrierConfigReceived) {
+                        mEventLog.log("boot complete - reeval");
+                        // Re-evaluate bound services for all slots after requerying packagemanager
+                        maybeAddedImsService(null /*packageName*/);
+                    } else {
+                        mEventLog.log("boot complete - update cache");
+                        // Do not bind any ImsServices yet, just update the cache to include new
+                        // services. All will be re-evaluated after first carrier config changed.
+                        updateInstalledServicesCache();
+                    }
+                }
+                break;
+            }
+            case HANDLER_CONFIG_CHANGED: {
+                int slotId = (Integer) msg.obj;
+                // If the msim config has changed and there is a residual event for an invalid slot,
+                // ignore.
+                if (slotId >= mNumSlots) {
+                    Log.w(TAG, "HANDLER_CONFIG_CHANGED for invalid slotid=" + slotId);
+                    break;
+                }
+                mCarrierConfigReceived = true;
+                carrierConfigChanged(slotId);
+                break;
+            }
+            case HANDLER_START_DYNAMIC_FEATURE_QUERY: {
+                ImsServiceInfo info = (ImsServiceInfo) msg.obj;
+                startDynamicQuery(info);
+                break;
+            }
+            case HANDLER_DYNAMIC_FEATURE_CHANGE: {
+                SomeArgs args = (SomeArgs) msg.obj;
+                ComponentName name = (ComponentName) args.arg1;
+                Set<ImsFeatureConfiguration.FeatureSlotPair> features =
+                        (Set<ImsFeatureConfiguration.FeatureSlotPair>) args.arg2;
+                args.recycle();
+                dynamicQueryComplete(name, features);
+                break;
+            }
+            case HANDLER_OVERRIDE_IMS_SERVICE_CONFIG: {
+                OverrideConfig config = (OverrideConfig) msg.obj;
+                if (config.isCarrierService) {
+                    overrideCarrierService(config.slotId,
+                            config.featureTypeToPackageMap);
+                } else {
+                    overrideDeviceService(config.featureTypeToPackageMap);
+                }
+                break;
+            }
+            case HANDLER_MSIM_CONFIGURATION_CHANGE: {
+                AsyncResult result = (AsyncResult) msg.obj;
+                handleMsimConfigChange((Integer) result.result);
+                break;
+            }
+            case HANDLER_CLEAR_CARRIER_IMS_SERVICE_CONFIG: {
+                clearCarrierServiceOverrides(msg.arg1);
+                break;
+            }
+            default:
+                return false;
         }
-    }
+        return true;
+    });
 
-    private final HandlerExecutor mRunnableExecutor;
+    private final HandlerExecutor mRunnableExecutor = new HandlerExecutor(mHandler);
 
     // Results from dynamic queries to ImsService regarding the features they support.
     private final ImsServiceFeatureQueryManager.Listener mDynamicQueryListener =
@@ -579,11 +566,9 @@
     // Active ImsServiceControllers, which are bound to ImsServices.
     private final Map<ComponentName, ImsServiceController> mActiveControllers = new HashMap<>();
     private ImsServiceFeatureQueryManager mFeatureQueryManager;
-    private final SparseIntArray mSlotIdToSubIdMap;
 
     public ImsResolver(Context context, String defaultMmTelPackageName,
-            String defaultRcsPackageName, int numSlots, ImsFeatureBinderRepository repo,
-            Looper looper) {
+            String defaultRcsPackageName, int numSlots, ImsFeatureBinderRepository repo) {
         Log.i(TAG, "device MMTEL package: " + defaultMmTelPackageName + ", device RCS package:"
                 + defaultRcsPackageName);
         mContext = context;
@@ -591,8 +576,6 @@
         mRepo = repo;
         mReceiverContext = context.createContextAsUser(UserHandle.ALL, 0 /*flags*/);
 
-        mHandler = new ResolverHandler(looper);
-        mRunnableExecutor = new HandlerExecutor(mHandler);
         mCarrierServices = new SparseArray<>(mNumSlots);
         setDeviceConfiguration(defaultMmTelPackageName, ImsFeature.FEATURE_EMERGENCY_MMTEL);
         setDeviceConfiguration(defaultMmTelPackageName, ImsFeature.FEATURE_MMTEL);
@@ -601,10 +584,6 @@
                 Context.CARRIER_CONFIG_SERVICE);
         mOverrideServices = new SparseArray<>(0 /*initial size*/);
         mBoundImsServicesByFeature = new SparseArray<>(mNumSlots);
-        mSlotIdToSubIdMap = new SparseIntArray(mNumSlots);
-        for (int i = 0; i < mNumSlots; i++) {
-            mSlotIdToSubIdMap.put(i, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        }
     }
 
     @VisibleForTesting
@@ -697,8 +676,7 @@
     private void bindCarrierServicesIfAvailable() {
         boolean hasConfigChanged = false;
         for (int slotId = 0; slotId < mNumSlots; slotId++) {
-            int subId = mSubscriptionManagerProxy.getSubId(slotId);
-            Map<Integer, String> featureMap = getImsPackageOverrideConfig(subId);
+            Map<Integer, String> featureMap = getImsPackageOverrideConfig(slotId);
             for (int f = ImsFeature.FEATURE_EMERGENCY_MMTEL; f < ImsFeature.FEATURE_MAX; f++) {
                 String newPackageName = featureMap.getOrDefault(f, "");
                 if (!TextUtils.isEmpty(newPackageName)) {
@@ -706,7 +684,6 @@
                             + newPackageName + " on slot " + slotId);
                     // Carrier configs are already available, so mark received.
                     mCarrierConfigReceived = true;
-                    setSubId(slotId, subId);
                     setCarrierConfiguredPackageName(newPackageName, slotId, f);
                     ImsServiceInfo info = getImsServiceInfoFromCache(newPackageName);
                     // We do not want to trigger feature configuration changes unless there is
@@ -728,8 +705,13 @@
      * trigger ImsFeature status updates.
      */
     public void enableIms(int slotId) {
-        getImsServiceControllers(slotId).forEach(
-                (controller) -> controller.enableIms(slotId, getSubId(slotId)));
+        SparseArray<ImsServiceController> controllers = getImsServiceControllers(slotId);
+        if (controllers != null) {
+            for (int i = 0; i < controllers.size(); i++) {
+                int key = controllers.keyAt(i);
+                controllers.get(key).enableIms(slotId);
+            }
+        }
     }
 
     /**
@@ -737,8 +719,13 @@
      * trigger ImsFeature capability status to become false.
      */
     public void disableIms(int slotId) {
-        getImsServiceControllers(slotId).forEach(
-                (controller) -> controller.disableIms(slotId, getSubId(slotId)));
+        SparseArray<ImsServiceController> controllers = getImsServiceControllers(slotId);
+        if (controllers != null) {
+            for (int i = 0; i < controllers.size(); i++) {
+                int key = controllers.keyAt(i);
+                controllers.get(key).disableIms(slotId);
+            }
+        }
     }
 
     /**
@@ -757,31 +744,17 @@
         return  (fc != null) ? fc.imsConfig : null;
     }
 
-    /**
-     * @return A Set containing all the bound ImsServiceControllers for the slotId specified.
-     */
-    private Set<ImsServiceController> getImsServiceControllers(int slotId) {
+    private  SparseArray<ImsServiceController> getImsServiceControllers(int slotId) {
         if (slotId < 0 || slotId >= mNumSlots) {
-            return Collections.emptySet();
+            return null;
         }
-        SparseArray<ImsServiceController> featureToControllerMap;
         synchronized (mBoundServicesLock) {
-            featureToControllerMap =  mBoundImsServicesByFeature.get(slotId);
+            SparseArray<ImsServiceController> services = mBoundImsServicesByFeature.get(slotId);
+            if (services == null) {
+                return null;
+            }
+            return services;
         }
-        if (featureToControllerMap == null) {
-            Log.w(TAG, "getImsServiceControllers: couldn't find any active "
-                    + "ImsServiceControllers");
-            return Collections.emptySet();
-        }
-        // Create a temporary set to dedupe when multiple features map to the same
-        // ImsServiceController
-        Set<ImsServiceController> controllers = new ArraySet<>(2);
-        for (int i = 0; i < featureToControllerMap.size(); i++) {
-            int key = featureToControllerMap.keyAt(i);
-            ImsServiceController c = featureToControllerMap.get(key);
-            if (c != null) controllers.add(c);
-        }
-        return controllers;
     }
 
     /**
@@ -1209,12 +1182,11 @@
         if (shouldFeaturesCauseBind(features)) {
             // Check to see if an active controller already exists
             ImsServiceController controller = getControllerByServiceInfo(mActiveControllers, info);
-            SparseIntArray slotIdToSubIdMap = mSlotIdToSubIdMap.clone();
             if (controller != null) {
                 Log.i(TAG, "ImsService connection exists for " + info.name + ", updating features "
                         + features);
                 try {
-                    controller.changeImsServiceFeatures(features, slotIdToSubIdMap);
+                    controller.changeImsServiceFeatures(features);
                     // Features have been set, there was an error adding/removing. When the
                     // controller recovers, it will add/remove again.
                 } catch (RemoteException e) {
@@ -1224,7 +1196,7 @@
                 controller = info.controllerFactory.create(mContext, info.name, this, mRepo);
                 Log.i(TAG, "Binding ImsService: " + controller.getComponentName()
                         + " with features: " + features);
-                controller.bind(features, slotIdToSubIdMap);
+                controller.bind(features);
                 mEventLog.log("bindImsServiceWithFeatures - create new controller: "
                         + controller);
             }
@@ -1286,7 +1258,7 @@
     /**
      * Implementation of
      * {@link ImsServiceController.ImsServiceControllerCallbacks#imsServiceFeatureCreated}, which
-     * adds the ImsServiceController from the mBoundImsServicesByFeature structure.
+     * removes the ImsServiceController from the mBoundImsServicesByFeature structure.
      */
     @Override
     public void imsServiceFeatureCreated(int slotId, int feature, ImsServiceController controller) {
@@ -1362,7 +1334,7 @@
         Log.i(TAG, "clearing carrier ImsService overrides");
         mEventLog.log("clearing carrier ImsService overrides");
         removeOverridePackageName(slotId);
-        carrierConfigChanged(slotId, getSubId(slotId));
+        carrierConfigChanged(slotId);
     }
 
     // Possibly rebind to another ImsService for testing carrier ImsServices.
@@ -1393,16 +1365,16 @@
     }
 
     // Called from handler ONLY.
-    private void carrierConfigChanged(int slotId, int subId) {
-        setSubId(slotId, subId);
+    private void carrierConfigChanged(int slotId) {
         updateBoundDeviceServices();
+
         if (slotId <= SubscriptionManager.INVALID_SIM_SLOT_INDEX) {
             // not specified, update carrier override cache and possibly rebind on all slots.
             for (int i = 0; i < mNumSlots; i++) {
-                updateBoundServices(i, getImsPackageOverrideConfig(getSubId(i)));
+                updateBoundServices(i, getImsPackageOverrideConfig(i));
             }
         }
-        updateBoundServices(slotId, getImsPackageOverrideConfig(subId));
+        updateBoundServices(slotId, getImsPackageOverrideConfig(slotId));
     }
 
     private void updateBoundDeviceServices() {
@@ -1468,7 +1440,8 @@
         }
     }
 
-    private @NonNull Map<Integer, String> getImsPackageOverrideConfig(int subId) {
+    private @NonNull Map<Integer, String> getImsPackageOverrideConfig(int slotId) {
+        int subId = mSubscriptionManagerProxy.getSubId(slotId);
         PersistableBundle config = mCarrierConfigManager.getConfigForSubId(subId);
         if (config == null) return Collections.emptyMap();
         String packageNameMmTel = config.getString(
@@ -1557,8 +1530,6 @@
                     int feature = overrideConfigs.keyAt(i);
                     setOverridePackageName("", oldSlot, feature);
                 }
-                //clear removed slot.
-                removeSlotId(oldSlot);
             }
         }
         // Get the new config for each ImsService. For manifest queries, this will update the
@@ -1787,23 +1758,6 @@
         return infos;
     }
 
-    private void setSubId(int slotId, int subId) {
-        synchronized (mSlotIdToSubIdMap) {
-            mSlotIdToSubIdMap.put(slotId, subId);
-        }
-    }
-
-    private int getSubId(int slotId) {
-        synchronized (mSlotIdToSubIdMap) {
-            return mSlotIdToSubIdMap.get(slotId, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        }
-    }
-    private void removeSlotId(int slotId) {
-        synchronized (mSlotIdToSubIdMap) {
-            mSlotIdToSubIdMap.delete(slotId);
-        }
-    }
-
     // Dump is called on the main thread, since ImsResolver Handler is also handled on main thread,
     // we shouldn't need to worry about concurrent access of private params.
     public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
diff --git a/src/java/com/android/internal/telephony/ims/ImsServiceController.java b/src/java/com/android/internal/telephony/ims/ImsServiceController.java
index 9ae40e1..c47d5b0 100644
--- a/src/java/com/android/internal/telephony/ims/ImsServiceController.java
+++ b/src/java/com/android/internal/telephony/ims/ImsServiceController.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.telephony.ims;
 
-import static android.telephony.SubscriptionManager.PLACEHOLDER_SUBSCRIPTION_ID_BASE;
-
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -32,7 +30,6 @@
 import android.os.UserHandle;
 import android.permission.LegacyPermissionManager;
 import android.telephony.AnomalyReporter;
-import android.telephony.SubscriptionManager;
 import android.telephony.ims.ImsService;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsRegistration;
@@ -42,7 +39,6 @@
 import android.telephony.ims.stub.ImsFeatureConfiguration;
 import android.util.LocalLog;
 import android.util.Log;
-import android.util.SparseIntArray;
 
 import com.android.ims.ImsFeatureBinderRepository;
 import com.android.ims.ImsFeatureContainer;
@@ -52,7 +48,6 @@
 import com.android.internal.telephony.util.TelephonyUtils;
 
 import java.io.PrintWriter;
-import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -101,7 +96,7 @@
                     for (ImsFeatureConfiguration.FeatureSlotPair i : mImsFeatures) {
                         long caps = modifyCapabiltiesForSlot(mImsFeatures, i.slotId,
                                 mServiceCapabilities);
-                        addImsServiceFeature(i, caps, mSlotIdToSubIdMap.get(i.slotId));
+                        addImsServiceFeature(i, caps);
                     }
                 } catch (RemoteException e) {
                     mIsBound = false;
@@ -240,14 +235,13 @@
     private boolean mIsBinding = false;
     // Set of a pair of slotId->feature
     private Set<ImsFeatureConfiguration.FeatureSlotPair> mImsFeatures;
-    private SparseIntArray mSlotIdToSubIdMap;
     private IImsServiceController mIImsServiceController;
     // The Capabilities bitmask of the connected ImsService (see ImsService#ImsServiceCapability).
     private long mServiceCapabilities;
     private ImsServiceConnection mImsServiceConnection;
     // Only added or removed, never accessed on purpose.
     private Set<ImsFeatureStatusCallback> mFeatureStatusCallbacks = new HashSet<>();
-    private final LocalLog mLocalLog = new LocalLog(8);
+    private final LocalLog mLocalLog = new LocalLog(10);
 
     protected final Object mLock = new Object();
     protected final Context mContext;
@@ -301,7 +295,7 @@
                 if (mIsBound) {
                     return;
                 }
-                bind(mImsFeatures, mSlotIdToSubIdMap);
+                bind(mImsFeatures);
             }
         }
     };
@@ -371,14 +365,12 @@
      * @return {@link true} if the service is in the process of being bound, {@link false} if it
      * has failed.
      */
-    public boolean bind(Set<ImsFeatureConfiguration.FeatureSlotPair> imsFeatureSet,
-            SparseIntArray  slotIdToSubIdMap) {
+    public boolean bind(Set<ImsFeatureConfiguration.FeatureSlotPair> imsFeatureSet) {
         synchronized (mLock) {
             if (!mIsBound && !mIsBinding) {
                 mIsBinding = true;
                 sanitizeFeatureConfig(imsFeatureSet);
                 mImsFeatures = imsFeatureSet;
-                mSlotIdToSubIdMap = slotIdToSubIdMap;
                 grantPermissionsToService();
                 Intent imsServiceIntent = new Intent(getServiceInterface()).setComponent(
                         mComponentName);
@@ -435,7 +427,7 @@
         synchronized (mLock) {
             mBackoff.stop();
             // Clean up all features
-            changeImsServiceFeatures(new HashSet<>(), mSlotIdToSubIdMap);
+            changeImsServiceFeatures(new HashSet<>());
             mIsBound = false;
             mIsBinding = false;
             setServiceController(null);
@@ -448,27 +440,15 @@
      * ImsFeature that is removed, {@link IImsServiceController#removeImsFeature} is called.
      */
     public void changeImsServiceFeatures(
-            Set<ImsFeatureConfiguration.FeatureSlotPair> newImsFeatures,
-                    SparseIntArray  slotIdToSubIdMap) throws RemoteException {
+            Set<ImsFeatureConfiguration.FeatureSlotPair> newImsFeatures)
+            throws RemoteException {
         sanitizeFeatureConfig(newImsFeatures);
         synchronized (mLock) {
-            HashSet<Integer> slotIDs =  new HashSet<>();
-            slotIDs.addAll(newImsFeatures.stream().map(e -> e.slotId).collect(Collectors.toSet()));
-            ArrayList<Integer> changedSubIds = new ArrayList<Integer>();
-            for (Integer slotID : slotIDs) {
-                if (mSlotIdToSubIdMap.get(slotID, PLACEHOLDER_SUBSCRIPTION_ID_BASE)
-                        != slotIdToSubIdMap.get(slotID)) {
-                    changedSubIds.add(slotIdToSubIdMap.get(slotID));
-                    mLocalLog.log("changed sub IDs: " + changedSubIds);
-                    Log.i(LOG_TAG, "changed sub IDs: " + changedSubIds);
-                }
-            }
-            mSlotIdToSubIdMap = slotIdToSubIdMap;
-            if (mImsFeatures.equals(newImsFeatures) && !isSubIdChanged(changedSubIds)) {
+            if (mImsFeatures.equals(newImsFeatures)) {
                 return;
             }
-            mLocalLog.log("Features (" + mImsFeatures + "->" + newImsFeatures + ")");
-            Log.i(LOG_TAG, "Features (" + mImsFeatures + "->" + newImsFeatures + ") for "
+            mLocalLog.log("Features changed (" + mImsFeatures + "->" + newImsFeatures + ")");
+            Log.i(LOG_TAG, "Features changed (" + mImsFeatures + "->" + newImsFeatures + ") for "
                     + "ImsService: " + mComponentName);
             HashSet<ImsFeatureConfiguration.FeatureSlotPair> oldImsFeatures =
                     new HashSet<>(mImsFeatures);
@@ -482,40 +462,20 @@
                 for (ImsFeatureConfiguration.FeatureSlotPair i : newFeatures) {
                     long caps = modifyCapabiltiesForSlot(mImsFeatures, i.slotId,
                             mServiceCapabilities);
-                    addImsServiceFeature(i, caps, mSlotIdToSubIdMap.get(i.slotId));
+                    addImsServiceFeature(i, caps);
                 }
                 // remove old features
                 HashSet<ImsFeatureConfiguration.FeatureSlotPair> oldFeatures =
                         new HashSet<>(oldImsFeatures);
                 oldFeatures.removeAll(mImsFeatures);
                 for (ImsFeatureConfiguration.FeatureSlotPair i : oldFeatures) {
-                    removeImsServiceFeature(i, false);
+                    removeImsServiceFeature(i);
                 }
                 // ensure the capabilities have been updated for unchanged features.
                 HashSet<ImsFeatureConfiguration.FeatureSlotPair> unchangedFeatures =
                         new HashSet<>(mImsFeatures);
                 unchangedFeatures.removeAll(oldFeatures);
                 unchangedFeatures.removeAll(newFeatures);
-                // ensure remove and add unchanged features that have a slot ID associated with
-                // the new subscription ID.
-                if (isSubIdChanged(changedSubIds)) {
-                    for (Integer changedSubId : changedSubIds) {
-                        int slotId = mSlotIdToSubIdMap.indexOfValue(changedSubId);
-                        HashSet<ImsFeatureConfiguration.FeatureSlotPair>
-                                removeAddFeatures = new HashSet<>();
-                        removeAddFeatures.addAll(unchangedFeatures.stream()
-                                .filter(e -> e.slotId == slotId).collect(Collectors.toSet()));
-                        for (ImsFeatureConfiguration.FeatureSlotPair i : removeAddFeatures) {
-                            removeImsServiceFeature(i, true);
-                        }
-                        for (ImsFeatureConfiguration.FeatureSlotPair i : removeAddFeatures) {
-                            long caps = modifyCapabiltiesForSlot(mImsFeatures, i.slotId,
-                                    mServiceCapabilities);
-                            addImsServiceFeature(i, caps, changedSubId);
-                        }
-                        unchangedFeatures.removeAll(removeAddFeatures);
-                    }
-                }
                 for (ImsFeatureConfiguration.FeatureSlotPair p : unchangedFeatures) {
                     long caps = modifyCapabiltiesForSlot(mImsFeatures, p.slotId,
                             mServiceCapabilities);
@@ -544,15 +504,11 @@
         return mComponentName;
     }
 
-    /**
-     * Notify ImsService to enable IMS for the framework. This will trigger IMS registration and
-     * trigger ImsFeature status updates.
-     */
-    public void enableIms(int slotId, int subId) {
+    public void enableIms(int slotId) {
         try {
             synchronized (mLock) {
                 if (isServiceControllerAvailable()) {
-                    mIImsServiceController.enableIms(slotId, subId);
+                    mIImsServiceController.enableIms(slotId);
                 }
             }
         } catch (RemoteException e) {
@@ -560,15 +516,11 @@
         }
     }
 
-    /**
-     * Notify ImsService to disable IMS for the framework. This will trigger IMS de-registration and
-     * trigger ImsFeature capability status to become false.
-     */
-    public void disableIms(int slotId, int subId) {
+    public void disableIms(int slotId) {
         try {
             synchronized (mLock) {
                 if (isServiceControllerAvailable()) {
-                    mIImsServiceController.disableIms(slotId, subId);
+                    mIImsServiceController.disableIms(slotId);
                 }
             }
         } catch (RemoteException e) {
@@ -579,20 +531,19 @@
     /**
      * @return the IImsRegistration that corresponds to the slot id specified.
      */
-    public IImsRegistration getRegistration(int slotId, int subId) throws RemoteException {
+    public IImsRegistration getRegistration(int slotId) throws RemoteException {
         synchronized (mLock) {
             return isServiceControllerAvailable()
-                    ? mIImsServiceController.getRegistration(slotId, subId) : null;
+                    ? mIImsServiceController.getRegistration(slotId) : null;
         }
     }
 
     /**
      * @return the IImsConfig that corresponds to the slot id specified.
      */
-    public IImsConfig getConfig(int slotId, int subId) throws RemoteException {
+    public IImsConfig getConfig(int slotId) throws RemoteException {
         synchronized (mLock) {
-            return isServiceControllerAvailable()
-                    ? mIImsServiceController.getConfig(slotId, subId) : null;
+            return isServiceControllerAvailable() ? mIImsServiceController.getConfig(slotId) : null;
         }
     }
 
@@ -735,16 +686,15 @@
 
     // This method should only be called when synchronized on mLock
     private void addImsServiceFeature(ImsFeatureConfiguration.FeatureSlotPair featurePair,
-            long capabilities, int subId) throws RemoteException {
+            long capabilities)
+            throws RemoteException {
         if (!isServiceControllerAvailable() || mCallbacks == null) {
             Log.w(LOG_TAG, "addImsServiceFeature called with null values.");
             return;
         }
         if (featurePair.featureType != ImsFeature.FEATURE_EMERGENCY_MMTEL) {
-            IInterface f = createImsFeature(
-                    featurePair.slotId, subId, featurePair.featureType, capabilities);
-            addImsFeatureBinder(featurePair.slotId, subId, featurePair.featureType,
-                    f, capabilities);
+            IInterface f = createImsFeature(featurePair.slotId, featurePair.featureType);
+            addImsFeatureBinder(featurePair.slotId, featurePair.featureType, f, capabilities);
             addImsFeatureStatusCallback(featurePair.slotId, featurePair.featureType);
         } else {
             // Don't update ImsService for emergency MMTEL feature.
@@ -755,8 +705,7 @@
     }
 
     // This method should only be called when synchronized on mLock
-    private void removeImsServiceFeature(ImsFeatureConfiguration.FeatureSlotPair featurePair,
-            boolean changeSubId) {
+    private void removeImsServiceFeature(ImsFeatureConfiguration.FeatureSlotPair featurePair) {
         if (!isServiceControllerAvailable() || mCallbacks == null) {
             Log.w(LOG_TAG, "removeImsServiceFeature called with null values.");
             return;
@@ -767,7 +716,7 @@
             removeImsFeatureStatusCallback(featurePair.slotId, featurePair.featureType);
             removeImsFeatureBinder(featurePair.slotId, featurePair.featureType);
             try {
-                removeImsFeature(featurePair.slotId, featurePair.featureType, changeSubId);
+                removeImsFeature(featurePair.slotId, featurePair.featureType);
             } catch (RemoteException e) {
                 // The connection to this ImsService doesn't exist. This may happen if the service
                 // has died and we are removing features.
@@ -783,23 +732,14 @@
 
     // This method should only be called when already synchronized on mLock.
     // overridden by compat layer to create features
-    protected IInterface createImsFeature(int slotId, int subId, int featureType, long capabilities)
+    protected IInterface createImsFeature(int slotId, int featureType)
             throws RemoteException {
         switch (featureType) {
             case ImsFeature.FEATURE_MMTEL: {
-                if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-                    boolean emergencyAvailable =
-                            (capabilities & ImsService.CAPABILITY_EMERGENCY_OVER_MMTEL) > 0;
-                    if (emergencyAvailable) {
-                        return mIImsServiceController.createEmergencyOnlyMmTelFeature(slotId);
-                    } else {
-                        return null;
-                    }
-                }
-                return mIImsServiceController.createMmTelFeature(slotId, subId);
+                return mIImsServiceController.createMmTelFeature(slotId);
             }
             case ImsFeature.FEATURE_RCS: {
-                return mIImsServiceController.createRcsFeature(slotId, subId);
+                return mIImsServiceController.createRcsFeature(slotId);
             }
             default:
                 return null;
@@ -842,13 +782,12 @@
 
 
     // overridden by compat layer to remove features
-    protected void removeImsFeature(int slotId, int featureType, boolean changeSubId)
+    protected void removeImsFeature(int slotId, int featureType)
             throws RemoteException {
-        mIImsServiceController.removeImsFeature(slotId, featureType, changeSubId);
+        mIImsServiceController.removeImsFeature(slotId, featureType);
     }
 
-    private void addImsFeatureBinder(int slotId, int subId, int featureType, IInterface b,
-            long capabilities)
+    private void addImsFeatureBinder(int slotId, int featureType, IInterface b, long capabilities)
             throws RemoteException {
         if (b == null) {
 
@@ -858,19 +797,18 @@
                     + ImsFeature.FEATURE_LOG_MAP.get(featureType));
             return;
         }
-        ImsFeatureContainer fc = createFeatureContainer(slotId, subId, b.asBinder(), capabilities);
-        mRepo.addConnection(slotId, subId, featureType, fc);
+        ImsFeatureContainer fc = createFeatureContainer(slotId, b.asBinder(), capabilities);
+        mRepo.addConnection(slotId, featureType, fc);
     }
 
     private void removeImsFeatureBinder(int slotId, int featureType) {
         mRepo.removeConnection(slotId, featureType);
     }
 
-    private ImsFeatureContainer createFeatureContainer(int slotId, int subId, IBinder b,
-            long capabilities)
+    private ImsFeatureContainer createFeatureContainer(int slotId, IBinder b, long capabilities)
             throws RemoteException {
-        IImsConfig config = getConfig(slotId, subId);
-        IImsRegistration reg = getRegistration(slotId, subId);
+        IImsConfig config = getConfig(slotId);
+        IImsRegistration reg = getRegistration(slotId);
         // When either is null, this is an unexpected condition. Do not report the ImsService as
         // being available.
         if (config == null || reg == null) {
@@ -895,7 +833,7 @@
         synchronized (mLock) {
             // Remove all features and clean up all associated Binders.
             for (ImsFeatureConfiguration.FeatureSlotPair i : mImsFeatures) {
-                removeImsServiceFeature(i, false);
+                removeImsServiceFeature(i);
             }
         }
     }
@@ -919,10 +857,6 @@
         AnomalyReporter.reportAnomaly(mAnomalyUUID, message);
     }
 
-    private boolean isSubIdChanged(ArrayList<Integer> changedSubIds) {
-        return !changedSubIds.isEmpty();
-    }
-
     @Override
     public String toString() {
         synchronized (mLock) {
diff --git a/src/java/com/android/internal/telephony/ims/ImsServiceControllerCompat.java b/src/java/com/android/internal/telephony/ims/ImsServiceControllerCompat.java
index 13ec750..8ba390b 100644
--- a/src/java/com/android/internal/telephony/ims/ImsServiceControllerCompat.java
+++ b/src/java/com/android/internal/telephony/ims/ImsServiceControllerCompat.java
@@ -18,7 +18,6 @@
 
 import android.content.ComponentName;
 import android.content.Context;
-import android.os.Handler;
 import android.os.IBinder;
 import android.os.IInterface;
 import android.os.RemoteException;
@@ -37,7 +36,6 @@
 import com.android.ims.internal.IImsFeatureStatusCallback;
 import com.android.ims.internal.IImsMMTelFeature;
 import com.android.ims.internal.IImsServiceController;
-import com.android.internal.annotations.VisibleForTesting;
 
 /**
  * Manages the Binding lifecycle of one ImsService as well as the relevant ImsFeatures that the
@@ -59,33 +57,10 @@
     private final SparseArray<ImsRegistrationCompatAdapter> mRegCompatAdapters =
             new SparseArray<>();
 
-    private final MmTelFeatureCompatFactory mMmTelFeatureFactory;
-
-    /**
-     * Used to inject test instances of MmTelFeatureCompatAdapter
-     */
-    @VisibleForTesting
-    public interface MmTelFeatureCompatFactory {
-        /**
-         * @return A new instance of {@link MmTelFeatureCompatAdapter}
-         */
-        MmTelFeatureCompatAdapter create(Context context, int slotId,
-                MmTelInterfaceAdapter compatFeature);
-    }
-
     public ImsServiceControllerCompat(Context context, ComponentName componentName,
             ImsServiceController.ImsServiceControllerCallbacks callbacks,
             ImsFeatureBinderRepository repo) {
         super(context, componentName, callbacks, repo);
-        mMmTelFeatureFactory = MmTelFeatureCompatAdapter::new;
-    }
-
-    @VisibleForTesting
-    public ImsServiceControllerCompat(Context context, ComponentName componentName,
-            ImsServiceControllerCallbacks callbacks, Handler handler, RebindRetry rebindRetry,
-            ImsFeatureBinderRepository repo, MmTelFeatureCompatFactory factory) {
-        super(context, componentName, callbacks, handler, rebindRetry, repo);
-        mMmTelFeatureFactory = factory;
     }
 
     @Override
@@ -98,7 +73,7 @@
      * Converts the new command to {@link MMTelFeature#turnOnIms()}.
      */
     @Override
-    public final void enableIms(int slotId, int subId) {
+    public final void enableIms(int slotId) {
         MmTelFeatureCompatAdapter adapter = mMmTelCompatAdapters.get(slotId);
         if (adapter == null) {
             Log.w(TAG, "enableIms: adapter null for slot :" + slotId);
@@ -115,7 +90,7 @@
      * Converts the new command to {@link MMTelFeature#turnOffIms()}.
      */
     @Override
-    public final void disableIms(int slotId, int subId) {
+    public final void disableIms(int slotId) {
         MmTelFeatureCompatAdapter adapter = mMmTelCompatAdapters.get(slotId);
         if (adapter == null) {
             Log.w(TAG, "enableIms: adapter null for slot :" + slotId);
@@ -132,7 +107,7 @@
      * @return the IImsRegistration that corresponds to the slot id specified.
      */
     @Override
-    public final IImsRegistration getRegistration(int slotId, int subId) {
+    public final IImsRegistration getRegistration(int slotId) {
         ImsRegistrationCompatAdapter adapter = mRegCompatAdapters.get(slotId);
         if (adapter == null) {
             Log.w(TAG, "getRegistration: Registration does not exist for slot " + slotId);
@@ -145,7 +120,7 @@
      * @return the IImsConfig that corresponds to the slot id specified.
      */
     @Override
-    public final IImsConfig getConfig(int slotId, int subId) {
+    public final IImsConfig getConfig(int slotId) {
         ImsConfigCompatAdapter adapter = mConfigCompatAdapters.get(slotId);
         if (adapter == null) {
             Log.w(TAG, "getConfig: Config does not exist for slot " + slotId);
@@ -176,8 +151,8 @@
     }
 
     @Override
-    protected final IInterface createImsFeature(int slotId, int subId, int featureType,
-            long capabilities) throws RemoteException {
+    protected final IInterface createImsFeature(int slotId, int featureType)
+            throws RemoteException {
         switch (featureType) {
             case ImsFeature.MMTEL: {
                 return createMMTelCompat(slotId);
@@ -208,13 +183,9 @@
     }
 
     @Override
-    protected final void removeImsFeature(int slotId, int featureType, boolean changeSubId)
+    protected final void removeImsFeature(int slotId, int featureType)
             throws RemoteException {
         if (featureType == ImsFeature.MMTEL) {
-            MmTelFeatureCompatAdapter adapter = mMmTelCompatAdapters.get(slotId, null);
-            // Need to manually call onFeatureRemoved here, since this is normally called by the
-            // ImsService itself.
-            if (adapter != null) adapter.onFeatureRemoved();
             mMmTelCompatAdapters.remove(slotId);
             mRegCompatAdapters.remove(slotId);
             mConfigCompatAdapters.remove(slotId);
@@ -247,7 +218,7 @@
     private IImsMmTelFeature createMMTelCompat(int slotId)
             throws RemoteException {
         MmTelInterfaceAdapter interfaceAdapter = getInterface(slotId);
-        MmTelFeatureCompatAdapter mmTelAdapter = mMmTelFeatureFactory.create(mContext, slotId,
+        MmTelFeatureCompatAdapter mmTelAdapter = new MmTelFeatureCompatAdapter(mContext, slotId,
                 interfaceAdapter);
         mMmTelCompatAdapters.put(slotId, mmTelAdapter);
         ImsRegistrationCompatAdapter regAdapter = new ImsRegistrationCompatAdapter();
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsExternalCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsExternalCallTracker.java
index 205628b..0c46a35 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsExternalCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsExternalCallTracker.java
@@ -33,12 +33,10 @@
 import com.android.internal.telephony.Connection;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.util.TelephonyUtils;
 
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.Executor;
 
 /**
  * Responsible for tracking external calls known to the system.
@@ -72,15 +70,9 @@
      * external call state updates from the IMS framework.
      */
     public class ExternalCallStateListener extends ImsExternalCallStateListener {
-        public ExternalCallStateListener(Executor executor) {
-            super(executor);
-        }
-
         @Override
-        public void onImsExternalCallStateUpdate(List<ImsExternalCallState> externalCallState,
-                    Executor executor) {
-            TelephonyUtils.runWithCleanCallingIdentity(()->
-                        refreshExternalCallState(externalCallState), executor);
+        public void onImsExternalCallStateUpdate(List<ImsExternalCallState> externalCallState) {
+            refreshExternalCallState(externalCallState);
         }
     }
 
@@ -157,15 +149,15 @@
 
     @VisibleForTesting
     public ImsExternalCallTracker(ImsPhone phone, ImsPullCall callPuller,
-            ImsCallNotify callNotifier, Executor executor) {
+            ImsCallNotify callNotifier) {
 
         mPhone = phone;
         mCallStateNotifier = callNotifier;
-        mExternalCallStateListener = new ExternalCallStateListener(executor);
+        mExternalCallStateListener = new ExternalCallStateListener();
         mCallPuller = callPuller;
     }
 
-    public ImsExternalCallTracker(ImsPhone phone, Executor executor) {
+    public ImsExternalCallTracker(ImsPhone phone) {
         mPhone = phone;
         mCallStateNotifier = new ImsCallNotify() {
             @Override
@@ -178,7 +170,7 @@
                 mPhone.notifyPreciseCallStateChanged();
             }
         };
-        mExternalCallStateListener = new ExternalCallStateListener(executor);
+        mExternalCallStateListener = new ExternalCallStateListener();
         registerForNotifications();
     }
 
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
index 71e85f3..786bbcf 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhone.java
@@ -16,7 +16,6 @@
 
 package com.android.internal.telephony.imsphone;
 
-import static android.provider.Telephony.SimInfo.COLUMN_PHONE_NUMBER_SOURCE_IMS;
 import static android.telephony.ims.ImsManager.EXTRA_WFC_REGISTRATION_FAILURE_MESSAGE;
 import static android.telephony.ims.ImsManager.EXTRA_WFC_REGISTRATION_FAILURE_TITLE;
 
@@ -71,7 +70,6 @@
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneNumberUtils;
 import android.telephony.ServiceState;
-import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.UssdResponse;
@@ -97,7 +95,6 @@
 import com.android.internal.telephony.CallForwardInfo;
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.CallTracker;
-import com.android.internal.telephony.CarrierPrivilegesTracker;
 import com.android.internal.telephony.CommandException;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.Connection;
@@ -107,9 +104,9 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.PhoneNotifier;
 import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.TelephonyComponentFactory;
 import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.telephony.dataconnection.TransportManager;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
 import com.android.internal.telephony.metrics.ImsStats;
@@ -118,16 +115,13 @@
 import com.android.internal.telephony.nano.TelephonyProto.ImsConnectionState;
 import com.android.internal.telephony.uicc.IccRecords;
 import com.android.internal.telephony.util.NotificationChannelController;
-import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.telephony.Rlog;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
-import java.util.concurrent.Executor;
 import java.util.function.Consumer;
 
 /**
@@ -272,7 +266,7 @@
 
     private final RegistrantList mSilentRedialRegistrants = new RegistrantList();
 
-    private final LocalLog mRegLocalLog = new LocalLog(64);
+    private final LocalLog mRegLocalLog = new LocalLog(100);
     private TelephonyMetrics mMetrics;
 
     // The helper class to receive and store the MmTel registration status updated.
@@ -457,11 +451,7 @@
         mCT.registerPhoneStateListener(mExternalCallTracker);
         mExternalCallTracker.setCallPuller(mCT);
 
-        boolean legacyMode = true;
-        if (mDefaultPhone.getAccessNetworksManager() != null) {
-            legacyMode = mDefaultPhone.getAccessNetworksManager().isInLegacyMode();
-        }
-        mSS.setOutOfService(legacyMode, false);
+        mSS.setStateOff();
 
         mPhoneId = mDefaultPhone.getPhoneId();
 
@@ -475,9 +465,8 @@
         mWakeLock.setReferenceCounted(false);
 
         if (mDefaultPhone.getServiceStateTracker() != null
-                && mDefaultPhone.getAccessNetworksManager() != null) {
-            for (int transport : mDefaultPhone.getAccessNetworksManager()
-                    .getAvailableTransports()) {
+                && mDefaultPhone.getTransportManager() != null) {
+            for (int transport : mDefaultPhone.getTransportManager().getAvailableTransports()) {
                 mDefaultPhone.getServiceStateTracker()
                         .registerForDataRegStateOrRatChanged(transport, this,
                                 EVENT_DEFAULT_PHONE_DATA_STATE_CHANGED, null);
@@ -509,8 +498,7 @@
 
         //Force all referenced classes to unregister their former registered events
         if (mDefaultPhone != null && mDefaultPhone.getServiceStateTracker() != null) {
-            for (int transport : mDefaultPhone.getAccessNetworksManager()
-                    .getAvailableTransports()) {
+            for (int transport : mDefaultPhone.getTransportManager().getAvailableTransports()) {
                 mDefaultPhone.getServiceStateTracker()
                         .unregisterForDataRegStateOrRatChanged(transport, this);
             }
@@ -525,7 +513,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     @Override
     public ServiceState getServiceState() {
-        return new ServiceState(mSS);
+        return mSS;
     }
 
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
@@ -639,11 +627,6 @@
         return mCT.isImsServiceReady();
     }
 
-    @Override
-    public CarrierPrivilegesTracker getCarrierPrivilegesTracker() {
-        return mDefaultPhone.getCarrierPrivilegesTracker();
-    }
-
     /**
      * Hold the currently active call, possibly unholding a currently held call.
      * @throws CallStateException
@@ -1436,10 +1419,6 @@
 
         switch(code) {
             case ImsReasonInfo.CODE_UT_NOT_SUPPORTED:
-                // fall through
-            case ImsReasonInfo.CODE_UT_OPERATION_NOT_ALLOWED:
-                // not allowed is reported by operators when the network doesn't support a specific
-                // type of barring.
                 error = CommandException.Error.REQUEST_NOT_SUPPORTED;
                 break;
             case ImsReasonInfo.CODE_UT_CB_PASSWORD_MISMATCH:
@@ -1980,22 +1959,17 @@
      * Listen to the IMS ECBM state change
      */
     private ImsEcbmStateListener mImsEcbmStateListener =
-            new ImsEcbmStateListener(mContext.getMainExecutor()) {
+            new ImsEcbmStateListener() {
                 @Override
-                public void onECBMEntered(Executor executor) {
+                public void onECBMEntered() {
                     if (DBG) logd("onECBMEntered");
-
-                    TelephonyUtils.runWithCleanCallingIdentity(()->
-                            handleEnterEmergencyCallbackMode(), executor);
+                    handleEnterEmergencyCallbackMode();
                 }
 
-
-
                 @Override
-                public void onECBMExited(Executor executor) {
+                public void onECBMExited() {
                     if (DBG) logd("onECBMExited");
-                    TelephonyUtils.runWithCleanCallingIdentity(()->
-                            handleExitEmergencyCallbackMode(), executor);
+                    handleExitEmergencyCallbackMode();
                 }
             };
 
@@ -2426,9 +2400,9 @@
      * for PS domain over WWAN transport.
      */
     private boolean isCsNotInServiceAndPsWwanReportingWlan(ServiceState ss) {
+        TransportManager tm = mDefaultPhone.getTransportManager();
         // We can not get into this condition if we are in AP-Assisted mode.
-        if (mDefaultPhone.getAccessNetworksManager() == null
-                || !mDefaultPhone.getAccessNetworksManager().isInLegacyMode()) {
+        if (tm == null || !tm.isInLegacyMode()) {
             return false;
         }
         NetworkRegistrationInfo csInfo = ss.getNetworkRegistrationInfo(
@@ -2505,69 +2479,9 @@
         public void handleImsSubscriberAssociatedUriChanged(Uri[] uris) {
             if (DBG) logd("handleImsSubscriberAssociatedUriChanged");
             setCurrentSubscriberUris(uris);
-            setPhoneNumberForSourceIms(uris);
         }
     };
 
-    /** Sets the IMS phone number from IMS associated URIs, if any found. */
-    @VisibleForTesting
-    public void setPhoneNumberForSourceIms(Uri[] uris) {
-        String phoneNumber = extractPhoneNumberFromAssociatedUris(uris);
-        if (phoneNumber == null) {
-            return;
-        }
-        int subId = getSubId();
-        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
-            // Defending b/219080264:
-            // SubscriptionController.setSubscriptionProperty validates input subId
-            // so do not proceed if subId invalid. This may be happening because cached
-            // IMS callbacks are sent back to telephony after SIM state changed.
-            return;
-        }
-        SubscriptionController subController = SubscriptionController.getInstance();
-        String countryIso = getCountryIso(subController, subId);
-        // Format the number as one more defense to reject garbage values:
-        // phoneNumber will become null.
-        phoneNumber = PhoneNumberUtils.formatNumberToE164(phoneNumber, countryIso);
-        if (phoneNumber == null) {
-            return;
-        }
-        subController.setSubscriptionProperty(subId, COLUMN_PHONE_NUMBER_SOURCE_IMS, phoneNumber);
-    }
-
-    private static String getCountryIso(SubscriptionController subController, int subId) {
-        SubscriptionInfo info = subController.getSubscriptionInfo(subId);
-        String countryIso = info == null ? "" : info.getCountryIso();
-        // info.getCountryIso() may return null
-        return countryIso == null ? "" : countryIso;
-    }
-
-    /**
-     * Finds the phone number from associated URIs.
-     *
-     * <p>Associated URIs are public user identities, and phone number could be used:
-     * see 3GPP TS 24.229 5.4.1.2 and 3GPP TS 23.003 13.4. This algotihm look for the
-     * possible "global number" in E.164 format.
-     */
-    private static String extractPhoneNumberFromAssociatedUris(Uri[] uris) {
-        if (uris == null) {
-            return null;
-        }
-        return Arrays.stream(uris)
-                // Phone number is an opaque URI "tel:<phone-number>" or "sip:<phone-number>@<...>"
-                .filter(u -> u != null && u.isOpaque())
-                .filter(u -> "tel".equalsIgnoreCase(u.getScheme())
-                        || "sip".equalsIgnoreCase(u.getScheme()))
-                .map(Uri::getSchemeSpecificPart)
-                // "Global number" should be in E.164 format starting with "+" e.g. "+447539447777"
-                .filter(ssp -> ssp != null && ssp.startsWith("+"))
-                // Remove whatever after "@" for sip URI
-                .map(ssp -> ssp.split("@")[0])
-                // Returns the first winner
-                .findFirst()
-                .orElse(null);
-    }
-
     public IccRecords getIccRecords() {
         return mDefaultPhone.getIccRecords();
     }
@@ -2578,7 +2492,7 @@
             imsDialArgsBuilder = ImsPhone.ImsDialArgs.Builder.from(dialArgs);
 
             Bundle extras = new Bundle(dialArgs.intentExtras);
-            if (causeCode == CallFailCause.EMC_REDIAL_ON_VOWIFI) {
+            if (causeCode == CallFailCause.EMC_REDIAL_ON_VOWIFI && isWifiCallingEnabled()) {
                 extras.putString(ImsCallProfile.EXTRA_CALL_RAT_TYPE,
                         String.valueOf(ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN));
                 logd("trigger VoWifi emergency call");
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
index d19b8d3..ceacb15 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneBase.java
@@ -17,17 +17,16 @@
 package com.android.internal.telephony.imsphone;
 
 import android.content.Context;
+import android.net.LinkProperties;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
 import android.os.RegistrantList;
 import android.sysprop.TelephonyProperties;
-import android.telephony.Annotation.DataActivityType;
 import android.telephony.CallQuality;
 import android.telephony.NetworkScanRequest;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
-import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsReasonInfo;
 import android.util.Pair;
 
@@ -179,8 +178,8 @@
     }
 
     @Override
-    public @DataActivityType int getDataActivityState() {
-        return TelephonyManager.DATA_ACTIVITY_NONE;
+    public DataActivityState getDataActivityState() {
+        return DataActivityState.NONE;
     }
 
     /**
@@ -473,7 +472,7 @@
     }
 
     @Override
-    public boolean isDataAllowed() {
+    public boolean isDataAllowed(int apnType) {
         return false;
     }
 
@@ -509,6 +508,13 @@
         return false;
     }
 
+    //@Override
+    @Override
+    public LinkProperties getLinkProperties(String apnType) {
+        // FIXME: what's this for Volte?
+        return null;
+    }
+
     @Override
     public void getCallBarring(String facility, String password, Message onComplete,
             int serviceClass) {
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
old mode 100644
new mode 100755
index cc8af38..f67082a
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java
@@ -113,7 +113,6 @@
 import com.android.internal.telephony.ServiceStateTracker;
 import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.d2d.RtpTransport;
-import com.android.internal.telephony.data.DataSettingsManager;
 import com.android.internal.telephony.dataconnection.DataEnabledSettings;
 import com.android.internal.telephony.dataconnection.DataEnabledSettings.DataEnabledChangedReason;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
@@ -123,7 +122,6 @@
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession.Event.ImsCommand;
-import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.internal.util.IndentingPrintWriter;
 import com.android.telephony.Rlog;
 
@@ -133,13 +131,8 @@
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
 import java.util.Queue;
 import java.util.Set;
-import java.util.concurrent.CancellationException;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionException;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.Executor;
@@ -194,21 +187,14 @@
     private final Map<String, CallQualityMetrics> mCallQualityMetrics = new ConcurrentHashMap<>();
     private final ConcurrentLinkedQueue<CallQualityMetrics> mCallQualityMetricsHistory =
             new ConcurrentLinkedQueue<>();
-    // True if there is a carrier config loaded for a specific subscription (and not the default
-    // configuration).
-    private boolean mCarrierConfigLoadedForSubscription = false;
-    // Cache the latest carrier config received for a subscription. The configuration will be
-    // applied to the ImsService when startListeningForCalls is called.
-    private Pair<Integer, PersistableBundle> mCarrierConfigForSubId = null;
-    // The subId of the last ImsService attached to this tracker or empty if there has not been
-    // an attached ImsService yet.
-    private Optional<Integer> mCurrentlyConnectedSubId = Optional.empty();
+    private boolean mCarrierConfigLoaded = false;
 
     private final MmTelFeatureListener mMmTelFeatureListener = new MmTelFeatureListener();
     private class MmTelFeatureListener extends MmTelFeature.Listener {
-
-        private void processIncomingCall(IImsCallSession c, Bundle extras) {
-            if (DBG) log("processIncomingCall: incoming call intent");
+        @Override
+        public void onIncomingCall(IImsCallSession c, Bundle extras) {
+            if (DBG) log("onReceive : incoming call intent");
+            mOperationLocalLog.log("onIncomingCall Received");
 
             if (extras == null) extras = new Bundle();
             if (mImsManager == null) return;
@@ -219,8 +205,7 @@
                 // For compatibility purposes with older vendor implmentations.
                 isUssd |= extras.getBoolean(ImsManager.EXTRA_USSD, false);
                 if (isUssd) {
-                    if (DBG) log("processIncomingCall: USSD");
-                    mOperationLocalLog.log("processIncomingCall: USSD");
+                    if (DBG) log("onReceive : USSD");
                     mUssdSession = mImsManager.takeCall(c, mImsUssdListener);
                     if (mUssdSession != null) {
                         mUssdSession.accept(ImsCallProfile.CALL_TYPE_VOICE);
@@ -232,7 +217,7 @@
                 // For compatibility purposes with older vendor implmentations.
                 isUnknown |= extras.getBoolean(ImsManager.EXTRA_IS_UNKNOWN_CALL, false);
                 if (DBG) {
-                    log("processIncomingCall: isUnknown = " + isUnknown
+                    log("onReceive : isUnknown = " + isUnknown
                             + " fg = " + mForegroundCall.getState()
                             + " bg = " + mBackgroundCall.getState());
                 }
@@ -272,7 +257,6 @@
                             if (cause == DisconnectCause.INCOMING_AUTO_REJECTED) {
                                 conn.setDisconnectCause(cause);
                                 if (DBG) log("onIncomingCall : incoming call auto rejected");
-                                mOperationLocalLog.log("processIncomingCall: auto rejected");
                             }
                         } catch (NumberFormatException e) {
                             Rlog.e(LOG_TAG, "Exception in parsing Integer Data: " + e);
@@ -280,9 +264,6 @@
                     }
                 }
 
-                mOperationLocalLog.log("onIncomingCall: isUnknown=" + isUnknown + ", connId="
-                        + System.identityHashCode(conn));
-
                 addConnection(conn);
 
                 setVideoCallProvider(conn, imsCall);
@@ -292,13 +273,6 @@
                 mPhone.getVoiceCallSessionStats().onImsCallReceived(conn);
 
                 if (isUnknown) {
-                    // Check for condition where an unknown connection replaces a pending
-                    // MO call.  This will cause problems later in all likelihood.
-                    if (mPendingMO != null
-                            && Objects.equals(mPendingMO.getAddress(), conn.getAddress())) {
-                        mOperationLocalLog.log("onIncomingCall: unknown call " + conn
-                                + " replaces " + mPendingMO);
-                    }
                     mPhone.notifyUnknownConnection(conn);
                 } else {
                     if ((mForegroundCall.getState() != ImsPhoneCall.State.IDLE)
@@ -312,42 +286,19 @@
 
                 updatePhoneState();
                 mPhone.notifyPreciseCallStateChanged();
-            } catch (ImsException | RemoteException e) {
-                loge("processIncomingCall: exception " + e);
-                mOperationLocalLog.log("onIncomingCall: exception processing: "  + e);
+            } catch (ImsException e) {
+                loge("onReceive : exception " + e);
+            } catch (RemoteException e) {
             }
         }
 
         @Override
-        public void onIncomingCall(IImsCallSession c, Bundle extras) {
-            // we want to ensure we block this binder thread until incoming call setup completes
-            // as to avoid race conditions where the ImsService tries to update the state of the
-            // call before the listeners have been attached.
-            executeAndWait(()-> processIncomingCall(c, extras));
-        }
-
-        @Override
         public void onVoiceMessageCountUpdate(int count) {
-            TelephonyUtils.runWithCleanCallingIdentity(()-> {
-                if (mPhone != null && mPhone.mDefaultPhone != null) {
-                    if (DBG) log("onVoiceMessageCountChanged :: count=" + count);
-                    mPhone.mDefaultPhone.setVoiceMessageCount(count);
-                } else {
-                    loge("onVoiceMessageCountUpdate: null phone");
-                }
-            }, mExecutor);
-        }
-
-        /**
-         * Schedule the given Runnable on mExecutor and block this thread until it finishes.
-         * @param r The Runnable to run.
-         */
-        private void executeAndWait(Runnable r) {
-            try {
-                CompletableFuture.runAsync(
-                        () -> TelephonyUtils.runWithCleanCallingIdentity(r), mExecutor).join();
-            } catch (CancellationException | CompletionException e) {
-                logw("Binder - exception: " + e.getMessage());
+            if (mPhone != null && mPhone.mDefaultPhone != null) {
+                if (DBG) log("onVoiceMessageCountChanged :: count=" + count);
+                mPhone.mDefaultPhone.setVoiceMessageCount(count);
+            } else {
+                loge("onVoiceMessageCountUpdate: null phone");
             }
         }
     }
@@ -394,29 +345,16 @@
         }
     }
 
-    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+    private BroadcastReceiver mReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)) {
-                int subId = intent.getIntExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX,
+                int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
                         SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-                int phoneId = intent.getIntExtra(CarrierConfigManager.EXTRA_SLOT_INDEX,
-                        SubscriptionManager.INVALID_PHONE_INDEX);
-                if (mPhone.getPhoneId() != phoneId) {
-                    log("onReceive: Skipping indication for other phoneId: " + phoneId);
-                    return;
-                }
-                PersistableBundle carrierConfig = getCarrierConfigBundle(subId);
-                mCarrierConfigForSubId = new Pair<>(subId, carrierConfig);
-                if (!mCurrentlyConnectedSubId.isEmpty()
-                        && subId == mCurrentlyConnectedSubId.get()) {
-                    log("onReceive: Applying carrier config for subId: " + subId);
-                    updateCarrierConfiguration(subId, carrierConfig);
-                } else {
-                    // cache the latest config update until ImsService connects for this subId.
-                    // Once it has connected, startListeningForCalls will apply the config.
-                    log("onReceive: caching carrier config until ImsService connects for subId: "
-                            + subId);
+                if (subId == mPhone.getSubId()) {
+                    updateCarrierConfiguration(subId);
+                    log("onReceive : Updating mAllowEmergencyVideoCalls = " +
+                            mAllowEmergencyVideoCalls);
                 }
             } else if (TelecomManager.ACTION_DEFAULT_DIALER_CHANGED.equals(intent.getAction())) {
                 mDefaultDialerUid.set(getPackageUid(context, intent.getStringExtra(
@@ -506,8 +444,6 @@
         PENDING_RESUME_FOREGROUND_AFTER_FAILURE,
         // Pending holding a call to dial another outgoing call
         HOLDING_TO_DIAL_OUTGOING,
-        // Pending resuming the foreground call after it has completed an ongoing hold operation.
-        PENDING_RESUME_FOREGROUND_AFTER_HOLD
     }
 
     //***** Instance Variables
@@ -612,7 +548,6 @@
 
     private String mLastDialString = null;
     private ImsDialArgs mLastDialArgs = null;
-    private Executor mExecutor = Runnable::run;
 
     /**
      * Listeners to changes in the phone state.  Intended for use by other interested IMS components
@@ -961,9 +896,6 @@
         }
     };
 
-    // TODO: make @NonNull after removing DataEnabledSettings
-    private DataSettingsManager.DataSettingsManagerCallback mSettingsCallback;
-
     /**
      * Allows the FeatureConnector used to be swapped for easier testing.
      */
@@ -980,9 +912,9 @@
     private final FeatureConnector<ImsManager> mImsManagerConnector;
 
     // Used exclusively for IMS Registration related events for logging.
-    private final LocalLog mRegLocalLog = new LocalLog(64);
+    private final LocalLog mRegLocalLog = new LocalLog(100);
     // Used for important operational related events for logging.
-    private final LocalLog mOperationLocalLog = new LocalLog(64);
+    private final LocalLog mOperationLocalLog = new LocalLog(100);
 
     //***** Events
 
@@ -996,9 +928,6 @@
     public ImsPhoneCallTracker(ImsPhone phone, ConnectorFactory factory, Executor executor) {
         this.mPhone = phone;
         mConnectorFactory = factory;
-        if (executor != null) {
-            mExecutor = executor;
-        }
 
         mMetrics = TelephonyMetrics.getInstance();
 
@@ -1006,41 +935,10 @@
         intentfilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         intentfilter.addAction(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED);
         mPhone.getContext().registerReceiver(mReceiver, intentfilter);
-        updateCarrierConfiguration(mPhone.getSubId(), getCarrierConfigBundle(mPhone.getSubId()));
+        updateCarrierConfiguration(mPhone.getSubId());
 
-        if (mPhone.getDefaultPhone().isUsingNewDataStack()) {
-            mSettingsCallback = new DataSettingsManager.DataSettingsManagerCallback(this::post) {
-                    @Override
-                    public void onDataEnabledChanged(boolean enabled,
-                            @TelephonyManager.DataEnabledChangedReason int reason,
-                            @NonNull String callingPackage) {
-                        int internalReason;
-                        switch (reason) {
-                            case TelephonyManager.DATA_ENABLED_REASON_USER:
-                                internalReason = DataEnabledSettings.REASON_USER_DATA_ENABLED;
-                                break;
-                            case TelephonyManager.DATA_ENABLED_REASON_POLICY:
-                                internalReason = DataEnabledSettings.REASON_POLICY_DATA_ENABLED;
-                                break;
-                            case TelephonyManager.DATA_ENABLED_REASON_CARRIER:
-                                internalReason = DataEnabledSettings.REASON_DATA_ENABLED_BY_CARRIER;
-                                break;
-                            case TelephonyManager.DATA_ENABLED_REASON_THERMAL:
-                                internalReason = DataEnabledSettings.REASON_THERMAL_DATA_ENABLED;
-                                break;
-                            case TelephonyManager.DATA_ENABLED_REASON_OVERRIDE:
-                                internalReason = DataEnabledSettings.REASON_OVERRIDE_RULE_CHANGED;
-                                break;
-                            default:
-                                internalReason = DataEnabledSettings.REASON_INTERNAL_DATA_ENABLED;
-                        }
-                        ImsPhoneCallTracker.this.onDataEnabledChanged(enabled, internalReason);
-                    }};
-            mPhone.getDefaultPhone().getDataSettingsManager().registerCallback(mSettingsCallback);
-        } else {
-            mPhone.getDefaultPhone().getDataEnabledSettings().registerForDataEnabledChanged(
-                    this, EVENT_DATA_ENABLED_CHANGED, null);
-        }
+        mPhone.getDefaultPhone().getDataEnabledSettings().registerForDataEnabledChanged(
+                this, EVENT_DATA_ENABLED_CHANGED, null);
 
         final TelecomManager telecomManager =
                 (TelecomManager) mPhone.getContext().getSystemService(Context.TELECOM_SERVICE);
@@ -1057,10 +955,9 @@
 
         mImsManagerConnector = mConnectorFactory.create(mPhone.getContext(), mPhone.getPhoneId(),
                 LOG_TAG, new FeatureConnector.Listener<ImsManager>() {
-                    public void connectionReady(ImsManager manager, int subId) throws ImsException {
+                    public void connectionReady(ImsManager manager) throws ImsException {
                         mImsManager = manager;
-                        log("connectionReady for subId = " + subId);
-                        startListeningForCalls(subId);
+                        startListeningForCalls();
                     }
 
                     @Override
@@ -1103,7 +1000,7 @@
     }
 
     @VisibleForTesting
-    public void startListeningForCalls(int subId) throws ImsException {
+    public void startListeningForCalls() throws ImsException {
         log("startListeningForCalls");
         mOperationLocalLog.log("startListeningForCalls - Connecting to ImsService");
         ImsExternalCallTracker externalCallTracker = mPhone.getExternalCallTracker();
@@ -1138,18 +1035,10 @@
                     null);
         }
 
-        if (mCarrierConfigForSubId != null && mCarrierConfigForSubId.first == subId) {
-            // The carrier configuration was received by CarrierConfigManager before the indication
-            // that the ImsService was connected or ImsService has restarted and we need to re-apply
-            // the configuration.
-            updateCarrierConfiguration(subId, mCarrierConfigForSubId.second);
-        } else {
-            log("startListeningForCalls - waiting for the first carrier config indication for this "
-                    + "subscription");
-        }
+        maybeConfigureRtpHeaderExtensions();
+        updateImsServiceConfig();
         // For compatibility with apps that still use deprecated intent
         sendImsServiceStateIntent(ImsManager.ACTION_IMS_SERVICE_UP);
-        mCurrentlyConnectedSubId = Optional.of(subId);
     }
 
     /**
@@ -1209,7 +1098,7 @@
             mUtInterface.unregisterForSuppServiceIndication(this);
             mUtInterface = null;
         }
-        mCurrentlyConnectedSubId = Optional.empty();
+
         resetImsCapabilities();
         hangupAllOrphanedConnections(DisconnectCause.LOST_SIGNAL);
         // For compatibility with apps that still use deprecated intent
@@ -1226,19 +1115,7 @@
     @VisibleForTesting
     public void hangupAllOrphanedConnections(int disconnectCause) {
         Log.w(LOG_TAG, "hangupAllOngoingConnections called for cause " + disconnectCause);
-        // Send a call terminate request to all available connections.
-        // In the ImsPhoneCallTrackerTest, when the hangup() of the connection call,
-        // onCallTerminated() is called immediately and the connection is removed.
-        // As a result, an IndexOutOfBoundsException is thrown.
-        // This is why it counts backwards.
-        int size = getConnections().size();
-        for (int index = size - 1; index > -1; index--) {
-            try {
-                getConnections().get(index).hangup();
-            } catch (CallStateException e) {
-                loge("Failed to disconnet call...");
-            }
-        }
+
         // Move connections to disconnected and notify the reason why.
         for (ImsPhoneConnection connection : mConnections) {
             connection.update(connection.getImsCall(), ImsPhoneCall.State.DISCONNECTED);
@@ -1283,11 +1160,7 @@
 
         clearDisconnected();
         mPhone.getContext().unregisterReceiver(mReceiver);
-        if (mPhone.getDefaultPhone().isUsingNewDataStack()) {
-            mPhone.getDefaultPhone().getDataSettingsManager().unregisterCallback(mSettingsCallback);
-        } else {
-            mPhone.getDefaultPhone().getDataEnabledSettings().unregisterForDataEnabledChanged(this);
-        }
+        mPhone.getDefaultPhone().getDataEnabledSettings().unregisterForDataEnabledChanged(this);
         mImsManagerConnector.disconnect();
 
         final NetworkStatsManager statsManager =
@@ -1455,6 +1328,7 @@
         int videoState = dialArgs.videoState;
 
         if (DBG) log("dial clirMode=" + clirMode);
+        mOperationLocalLog.log("dial requested.");
         String origNumber = dialString;
         if (isEmergencyNumber) {
             clirMode = CommandsInterface.CLIR_SUPPRESSION;
@@ -1486,7 +1360,6 @@
             mLastDialArgs = dialArgs;
             mPendingMO = new ImsPhoneConnection(mPhone, dialString, this, mForegroundCall,
                     isEmergencyNumber, isWpsCall);
-            mOperationLocalLog.log("dial requested. connId=" + System.identityHashCode(mPendingMO));
             if (isEmergencyNumber && dialArgs != null && dialArgs.intentExtras != null) {
                 Rlog.i(LOG_TAG, "dial ims emergency dialer: " + dialArgs.intentExtras.getBoolean(
                         TelecomManager.EXTRA_IS_USER_INTENT_EMERGENCY_CALL));
@@ -1578,27 +1451,14 @@
      * @param subId The sub id to use to update configuration, may be invalid if a SIM has been
      *              removed.
      */
-    private void updateCarrierConfiguration(int subId, PersistableBundle carrierConfig) {
-        // start by assuming the carrier config is not loaded for the provided subscription.
-        mCarrierConfigLoadedForSubscription = false;
-
-        if (carrierConfig == null) {
-            loge("updateCarrierConfiguration: carrier config is null, skipping.");
-            return;
-        }
-
-        // Ensure the local cache is up to date first (including default config for no SIM case) in
-        // ImsPhoneCallTracker to ensure we do not carry over settings from the previously inserted
-        // SIM for things like emergency calling.
-        updateCarrierConfigCache(carrierConfig);
-        log("updateCarrierConfiguration: Updating mAllowEmergencyVideoCalls = "
-                + mAllowEmergencyVideoCalls);
-        // Check for changes due to carrier config.
-        maybeConfigureRtpHeaderExtensions();
-
-        if (!SubscriptionController.getInstance().isActiveSubId(subId)) {
-            loge("updateCarrierConfiguration: skipping notification to ImsService, non"
-                    + "active subId = " + subId);
+    private void updateCarrierConfiguration(int subId) {
+        CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
+                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        if (carrierConfigManager == null
+                || !SubscriptionController.getInstance().isActiveSubId(subId)) {
+            loge("cacheCarrierConfiguration: No carrier config service found" + " "
+                    + "or not active subId = " + subId);
+            mCarrierConfigLoaded = false;
             return;
         }
 
@@ -1609,23 +1469,25 @@
             // when the device is still locked. A CARRIER_CONFIG_CHANGED indication will be sent
             // once the device moves to ready.
             if (state != null && (!state.iccCardExist() || state.isPinLocked())) {
-                loge("updateCarrierConfiguration: card state is not ready, skipping "
-                        + "notification to ImsService. State= " + state);
+                loge("cacheCarrierConfiguration: card state is not ready, skipping. State= "
+                        + state);
+                mCarrierConfigLoaded = false;
                 return;
             }
         }
 
-        if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
-            logi("updateCarrierConfiguration: Empty or default carrier config, skipping "
-                    + "notification to ImsService.");
+        PersistableBundle carrierConfig = carrierConfigManager.getConfigForSubId(subId);
+        if (carrierConfig == null) {
+            loge("cacheCarrierConfiguration: Empty carrier config.");
+            mCarrierConfigLoaded = false;
             return;
         }
+        mCarrierConfigLoaded = true;
 
-        // Only update the ImsService configurations for the case where a new subscription has been
-        // loaded and is active.
-        logi("updateCarrierConfiguration: Updating ImsService configs.");
-        mCarrierConfigLoadedForSubscription = true;
+        updateCarrierConfigCache(carrierConfig);
         updateImsServiceConfig();
+        // Check for changes due to carrier config.
+        maybeConfigureRtpHeaderExtensions();
     }
 
     /**
@@ -1680,9 +1542,6 @@
             mUssdMethod = carrierConfig.getInt(CarrierConfigManager.KEY_CARRIER_USSD_METHOD_INT);
         }
 
-        if (!mImsReasonCodeMap.isEmpty()) {
-            mImsReasonCodeMap.clear();
-        }
         String[] mappings = carrierConfig
                 .getStringArray(CarrierConfigManager.KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY);
         if (mappings != null && mappings.length > 0) {
@@ -1703,22 +1562,21 @@
                     if (message == null) {
                         message = "";
                     }
-                    else if (message.equals("*")) {
-                        message = null;
-                    }
                     int toCode = Integer.parseInt(values[2]);
 
                     addReasonCodeRemapping(fromCode, message, toCode);
-                    log("Loaded ImsReasonInfo mapping :" +
-                            " fromCode = " + (fromCode == null ? "any" : fromCode) +
-                            " ; message = " + (message == null ? "any" : message) +
-                            " ; toCode = " + toCode);
+                    log("Loaded ImsReasonInfo mapping : fromCode = " +
+                            fromCode == null ? "any" : fromCode + " ; message = " +
+                            message + " ; toCode = " + toCode);
                 } catch (NumberFormatException nfe) {
                     loge("Invalid ImsReasonInfo mapping found: " + mapping);
                 }
             }
         } else {
             log("No carrier ImsReasonInfo mappings defined.");
+            if (!mImsReasonCodeMap.isEmpty()) {
+                mImsReasonCodeMap.clear();
+            }
         }
     }
 
@@ -1999,7 +1857,7 @@
                 callToHold.hold();
                 mMetrics.writeOnImsCommand(mPhone.getPhoneId(), callToHold.getSession(),
                         ImsCommand.IMS_CMD_HOLD);
-            } catch (ImsException | NullPointerException e) {
+            } catch (ImsException e) {
                 mForegroundCall.switchWith(mBackgroundCall);
                 mHoldSwitchingState = oldHoldState;
                 logHoldSwapState("holdActiveCall - fail");
@@ -2070,15 +1928,9 @@
         //they were switched before holding
         ImsCall imsCall = mForegroundCall.getImsCall();
         if (imsCall != null) {
-            if (!imsCall.isPendingHold()) {
-                imsCall.resume();
-                mMetrics.writeOnImsCommand(mPhone.getPhoneId(), imsCall.getSession(),
-                        ImsCommand.IMS_CMD_RESUME);
-            } else {
-                mHoldSwitchingState =
-                        HoldSwapState.PENDING_RESUME_FOREGROUND_AFTER_HOLD;
-                logHoldSwapState("resumeForegroundCall - unhold pending; resume request again");
-            }
+            imsCall.resume();
+            mMetrics.writeOnImsCommand(mPhone.getPhoneId(), imsCall.getSession(),
+                    ImsCommand.IMS_CMD_RESUME);
         }
     }
 
@@ -2297,7 +2149,6 @@
         return !isImsAudioCallActiveOrHolding || !VideoProfile.isVideo(videoState);
     }
 
-
     /**
      * Determines if there are issues which would preclude dialing an outgoing call.  Throws a
      * {@link CallStateException} if there is an issue.
@@ -2365,14 +2216,9 @@
 
         if (DBG) {
             log("updatePhoneState pendingMo = " + (mPendingMO == null ? "null"
-                    : mPendingMO.getState() + "(" + mPendingMO.getTelecomCallId() + "/objId:"
-                            + System.identityHashCode(mPendingMO) + ")")
-                    + ", rng= " + mRingingCall.getState() + "("
-                    + mRingingCall.getConnectionSummary()
-                    + "), fg= " + mForegroundCall.getState() + "("
-                    + mForegroundCall.getConnectionSummary()
-                    + "), bg= " + mBackgroundCall.getState()
-                    + "(" + mBackgroundCall.getConnectionSummary() + ")");
+                    : mPendingMO.getState()) + ", fg= " + mForegroundCall.getState() + "("
+                    + mForegroundCall.getConnectionsCount() + "), bg= " + mBackgroundCall
+                    .getState() + "(" + mBackgroundCall.getConnectionsCount() + ")");
             log("updatePhoneState oldState=" + oldState + ", newState=" + mState);
         }
 
@@ -2535,33 +2381,34 @@
         }
 
         ImsCall imsCall = call.getImsCall();
-        ImsPhoneConnection conn = findConnection(imsCall);
         boolean rejectCall = false;
 
-        String logResult = "(undefined)";
         if (call == mRingingCall) {
-            logResult = "(ringing) hangup incoming";
+            if (Phone.DEBUG_PHONE) log("(ringing) hangup incoming");
             rejectCall = true;
         } else if (call == mForegroundCall) {
             if (call.isDialingOrAlerting()) {
-                logResult = "(foregnd) hangup dialing or alerting...";
+                if (Phone.DEBUG_PHONE) {
+                    log("(foregnd) hangup dialing or alerting...");
+                }
             } else {
-                logResult = "(foregnd) hangup foreground";
+                if (Phone.DEBUG_PHONE) {
+                    log("(foregnd) hangup foreground");
+                }
                 //held call will be resumed by onCallTerminated
             }
         } else if (call == mBackgroundCall) {
-            logResult = "(backgnd) hangup waiting or background";
+            if (Phone.DEBUG_PHONE) {
+                log("(backgnd) hangup waiting or background");
+            }
         } else if (call == mHandoverCall) {
-            logResult = "(handover) hangup handover (SRVCC) call";
+            if (Phone.DEBUG_PHONE) {
+                log("(handover) hangup handover (SRVCC) call");
+            }
         } else {
-            mOperationLocalLog.log("hangup: ImsPhoneCall " + System.identityHashCode(conn)
-                    + " does not belong to ImsPhoneCallTracker " + this);
             throw new CallStateException ("ImsPhoneCall " + call +
                     "does not belong to ImsPhoneCallTracker " + this);
         }
-        if (Phone.DEBUG_PHONE) log(logResult);
-        mOperationLocalLog.log("hangup: " + logResult + ", connId="
-                + System.identityHashCode(conn));
 
         call.onHangupLocal();
 
@@ -2590,7 +2437,6 @@
                 removeMessages(EVENT_DIAL_PENDINGMO);
             }
         } catch (ImsException e) {
-            mOperationLocalLog.log("hangup: ImsException=" + e);
             throw new CallStateException(e.getMessage());
         }
 
@@ -2663,32 +2509,9 @@
         return null;
     }
 
-    /**
-     * Given a connection, detach it from any {@link ImsPhoneCall} it is associated with, remove it
-     * from the connections lists, and ensure if it was the pending MO connection it gets removed
-     * from there as well.
-     * @param conn The connection to cleanup and remove.
-     */
-    public synchronized void cleanupAndRemoveConnection(ImsPhoneConnection conn) {
-        mOperationLocalLog.log("cleanupAndRemoveConnection: " + conn);
-        // If the connection is attached to a call, detach it.
-        if (conn.getCall() != null) {
-            conn.getCall().detach(conn);
-        }
-        // Remove it from the connection list.
-        removeConnection(conn);
-
-        // Finally, if it was the pending MO, then ensure that connection gets cleaned up as well.
-        if (conn == mPendingMO) {
-            mPendingMO.finalize();
-            mPendingMO = null;
-        }
-    }
-
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
-    public synchronized void removeConnection(ImsPhoneConnection conn) {
+    private synchronized void removeConnection(ImsPhoneConnection conn) {
         mConnections.remove(conn);
-
         // If not emergency call is remaining, notify emergency call registrants
         if (mIsInEmergencyCall) {
             boolean isEmergencyCallInList = false;
@@ -2764,10 +2587,6 @@
             return;
         }
 
-        // Do not log operations that do not change the state
-        mOperationLocalLog.log("processCallStateChange: state=" + state + " cause=" + cause
-                + " connId=" + System.identityHashCode(conn));
-
         changed = conn.update(imsCall, state);
         if (state == ImsPhoneCall.State.DISCONNECTED) {
             changed = conn.onDisconnect(cause) || changed;
@@ -2846,7 +2665,6 @@
                 + reason);
         Pair<Integer, String> toCheck = new Pair<>(code, reason);
         Pair<Integer, String> wildcardToCheck = new Pair<>(null, reason);
-        Pair<Integer, String> wildcardMessageToCheck = new Pair<>(code, null);
         if (mImsReasonCodeMap.containsKey(toCheck)) {
             int toCode = mImsReasonCodeMap.get(toCheck);
 
@@ -2864,19 +2682,6 @@
                     " ; message = " + reason + " ; toCode = " + toCode);
             return toCode;
         }
-        else if (mImsReasonCodeMap.containsKey(wildcardMessageToCheck)) {
-            // Handle the case where a wildcard is specified for the reason.
-            // For example, we can set these two strings in
-            // CarrierConfigManager.KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY:
-            //   - "1014|call completed elsewhere|1014"
-            //   - "1014|*|510"
-            // to remap CODE_ANSWERED_ELSEWHERE to CODE_USER_TERMINATED_BY_REMOTE
-            // when reason is NOT "call completed elsewhere".
-            int toCode = mImsReasonCodeMap.get(wildcardMessageToCheck);
-            log("maybeRemapReasonCode : fromCode = " + reasonInfo.getCode() +
-                    " ; message(wildcard) = " + reason + " ; toCode = " + toCode);
-            return toCode;
-        }
         return code;
     }
 
@@ -3292,16 +3097,12 @@
 
                 } else if (conn.isIncoming() && conn.getConnectTime() == 0
                         && cause != DisconnectCause.ANSWERED_ELSEWHERE) {
-
-                    if (conn.getDisconnectCause() == DisconnectCause.LOCAL) {
-                        // If the user initiated a disconnect of this connection, then we will treat
-                        // this is a rejected call.
-                        // Note; the record the fact that this is a local disconnect in
-                        // ImsPhoneConnection#onHangupLocal
-                        cause = DisconnectCause.INCOMING_REJECTED;
-                    } else {
-                        // Otherwise in all other cases consider it missed.
+                    // Missed
+                    if (cause == DisconnectCause.NORMAL
+                            || cause == DisconnectCause.INCOMING_AUTO_REJECTED) {
                         cause = DisconnectCause.INCOMING_MISSED;
+                    } else {
+                        cause = DisconnectCause.INCOMING_REJECTED;
                     }
                     if (DBG) log("Incoming connection of 0 connect time detected - translated " +
                             "cause = " + cause);
@@ -3327,9 +3128,7 @@
                     getNetworkCountryIso(), emergencyNumberTracker != null
                     ? emergencyNumberTracker.getEmergencyNumberDbVersion()
                     : TelephonyManager.INVALID_EMERGENCY_NUMBER_DB_VERSION);
-            mPhone.getVoiceCallSessionStats().onImsCallTerminated(conn, new ImsReasonInfo(
-                    maybeRemapReasonCode(reasonInfo),
-                    reasonInfo.mExtraCode, reasonInfo.mExtraMessage));
+            mPhone.getVoiceCallSessionStats().onImsCallTerminated(conn, reasonInfo);
             // Remove info for the callId from the current calls and add it to the history
             CallQualityMetrics lastCallMetrics = mCallQualityMetrics.remove(callId);
             if (lastCallMetrics != null) {
@@ -3457,12 +3256,7 @@
                 // processCallStateChange above may have caused the mBackgroundCall and
                 // mForegroundCall references below to change meaning.  Watch out for this if you
                 // are reading through this code.
-                if (mHoldSwitchingState
-                        == HoldSwapState.PENDING_RESUME_FOREGROUND_AFTER_HOLD) {
-                    sendEmptyMessage(EVENT_RESUME_NOW_FOREGROUND_CALL);
-                    mHoldSwitchingState = HoldSwapState.INACTIVE;
-                    mCallExpectedToResume = null;
-                } else if (oldState == ImsPhoneCall.State.ACTIVE) {
+                if (oldState == ImsPhoneCall.State.ACTIVE) {
                     // Note: This case comes up when we have just held a call in response to a
                     // switchWaitingOrHoldingAndActive.  We now need to resume the background call.
                     if (mForegroundCall.getState() == ImsPhoneCall.State.HOLDING
@@ -3507,10 +3301,7 @@
 
             synchronized (mSyncHold) {
                 ImsPhoneCall.State bgState = mBackgroundCall.getState();
-                if (mHoldSwitchingState
-                        == HoldSwapState.PENDING_RESUME_FOREGROUND_AFTER_HOLD) {
-                    mHoldSwitchingState = HoldSwapState.INACTIVE;
-                } else if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED) {
+                if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED) {
                     // disconnected while processing hold
                     if (mPendingMO != null) {
                         dialPendingMO();
@@ -3815,12 +3606,8 @@
             // Check with the DCTracker to see if data is enabled; there may be a case when
             // ImsPhoneCallTracker isn't being informed of the right data enabled state via its
             // registration, so we'll refresh now.
-            boolean isDataEnabled;
-            if (mPhone.getDefaultPhone().isUsingNewDataStack()) {
-                isDataEnabled = mPhone.getDefaultPhone().getDataSettingsManager().isDataEnabled();
-            } else {
-                isDataEnabled = mPhone.getDefaultPhone().getDataEnabledSettings().isDataEnabled();
-            }
+            boolean isDataEnabled = mPhone.getDefaultPhone().getDataEnabledSettings()
+                    .isDataEnabled();
 
             if (DBG) {
                 log("onCallHandover ::  srcAccessTech=" + srcAccessTech + ", targetAccessTech="
@@ -4531,15 +4318,16 @@
         // Since the modem only reports the total vt data usage rather than rx/tx separately,
         // the only thing we can do here is splitting the usage into half rx and half tx.
         // Uid -1 indicates this is for the overall device data usage.
-        mVtDataUsageSnapshot = vtDataUsageSnapshot.addEntry(new NetworkStats.Entry(
+        vtDataUsageSnapshot.combineValues(new NetworkStats.Entry(
                 getVtInterface(), -1, NetworkStats.SET_FOREGROUND,
                 NetworkStats.TAG_NONE, NetworkStats.METERED_YES, isRoaming,
                 NetworkStats.DEFAULT_NETWORK_YES, delta / 2, 0, delta / 2, 0, 0));
+        mVtDataUsageSnapshot = vtDataUsageSnapshot;
 
         // Create the snapshot of video call data usage per dialer. combineValues will create
         // a separate entry if uid is different from the previous snapshot.
         NetworkStats vtDataUsageUidSnapshot = new NetworkStats(currentTime, 1);
-        vtDataUsageUidSnapshot = vtDataUsageUidSnapshot.add(mVtDataUsageUidSnapshot);
+        vtDataUsageUidSnapshot.combineAllValues(mVtDataUsageUidSnapshot);
 
         // The dialer uid might not be initialized correctly during boot up due to telecom service
         // not ready or its default dialer cache not ready. So we double check again here to see if
@@ -4553,10 +4341,11 @@
 
         // Since the modem only reports the total vt data usage rather than rx/tx separately,
         // the only thing we can do here is splitting the usage into half rx and half tx.
-        mVtDataUsageUidSnapshot = vtDataUsageUidSnapshot.addEntry(new NetworkStats.Entry(
+        vtDataUsageUidSnapshot.combineValues(new NetworkStats.Entry(
                 getVtInterface(), mDefaultDialerUid.get(),
                 NetworkStats.SET_FOREGROUND, NetworkStats.TAG_NONE, NetworkStats.METERED_YES,
                 isRoaming, NetworkStats.DEFAULT_NETWORK_YES, delta / 2, 0, delta / 2, 0, 0));
+        mVtDataUsageUidSnapshot = vtDataUsageUidSnapshot;
     }
 
     @VisibleForTesting(visibility = PRIVATE)
@@ -4607,9 +4396,6 @@
             case HOLDING_TO_DIAL_OUTGOING:
                 holdSwapState = "HOLDING_TO_DIAL_OUTGOING";
                 break;
-            case PENDING_RESUME_FOREGROUND_AFTER_HOLD:
-                holdSwapState = "PENDING_RESUME_FOREGROUND_AFTER_HOLD";
-                break;
         }
         logi("holdSwapState set to " + holdSwapState + " at " + loc);
     }
@@ -4809,27 +4595,6 @@
     }
 
     /**
-     *
-     * @param subId The subId to get the carrier config for.
-     * @return The PersistableBundle containing the carrier config  from
-     * {@link CarrierConfigManager} for the subId specified.
-     */
-    private PersistableBundle getCarrierConfigBundle(int subId) {
-        CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
-                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
-        if (carrierConfigManager == null) {
-            loge("getCarrierConfigBundle: No carrier config service found");
-            return null;
-        }
-        PersistableBundle carrierConfig = carrierConfigManager.getConfigForSubId(subId);
-        if (carrierConfig == null) {
-            loge("getCarrierConfigBundle: carrier config is null, skipping.");
-            return null;
-        }
-        return carrierConfig;
-    }
-
-    /**
      * Given a call subject, removes any characters considered by the current carrier to be
      * invalid, as well as escaping (using \) any characters which the carrier requires to be
      * escaped.
@@ -4842,7 +4607,15 @@
             return callSubject;
         }
 
-        PersistableBundle carrierConfig = getCarrierConfigBundle(mPhone.getSubId());
+        // Get the carrier config for the current sub.
+        CarrierConfigManager configMgr = (CarrierConfigManager)
+                mPhone.getContext().getSystemService(Context.CARRIER_CONFIG_SERVICE);
+        // Bail if we can't find the carrier config service.
+        if (configMgr == null) {
+            return callSubject;
+        }
+
+        PersistableBundle carrierConfig = configMgr.getConfigForSubId(mPhone.getSubId());
         // Bail if no carrier config found.
         if (carrierConfig == null) {
             return callSubject;
@@ -5002,7 +4775,7 @@
      * @param reason Reason for data enabled/disabled. See {@link DataEnabledChangedReason}.
      */
     private void onDataEnabledChanged(boolean enabled, @DataEnabledChangedReason int reason) {
-        // TODO: TelephonyManager.DataEnabledChangedReason instead once DataEnabledSettings is gone
+
         log("onDataEnabledChanged: enabled=" + enabled + ", reason=" + reason);
 
         mIsDataEnabled = enabled;
@@ -5040,8 +4813,7 @@
         // We do not want to update the ImsConfig for REASON_REGISTERED, since it can happen before
         // the carrier config has loaded and will deregister IMS.
         if (!mShouldUpdateImsConfigOnDisconnect
-                && reason != DataEnabledSettings.REASON_REGISTERED
-                && mCarrierConfigLoadedForSubscription) {
+                && reason != DataEnabledSettings.REASON_REGISTERED && mCarrierConfigLoaded) {
             // This will call into updateVideoCallFeatureValue and eventually all clients will be
             // asynchronously notified that the availability of VT over LTE has changed.
             updateImsServiceConfig();
@@ -5053,7 +4825,7 @@
      * trigger the update of the configuration sent to the ImsService.
      */
     private void updateImsServiceConfig() {
-        if (mImsManager != null && mCarrierConfigLoadedForSubscription) {
+        if (mImsManager != null && mCarrierConfigLoaded) {
             mImsManager.updateImsServiceConfig();
         }
     }
@@ -5408,11 +5180,6 @@
         return mConnections;
     }
 
-    @VisibleForTesting
-    public ImsPhoneConnection getPendingMO() {
-        return mPendingMO;
-    }
-
     /**
      * Set up static configuration from package/services/Telephony's config.xml.
      * @param config the config.
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
index 14952b7..1371c92 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneCommandInterface.java
@@ -38,8 +38,6 @@
 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
 
-import java.util.List;
-
 /**
  * Volte doesn't need CommandsInterface. The class does nothing but made to work
  * with Phone's constructor.
@@ -661,7 +659,7 @@
 
     @Override
     public void setSignalStrengthReportingCriteria(
-            List<SignalThresholdInfo> signalThresholdInfo, Message result) {
+            SignalThresholdInfo signalThresholdInfo, int ran, Message result) {
     }
 
     @Override
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
index c60a4db..8c4e2e0 100755
--- a/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsPhoneConnection.java
@@ -59,8 +59,6 @@
 import com.android.internal.telephony.metrics.TelephonyMetrics;
 import com.android.telephony.Rlog;
 
-import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Objects;
 import java.util.Set;
@@ -160,7 +158,7 @@
     private static final int EVENT_DTMF_DELAY_DONE = 5;
 
     //***** Constants
-    @VisibleForTesting static final int PAUSE_DELAY_MILLIS = 3 * 1000;
+    private static final int PAUSE_DELAY_MILLIS = 3 * 1000;
     private static final int WAKE_LOCK_TIMEOUT_MILLIS = 60*1000;
 
     //***** Inner Classes
@@ -356,8 +354,6 @@
         Rlog.w(LOG_TAG, "applyRemoteCallCapabilities - remoteProfile = "+remoteProfile);
         capabilities = removeCapability(capabilities,
                 Connection.Capability.SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
-        capabilities = removeCapability(capabilities,
-                Connection.Capability.SUPPORTS_RTT_REMOTE);
 
         switch (remoteProfile.mCallType) {
             case ImsCallProfile.CALL_TYPE_VT:
@@ -367,10 +363,6 @@
                         Connection.Capability.SUPPORTS_VT_REMOTE_BIDIRECTIONAL);
                 break;
         }
-
-        if (remoteProfile.getMediaProfile().getRttMode() == ImsStreamMediaProfile.RTT_MODE_FULL) {
-            capabilities = addCapability(capabilities, Connection.Capability.SUPPORTS_RTT_REMOTE);
-        }
         return capabilities;
     }
 
@@ -542,7 +534,8 @@
     /**
      * Called when this Connection is being hung up locally (eg, user pressed "end")
      */
-    public void onHangupLocal() {
+    void
+    onHangupLocal() {
         mCause = DisconnectCause.LOCAL;
     }
 
@@ -1319,11 +1312,7 @@
             return;
         }
         if (extras.containsKey(ImsCallProfile.EXTRA_FORWARDED_NUMBER)) {
-            String[] forwardedNumberArray =
-                    extras.getStringArray(ImsCallProfile.EXTRA_FORWARDED_NUMBER);
-            if (forwardedNumberArray != null) {
-                mForwardedNumber = new ArrayList<String>(Arrays.asList(forwardedNumberArray));
-            }
+            mForwardedNumber = extras.getStringArrayList(ImsCallProfile.EXTRA_FORWARDED_NUMBER);
         }
     }
 
diff --git a/src/java/com/android/internal/telephony/imsphone/ImsRttTextHandler.java b/src/java/com/android/internal/telephony/imsphone/ImsRttTextHandler.java
index 67a8c04..3955ea7 100644
--- a/src/java/com/android/internal/telephony/imsphone/ImsRttTextHandler.java
+++ b/src/java/com/android/internal/telephony/imsphone/ImsRttTextHandler.java
@@ -128,16 +128,7 @@
                 mReaderThread.start();
                 break;
             case SEND_TO_INCALL:
-                if (msg.obj == null) {
-                    Rlog.e(LOG_TAG, "RTT msg.obj is null. Ignoring.");
-                    return;
-                }
                 String messageToIncall = (String) msg.obj;
-                if (mRttTextStream == null) {
-                    Rlog.e(LOG_TAG, "RTT text stream is null. Writing to in-call buffer.");
-                    mBufferedTextToIncall.append(messageToIncall);
-                    return;
-                }
                 try {
                     mRttTextStream.write(messageToIncall);
                 } catch (IOException e) {
@@ -225,21 +216,6 @@
         mReadNotifier = latch;
     }
 
-    @VisibleForTesting
-    public StringBuffer getBufferedTextToIncall() {
-        return mBufferedTextToIncall;
-    }
-
-    @VisibleForTesting
-    public void setRttTextStream(Connection.RttTextStream rttTextStream) {
-        mRttTextStream = rttTextStream;
-    }
-
-    @VisibleForTesting
-    public int getSendToIncall() {
-        return SEND_TO_INCALL;
-    }
-
     public String getNetworkBufferText() {
         return mBufferedTextToNetwork.toString();
     }
diff --git a/src/java/com/android/internal/telephony/metrics/CallQualityMetrics.java b/src/java/com/android/internal/telephony/metrics/CallQualityMetrics.java
index 208aff6..cf98acb 100644
--- a/src/java/com/android/internal/telephony/metrics/CallQualityMetrics.java
+++ b/src/java/com/android/internal/telephony/metrics/CallQualityMetrics.java
@@ -25,7 +25,7 @@
 import android.util.Pair;
 
 import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.SignalStrengthController;
+import com.android.internal.telephony.ServiceStateTracker;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession;
 import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
@@ -215,13 +215,13 @@
 
     // Returns the LTE signal to noise ratio, or 0 if unavailable
     private Integer getLteSnr() {
-        SignalStrengthController ssc = mPhone.getDefaultPhone().getSignalStrengthController();
-        if (ssc == null) {
-            Rlog.e(TAG, "getLteSnr: unable to get SSC for phone " + mPhone.getPhoneId());
+        ServiceStateTracker sst = mPhone.getDefaultPhone().getServiceStateTracker();
+        if (sst == null) {
+            Rlog.e(TAG, "getLteSnr: unable to get SST for phone " + mPhone.getPhoneId());
             return CellInfo.UNAVAILABLE;
         }
 
-        SignalStrength ss = ssc.getSignalStrength();
+        SignalStrength ss = sst.getSignalStrength();
         if (ss == null) {
             Rlog.e(TAG, "getLteSnr: unable to get SignalStrength for phone " + mPhone.getPhoneId());
             return CellInfo.UNAVAILABLE;
diff --git a/src/java/com/android/internal/telephony/metrics/DataCallSessionStats.java b/src/java/com/android/internal/telephony/metrics/DataCallSessionStats.java
index ae760f9..da350c3 100644
--- a/src/java/com/android/internal/telephony/metrics/DataCallSessionStats.java
+++ b/src/java/com/android/internal/telephony/metrics/DataCallSessionStats.java
@@ -29,6 +29,7 @@
 import android.telephony.Annotation.NetworkType;
 import android.telephony.DataFailCause;
 import android.telephony.ServiceState;
+import android.telephony.ServiceState.RilRadioTechnology;
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting.ProtocolType;
 import android.telephony.data.DataCallResponse;
@@ -43,13 +44,11 @@
 import com.android.internal.telephony.nano.PersistAtomsProto.DataCallSession;
 import com.android.telephony.Rlog;
 
-import java.util.Arrays;
 import java.util.Random;
 
 /** Collects data call change events per DataConnection for the pulled atom. */
 public class DataCallSessionStats {
     private static final String TAG = DataCallSessionStats.class.getSimpleName();
-    private static final int SIZE_LIMIT_HANDOVER_FAILURE_CAUSES = 15;
 
     private final Phone mPhone;
     private long mStartTime;
@@ -68,21 +67,20 @@
     public synchronized void onSetupDataCall(@ApnType int apnTypeBitMask) {
         mDataCallSession = getDefaultProto(apnTypeBitMask);
         mStartTime = getTimeMillis();
-        PhoneFactory.getMetricsCollector().registerOngoingDataCallStat(this);
     }
 
     /**
      * Updates the ongoing dataCall's atom for data call response event.
      *
      * @param response setup Data call response
-     * @param currentRat The data call current Network Type
+     * @param radioTechnology The data call RAT
      * @param apnTypeBitmask APN type bitmask
      * @param protocol Data connection protocol
      * @param failureCause failure cause as per android.telephony.DataFailCause
      */
     public synchronized void onSetupDataCallResponse(
             @Nullable DataCallResponse response,
-            @NetworkType int currentRat,
+            @RilRadioTechnology int radioTechnology,
             @ApnType int apnTypeBitmask,
             @ProtocolType int protocol,
             @DataFailureCause int failureCause) {
@@ -92,14 +90,7 @@
             loge("onSetupDataCallResponse: no DataCallSession atom has been initiated.");
             return;
         }
-
-        if (currentRat != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
-            mDataCallSession.ratAtEnd = currentRat;
-            mDataCallSession.bandAtEnd =
-                    (currentRat == TelephonyManager.NETWORK_TYPE_IWLAN)
-                            ? 0
-                            : ServiceStateStats.getBand(mPhone);
-        }
+        mDataCallSession.ratAtEnd = ServiceState.rilRadioTechnologyToNetworkType(radioTechnology);
 
         // only set if apn hasn't been set during setup
         if (mDataCallSession.apnTypeBitmask == 0) {
@@ -113,8 +104,11 @@
                     (int) Math.min(response.getRetryDurationMillis(), Integer.MAX_VALUE);
             // If setup has failed, then store the atom
             if (failureCause != DataFailCause.NONE) {
+                mDataCallSession.failureCause = failureCause;
                 mDataCallSession.setupFailed = true;
-                endDataCallSession();
+                mDataCallSession.ongoing = false;
+                mAtomsStorage.addDataCallSession(mDataCallSession);
+                mDataCallSession = null;
             }
         }
     }
@@ -151,42 +145,24 @@
         }
     }
 
-    /**
-     * Stores the atom when DataConnection reaches DISCONNECTED state.
-     *
-     * @param failureCause failure cause as per android.telephony.DataFailCause
-     */
+    /** Stores the atom when DataConnection reaches DISCONNECTED state.
+     *  @param failureCause failure cause as per android.telephony.DataFailCause
+     **/
     public synchronized void onDataCallDisconnected(@DataFailureCause int failureCause) {
         // there should've been another call to initiate the atom,
         // so this method is being called out of order -> no atom will be saved
-        // this also happens when DataConnection is created, which is expected
         if (mDataCallSession == null) {
-            logi("onDataCallDisconnected: no DataCallSession atom has been initiated.");
+            loge("onDataCallDisconnected: no DataCallSession atom has been initiated.");
             return;
         }
         mDataCallSession.failureCause = failureCause;
+        mDataCallSession.oosAtEnd = getIsOos();
+        mDataCallSession.ongoing = false;
         mDataCallSession.durationMinutes = convertMillisToMinutes(getTimeMillis() - mStartTime);
-        endDataCallSession();
-    }
-
-    /**
-     * Updates the atom when a handover fails. Note we only record distinct failure causes, as in
-     * most cases retry failures are due to the same cause.
-     *
-     * @param failureCause failure cause as per android.telephony.DataFailCause
-     */
-    public synchronized void onHandoverFailure(@DataFailureCause int failureCause) {
-        if (mDataCallSession != null
-                && mDataCallSession.handoverFailureCauses.length
-                < SIZE_LIMIT_HANDOVER_FAILURE_CAUSES) {
-            int[] failureCauses = mDataCallSession.handoverFailureCauses;
-            for (int cause : failureCauses) {
-                if (failureCause == cause) return;
-            }
-            mDataCallSession.handoverFailureCauses = Arrays.copyOf(
-                    failureCauses, failureCauses.length + 1);
-            mDataCallSession.handoverFailureCauses[failureCauses.length] = failureCause;
-        }
+        // store for the data call list event, after DataCall is disconnected and entered into
+        // inactive mode
+        mAtomsStorage.addDataCallSession(mDataCallSession);
+        mDataCallSession = null;
     }
 
     /**
@@ -195,79 +171,22 @@
      * <p>NOTE: in {@link ServiceStateTracker}, change of channel number will trigger data
      * registration state change.
      */
-    public synchronized void onDrsOrRatChanged(@NetworkType int currentRat) {
-        if (mDataCallSession != null && currentRat != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
-            if (mDataCallSession.ratAtEnd != currentRat) {
-                mDataCallSession.ratSwitchCount++;
-                mDataCallSession.ratAtEnd = currentRat;
-            }
-            // band may have changed even if RAT was the same
-            mDataCallSession.bandAtEnd =
-                    (currentRat == TelephonyManager.NETWORK_TYPE_IWLAN)
-                            ? 0
-                            : ServiceStateStats.getBand(mPhone);
+    public synchronized void onDrsOrRatChanged(@RilRadioTechnology int radioTechnology) {
+        @NetworkType int currentRat =
+                ServiceState.rilRadioTechnologyToNetworkType(radioTechnology);
+        if (mDataCallSession != null
+                && currentRat != TelephonyManager.NETWORK_TYPE_UNKNOWN
+                && mDataCallSession.ratAtEnd != currentRat) {
+            mDataCallSession.ratSwitchCount++;
+            mDataCallSession.ratAtEnd = currentRat;
+            mDataCallSession.bandAtEnd = ServiceStateStats.getBand(mPhone, currentRat);
         }
     }
 
-    /**
-     * Take a snapshot of the on-going data call segment to add to the atom storage.
-     *
-     * Note the following fields are reset after the snapshot:
-     * - rat switch count
-     * - handover failure causes
-     */
-    public synchronized void conclude() {
-        if (mDataCallSession != null) {
-            DataCallSession call = copyOf(mDataCallSession);
-            long nowMillis = getTimeMillis();
-            call.durationMinutes = convertMillisToMinutes(nowMillis - mStartTime);
-            mStartTime = nowMillis;
-            mDataCallSession.ratSwitchCount = 0L;
-            mDataCallSession.handoverFailureCauses = new int[0];
-            mAtomsStorage.addDataCallSession(call);
-        }
-    }
-
-    /** Put the current data call to an end after being uploaded to AtomStorage. */
-    private void endDataCallSession() {
-        mDataCallSession.oosAtEnd = getIsOos();
-        mDataCallSession.ongoing = false;
-        // store for the data call list event, after DataCall is disconnected and entered into
-        // inactive mode
-        PhoneFactory.getMetricsCollector().unregisterOngoingDataCallStat(this);
-        mAtomsStorage.addDataCallSession(mDataCallSession);
-        mDataCallSession = null;
-    }
-
     private static long convertMillisToMinutes(long millis) {
         return Math.round(millis / 60000.0);
     }
 
-    private static DataCallSession copyOf(DataCallSession call) {
-        DataCallSession copy = new DataCallSession();
-        copy.dimension = call.dimension;
-        copy.isMultiSim = call.isMultiSim;
-        copy.isEsim = call.isEsim;
-        copy.apnTypeBitmask = call.apnTypeBitmask;
-        copy.carrierId = call.carrierId;
-        copy.isRoaming = call.isRoaming;
-        copy.ratAtEnd = call.ratAtEnd;
-        copy.oosAtEnd = call.oosAtEnd;
-        copy.ratSwitchCount = call.ratSwitchCount;
-        copy.isOpportunistic = call.isOpportunistic;
-        copy.ipType = call.ipType;
-        copy.setupFailed = call.setupFailed;
-        copy.failureCause = call.failureCause;
-        copy.suggestedRetryMillis = call.suggestedRetryMillis;
-        copy.deactivateReason = call.deactivateReason;
-        copy.durationMinutes = call.durationMinutes;
-        copy.ongoing = call.ongoing;
-        copy.bandAtEnd = call.bandAtEnd;
-        copy.handoverFailureCauses = Arrays.copyOf(call.handoverFailureCauses,
-                call.handoverFailureCauses.length);
-        return copy;
-    }
-
     /** Creates a proto for a normal {@code DataCallSession} with default values. */
     private DataCallSession getDefaultProto(@ApnType int apnTypeBitmask) {
         DataCallSession proto = new DataCallSession();
@@ -287,7 +206,6 @@
         proto.deactivateReason = DATA_CALL_SESSION__DEACTIVATE_REASON__DEACTIVATE_REASON_UNKNOWN;
         proto.durationMinutes = 0;
         proto.ongoing = true;
-        proto.handoverFailureCauses = new int[0];
         return proto;
     }
 
@@ -312,10 +230,6 @@
                 : false;
     }
 
-    private void logi(String format, Object... args) {
-        Rlog.i(TAG, "[" + mPhone.getPhoneId() + "]" + String.format(format, args));
-    }
-
     private void loge(String format, Object... args) {
         Rlog.e(TAG, "[" + mPhone.getPhoneId() + "]" + String.format(format, args));
     }
diff --git a/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java b/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
index 5ade0bb..410afcf 100644
--- a/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
+++ b/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
@@ -25,7 +25,6 @@
 import com.android.internal.telephony.ServiceStateTracker;
 import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.TelephonyStatsLog;
-import com.android.internal.telephony.data.DataStallRecoveryManager;
 import com.android.internal.telephony.dataconnection.DcTracker;
 
 /** Generates metrics related to data stall recovery events per phone ID for the pushed atom. */
@@ -36,93 +35,23 @@
      * @param recoveryAction Data stall recovery action
      * @param phone
      */
-
-    /* Since the Enum has been extended in Android T, we are mapping it to the correct number. */
-    private static final int RECOVERY_ACTION_RADIO_RESTART_MAPPING = 3;
-    private static final int RECOVERY_ACTION_RESET_MODEM_MAPPING = 4;
-
-
-    /** TODO: b/214044479 : Remove this function when new data design(Android T) start. */
-    public static void onDataStallEvent(
-            @DcTracker.RecoveryAction int recoveryAction,
-            Phone phone,
-            boolean isRecovered,
-            int durationMillis) {
+    public static void onDataStallEvent(@DcTracker.RecoveryAction int recoveryAction,
+            Phone phone, boolean isRecovered, int durationMillis) {
         if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
             phone = phone.getDefaultPhone();
         }
 
         int carrierId = phone.getCarrierId();
         int rat = getRat(phone);
-        int band =
-                (rat == TelephonyManager.NETWORK_TYPE_IWLAN) ? 0 : ServiceStateStats.getBand(phone);
+        int band = ServiceStateStats.getBand(phone, rat);
         // the number returned here matches the SignalStrength enum we have
         int signalStrength = phone.getSignalStrength().getLevel();
         boolean isOpportunistic = getIsOpportunistic(phone);
         boolean isMultiSim = SimSlotState.getCurrentState().numActiveSims > 1;
 
-        // Not use this field in Android S, so we send RECOVERED_REASON_NONE for default value.
-        int recoveryReason = 0;
-        TelephonyStatsLog.write(
-                TelephonyStatsLog.DATA_STALL_RECOVERY_REPORTED,
-                carrierId,
-                rat,
-                signalStrength,
-                recoveryAction,
-                isOpportunistic,
-                isMultiSim,
-                band,
-                isRecovered,
-                durationMillis,
-                recoveryReason);
-    }
-
-    /**
-     * Called when data stall happened.
-     *
-     * @param recoveryAction The recovery action.
-     * @param phone The phone instance.
-     * @param isRecovered The data stall symptom recovered or not.
-     * @param durationMillis The duration from data stall symptom occurred.
-     * @param reason The recovered(data resume) reason.
-     */
-    public static void onDataStallEvent(
-            @DataStallRecoveryManager.RecoveryAction int recoveryAction,
-            Phone phone,
-            boolean isRecovered,
-            int durationMillis,
-            @DataStallRecoveryManager.RecoveredReason int reason) {
-        if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
-            phone = phone.getDefaultPhone();
-        }
-
-        int carrierId = phone.getCarrierId();
-        int rat = getRat(phone);
-        int band =
-                (rat == TelephonyManager.NETWORK_TYPE_IWLAN) ? 0 : ServiceStateStats.getBand(phone);
-        // the number returned here matches the SignalStrength enum we have
-        int signalStrength = phone.getSignalStrength().getLevel();
-        boolean isOpportunistic = getIsOpportunistic(phone);
-        boolean isMultiSim = SimSlotState.getCurrentState().numActiveSims > 1;
-
-        if (recoveryAction == DataStallRecoveryManager.RECOVERY_ACTION_RADIO_RESTART) {
-            recoveryAction = RECOVERY_ACTION_RADIO_RESTART_MAPPING;
-        } else if (recoveryAction == DataStallRecoveryManager.RECOVERY_ACTION_RESET_MODEM) {
-            recoveryAction = RECOVERY_ACTION_RESET_MODEM_MAPPING;
-        }
-
-        TelephonyStatsLog.write(
-                TelephonyStatsLog.DATA_STALL_RECOVERY_REPORTED,
-                carrierId,
-                rat,
-                signalStrength,
-                recoveryAction,
-                isOpportunistic,
-                isMultiSim,
-                band,
-                isRecovered,
-                durationMillis,
-                reason);
+        TelephonyStatsLog.write(TelephonyStatsLog.DATA_STALL_RECOVERY_REPORTED, carrierId, rat,
+                signalStrength, recoveryAction, isOpportunistic, isMultiSim, band, isRecovered,
+                durationMillis);
     }
 
     /** Returns the RAT used for data (including IWLAN). */
@@ -130,8 +59,7 @@
         ServiceStateTracker serviceStateTracker = phone.getServiceStateTracker();
         ServiceState serviceState =
                 serviceStateTracker != null ? serviceStateTracker.getServiceState() : null;
-        return serviceState != null
-                ? serviceState.getDataNetworkType()
+        return serviceState != null ? serviceState.getDataNetworkType()
                 : TelephonyManager.NETWORK_TYPE_UNKNOWN;
     }
 
diff --git a/src/java/com/android/internal/telephony/metrics/ImsStats.java b/src/java/com/android/internal/telephony/metrics/ImsStats.java
index fefb799..fe00a4a 100644
--- a/src/java/com/android/internal/telephony/metrics/ImsStats.java
+++ b/src/java/com/android/internal/telephony/metrics/ImsStats.java
@@ -35,6 +35,8 @@
 import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.TransportType;
 import android.telephony.Annotation.NetworkType;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsReasonInfo;
 import android.telephony.ims.ProvisioningManager;
@@ -263,24 +265,10 @@
             @ImsRegistrationTech int radioTech, MmTelCapabilities capabilities) {
         conclude();
 
-        boolean ratChanged = false;
-        @NetworkType int newRat = convertRegistrationTechToNetworkType(radioTech);
-        if (mLastRegistrationStats != null && mLastRegistrationStats.rat != newRat) {
-            mLastRegistrationStats.rat = newRat;
-            ratChanged = true;
+        if (mLastRegistrationStats != null) {
+            mLastRegistrationStats.rat = convertRegistrationTechToNetworkType(radioTech);
         }
-
-        boolean voiceAvailableNow = capabilities.isCapable(CAPABILITY_TYPE_VOICE);
-        boolean voiceAvailabilityChanged =
-                (mLastAvailableFeatures.isCapable(CAPABILITY_TYPE_VOICE) != voiceAvailableNow);
         mLastAvailableFeatures = capabilities;
-
-        // Notify voice RAT change if 1. RAT changed while voice over IMS is available, or 2. voice
-        // over IMS availability changed
-        if ((ratChanged && voiceAvailableNow) || voiceAvailabilityChanged) {
-            mPhone.getDefaultPhone().getServiceStateTracker().getServiceStateStats()
-                    .onImsVoiceRegistrationChanged();
-        }
     }
 
     /** Updates the stats when capable features changed. */
@@ -347,20 +335,6 @@
         mLastAvailableFeatures = new MmTelCapabilities();
     }
 
-    /**
-     * Returns the current RAT used for IMS voice registration, or {@link
-     * TelephonyManager#NETWORK_TYPE_UNKNOWN} if there isn't any.
-     */
-    @NetworkType
-    @VisibleForTesting
-    public synchronized int getImsVoiceRadioTech() {
-        if (mLastRegistrationStats == null
-                || !mLastAvailableFeatures.isCapable(CAPABILITY_TYPE_VOICE)) {
-            return TelephonyManager.NETWORK_TYPE_UNKNOWN;
-        }
-        return mLastRegistrationStats.rat;
-    }
-
     @NetworkType
     private int getRatAtEnd(@NetworkType int lastStateRat) {
         return lastStateRat == TelephonyManager.NETWORK_TYPE_IWLAN ? lastStateRat : getWwanPsRat();
@@ -380,7 +354,14 @@
 
     @NetworkType
     private int getWwanPsRat() {
-        return ServiceStateStats.getDataRat(mPhone.getServiceStateTracker().getServiceState());
+        ServiceState state = mPhone.getServiceStateTracker().getServiceState();
+        final NetworkRegistrationInfo wwanRegInfo =
+                state.getNetworkRegistrationInfo(
+                        NetworkRegistrationInfo.DOMAIN_PS,
+                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        return wwanRegInfo != null
+                ? wwanRegInfo.getAccessNetworkTechnology()
+                : TelephonyManager.NETWORK_TYPE_UNKNOWN;
     }
 
     private ImsRegistrationStats getDefaultImsRegistrationStats() {
diff --git a/src/java/com/android/internal/telephony/metrics/InProgressCallSession.java b/src/java/com/android/internal/telephony/metrics/InProgressCallSession.java
index e0d60b6..748fe7d 100644
--- a/src/java/com/android/internal/telephony/metrics/InProgressCallSession.java
+++ b/src/java/com/android/internal/telephony/metrics/InProgressCallSession.java
@@ -99,7 +99,7 @@
      * Check if the Call Session contains CS calls
      * @return true if there are CS calls in the call list
      */
-    public synchronized boolean containsCsCalls() {
+    public boolean containsCsCalls() {
         for (TelephonyCallSession.Event event : events) {
             if (event.type == TelephonyCallSession.Event.Type.RIL_CALL_LIST_CHANGED) {
                 return true;
diff --git a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
index 6c5f8d4..ae9e30e 100644
--- a/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
+++ b/src/java/com/android/internal/telephony/metrics/MetricsCollector.java
@@ -24,28 +24,13 @@
 import static com.android.internal.telephony.TelephonyStatsLog.CELLULAR_DATA_SERVICE_SWITCH;
 import static com.android.internal.telephony.TelephonyStatsLog.CELLULAR_SERVICE_STATE;
 import static com.android.internal.telephony.TelephonyStatsLog.DATA_CALL_SESSION;
-import static com.android.internal.telephony.TelephonyStatsLog.DEVICE_TELEPHONY_PROPERTIES;
-import static com.android.internal.telephony.TelephonyStatsLog.GBA_EVENT;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_DEDICATED_BEARER_EVENT;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_DEDICATED_BEARER_LISTENER_EVENT;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_FEATURE_TAG_STATS;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS;
 import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_STATS;
 import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_TERMINATION;
 import static com.android.internal.telephony.TelephonyStatsLog.INCOMING_SMS;
 import static com.android.internal.telephony.TelephonyStatsLog.OUTGOING_SMS;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS;
-import static com.android.internal.telephony.TelephonyStatsLog.PRESENCE_NOTIFY_EVENT;
-import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS;
-import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS;
 import static com.android.internal.telephony.TelephonyStatsLog.SIM_SLOT_STATE;
-import static com.android.internal.telephony.TelephonyStatsLog.SIP_DELEGATE_STATS;
-import static com.android.internal.telephony.TelephonyStatsLog.SIP_MESSAGE_RESPONSE;
-import static com.android.internal.telephony.TelephonyStatsLog.SIP_TRANSPORT_FEATURE_TAG_STATS;
-import static com.android.internal.telephony.TelephonyStatsLog.SIP_TRANSPORT_SESSION;
 import static com.android.internal.telephony.TelephonyStatsLog.SUPPORTED_RADIO_ACCESS_FAMILY;
-import static com.android.internal.telephony.TelephonyStatsLog.TELEPHONY_NETWORK_REQUESTS_V2;
-import static com.android.internal.telephony.TelephonyStatsLog.UCE_EVENT_STATS;
+import static com.android.internal.telephony.TelephonyStatsLog.TELEPHONY_NETWORK_REQUESTS;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_RAT_USAGE;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION;
 
@@ -62,24 +47,11 @@
 import com.android.internal.telephony.nano.PersistAtomsProto.CellularDataServiceSwitch;
 import com.android.internal.telephony.nano.PersistAtomsProto.CellularServiceState;
 import com.android.internal.telephony.nano.PersistAtomsProto.DataCallSession;
-import com.android.internal.telephony.nano.PersistAtomsProto.GbaEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerListenerEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationFeatureTagStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationServiceDescStats;
 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationStats;
 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationTermination;
 import com.android.internal.telephony.nano.PersistAtomsProto.IncomingSms;
-import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequestsV2;
+import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequests;
 import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms;
-import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.RcsClientProvisioningStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipDelegateStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipMessageResponse;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportFeatureTagStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportSession;
-import com.android.internal.telephony.nano.PersistAtomsProto.UceEventStats;
 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallRatUsage;
 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallSession;
 import com.android.internal.util.ConcurrentUtils;
@@ -89,8 +61,6 @@
 import java.util.Comparator;
 import java.util.List;
 import java.util.Random;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * Implements statsd pullers for Telephony.
@@ -129,21 +99,13 @@
                     .setCoolDownMillis(MIN_COOLDOWN_MILLIS)
                     .build();
 
-    private final PersistAtomsStorage mStorage;
+    private PersistAtomsStorage mStorage;
     private final StatsManager mStatsManager;
     private final AirplaneModeStats mAirplaneModeStats;
-    private final Set<DataCallSessionStats> mOngoingDataCallStats = ConcurrentHashMap.newKeySet();
     private static final Random sRandom = new Random();
 
     public MetricsCollector(Context context) {
-        this(context, new PersistAtomsStorage(context));
-    }
-
-    /** Allows dependency injection. Used during unit tests. */
-    @VisibleForTesting
-    public MetricsCollector(Context context,
-                            PersistAtomsStorage storage) {
-        mStorage = storage;
+        mStorage = new PersistAtomsStorage(context);
         mStatsManager = (StatsManager) context.getSystemService(Context.STATS_MANAGER);
         if (mStatsManager != null) {
             registerAtom(CELLULAR_DATA_SERVICE_SWITCH, POLICY_PULL_DAILY);
@@ -158,22 +120,7 @@
             registerAtom(DATA_CALL_SESSION, POLICY_PULL_DAILY);
             registerAtom(IMS_REGISTRATION_STATS, POLICY_PULL_DAILY);
             registerAtom(IMS_REGISTRATION_TERMINATION, POLICY_PULL_DAILY);
-            registerAtom(TELEPHONY_NETWORK_REQUESTS_V2, POLICY_PULL_DAILY);
-            registerAtom(IMS_REGISTRATION_FEATURE_TAG_STATS, POLICY_PULL_DAILY);
-            registerAtom(RCS_CLIENT_PROVISIONING_STATS, POLICY_PULL_DAILY);
-            registerAtom(RCS_ACS_PROVISIONING_STATS, POLICY_PULL_DAILY);
-            registerAtom(SIP_DELEGATE_STATS, POLICY_PULL_DAILY);
-            registerAtom(SIP_TRANSPORT_FEATURE_TAG_STATS, POLICY_PULL_DAILY);
-            registerAtom(SIP_MESSAGE_RESPONSE, POLICY_PULL_DAILY);
-            registerAtom(SIP_TRANSPORT_SESSION, POLICY_PULL_DAILY);
-            registerAtom(DEVICE_TELEPHONY_PROPERTIES, null);
-            registerAtom(IMS_DEDICATED_BEARER_LISTENER_EVENT, POLICY_PULL_DAILY);
-            registerAtom(IMS_DEDICATED_BEARER_EVENT, POLICY_PULL_DAILY);
-            registerAtom(IMS_REGISTRATION_SERVICE_DESC_STATS, POLICY_PULL_DAILY);
-            registerAtom(UCE_EVENT_STATS, POLICY_PULL_DAILY);
-            registerAtom(PRESENCE_NOTIFY_EVENT, POLICY_PULL_DAILY);
-            registerAtom(GBA_EVENT, POLICY_PULL_DAILY);
-            registerAtom(PER_SIM_STATUS, null);
+            registerAtom(TELEPHONY_NETWORK_REQUESTS, POLICY_PULL_DAILY);
 
             Rlog.d(TAG, "registered");
         } else {
@@ -183,6 +130,12 @@
         mAirplaneModeStats = new AirplaneModeStats(context);
     }
 
+    /** Replaces the {@link PersistAtomsStorage} backing the puller. Used during unit tests. */
+    @VisibleForTesting
+    public void setPersistAtomsStorage(PersistAtomsStorage storage) {
+        mStorage = storage;
+    }
+
     /**
      * {@inheritDoc}
      *
@@ -217,38 +170,8 @@
                 return pullImsRegistrationStats(data);
             case IMS_REGISTRATION_TERMINATION:
                 return pullImsRegistrationTermination(data);
-            case TELEPHONY_NETWORK_REQUESTS_V2:
-                return pullTelephonyNetworkRequestsV2(data);
-            case DEVICE_TELEPHONY_PROPERTIES:
-                return pullDeviceTelephonyProperties(data);
-            case IMS_REGISTRATION_FEATURE_TAG_STATS:
-                return pullImsRegistrationFeatureTagStats(data);
-            case RCS_CLIENT_PROVISIONING_STATS:
-                return pullRcsClientProvisioningStats(data);
-            case RCS_ACS_PROVISIONING_STATS:
-                return pullRcsAcsProvisioningStats(data);
-            case SIP_DELEGATE_STATS:
-                return pullSipDelegateStats(data);
-            case SIP_TRANSPORT_FEATURE_TAG_STATS:
-                return pullSipTransportFeatureTagStats(data);
-            case SIP_MESSAGE_RESPONSE:
-                return pullSipMessageResponse(data);
-            case SIP_TRANSPORT_SESSION:
-                return pullSipTransportSession(data);
-            case IMS_DEDICATED_BEARER_LISTENER_EVENT:
-                return pullImsDedicatedBearerListenerEvent(data);
-            case IMS_DEDICATED_BEARER_EVENT:
-                return pullImsDedicatedBearerEvent(data);
-            case IMS_REGISTRATION_SERVICE_DESC_STATS:
-                return pullImsRegistrationServiceDescStats(data);
-            case UCE_EVENT_STATS:
-                return pullUceEventStats(data);
-            case PRESENCE_NOTIFY_EVENT:
-                return pullPresenceNotifyEvent(data);
-            case GBA_EVENT:
-                return pullGbaEvent(data);
-            case PER_SIM_STATUS:
-                return pullPerSimStatus(data);
+            case TELEPHONY_NETWORK_REQUESTS:
+                return pullTelephonyNetworkRequests(data);
             default:
                 Rlog.e(TAG, String.format("unexpected atom ID %d", atomTag));
                 return StatsManager.PULL_SKIP;
@@ -260,19 +183,6 @@
         return mStorage;
     }
 
-    /**
-     * Registers a {@link DataCallSessionStats} which will be pinged for on-going data calls when
-     * data call atoms are pulled.
-     */
-    public void registerOngoingDataCallStat(DataCallSessionStats call) {
-        mOngoingDataCallStats.add(call);
-    }
-
-    /** Unregisters a {@link DataCallSessionStats} when it no longer handles an active data call. */
-    public void unregisterOngoingDataCallStat(DataCallSessionStats call) {
-        mOngoingDataCallStats.remove(call);
-    }
-
     private static int pullSimSlotState(List<StatsEvent> data) {
         SimSlotState state;
         try {
@@ -379,11 +289,6 @@
     }
 
     private int pullDataCallSession(List<StatsEvent> data) {
-        // Include ongoing data call segments
-        for (DataCallSessionStats stats : mOngoingDataCallStats) {
-            stats.conclude();
-        }
-
         DataCallSession[] dataCallSessions = mStorage.getDataCallSessions(MIN_COOLDOWN_MILLIS);
         if (dataCallSessions != null) {
             Arrays.stream(dataCallSessions)
@@ -463,233 +368,18 @@
         }
     }
 
-    private int pullTelephonyNetworkRequestsV2(List<StatsEvent> data) {
-        NetworkRequestsV2[] persistAtoms = mStorage.getNetworkRequestsV2(MIN_COOLDOWN_MILLIS);
+    private int pullTelephonyNetworkRequests(List<StatsEvent> data) {
+        NetworkRequests[] persistAtoms = mStorage.getNetworkRequests(MIN_COOLDOWN_MILLIS);
         if (persistAtoms != null) {
             Arrays.stream(persistAtoms)
                     .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
             return StatsManager.PULL_SUCCESS;
         } else {
-            Rlog.w(TAG, "TELEPHONY_NETWORK_REQUESTS_V2 pull too frequent, skipping");
+            Rlog.w(TAG, "TELEPHONY_NETWORK_REQUESTS pull too frequent, skipping");
             return StatsManager.PULL_SKIP;
         }
     }
 
-    private static int pullDeviceTelephonyProperties(List<StatsEvent> data) {
-        Phone[] phones = getPhonesIfAny();
-        if (phones.length == 0) {
-            return StatsManager.PULL_SKIP;
-        }
-
-        data.add(TelephonyStatsLog.buildStatsEvent(DEVICE_TELEPHONY_PROPERTIES,
-                phones[0].isUsingNewDataStack()));
-        return StatsManager.PULL_SUCCESS;
-    }
-
-    private int pullImsRegistrationFeatureTagStats(List<StatsEvent> data) {
-        RcsStats.getInstance().onFlushIncompleteImsRegistrationFeatureTagStats();
-
-        ImsRegistrationFeatureTagStats[] persistAtoms =
-                mStorage.getImsRegistrationFeatureTagStats(MIN_COOLDOWN_MILLIS);
-        if (persistAtoms != null) {
-            Arrays.stream(persistAtoms)
-                    .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
-            return StatsManager.PULL_SUCCESS;
-        } else {
-            Rlog.w(TAG, "IMS_REGISTRATION_FEATURE_TAG_STATS pull too frequent, skipping");
-            return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private int pullRcsClientProvisioningStats(List<StatsEvent> data) {
-        RcsClientProvisioningStats[] persistAtoms =
-                mStorage.getRcsClientProvisioningStats(MIN_COOLDOWN_MILLIS);
-        if (persistAtoms != null) {
-            Arrays.stream(persistAtoms)
-                    .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
-            return StatsManager.PULL_SUCCESS;
-        } else {
-            Rlog.w(TAG, "RCS_CLIENT_PROVISIONING_STATS pull too frequent, skipping");
-            return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private int pullRcsAcsProvisioningStats(List<StatsEvent> data) {
-        RcsStats.getInstance().onFlushIncompleteRcsAcsProvisioningStats();
-
-        RcsAcsProvisioningStats[] persistAtoms =
-                mStorage.getRcsAcsProvisioningStats(MIN_COOLDOWN_MILLIS);
-        if (persistAtoms != null) {
-            Arrays.stream(persistAtoms)
-                    .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
-            return StatsManager.PULL_SUCCESS;
-        } else {
-            Rlog.w(TAG, "RCS_ACS_PROVISIONING_STATS pull too frequent, skipping");
-            return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private int pullSipDelegateStats(List<StatsEvent> data) {
-        SipDelegateStats[] persisAtoms =
-                mStorage.getSipDelegateStats(MIN_COOLDOWN_MILLIS);
-        if (persisAtoms != null) {
-            Arrays.stream(persisAtoms)
-                    .forEach(persisAtom -> data.add(buildStatsEvent(persisAtom)));
-            return StatsManager.PULL_SUCCESS;
-        } else {
-            Rlog.w(TAG, "SIP_DELEGATE_STATS pull too frequent, skipping");
-            return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private int pullSipTransportFeatureTagStats(List<StatsEvent> data) {
-        RcsStats.getInstance().concludeSipTransportFeatureTagsStat();
-
-        SipTransportFeatureTagStats[] persisAtoms =
-                mStorage.getSipTransportFeatureTagStats(MIN_COOLDOWN_MILLIS);
-        if (persisAtoms != null) {
-            Arrays.stream(persisAtoms)
-                    .forEach(persisAtom -> data.add(buildStatsEvent(persisAtom)));
-            return StatsManager.PULL_SUCCESS;
-        } else {
-            Rlog.w(TAG, "SIP_DELEGATE_STATS pull too frequent, skipping");
-            return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private int pullSipMessageResponse(List<StatsEvent> data) {
-        SipMessageResponse[] persistAtoms =
-                mStorage.getSipMessageResponse(MIN_COOLDOWN_MILLIS);
-        if (persistAtoms != null) {
-            Arrays.stream(persistAtoms)
-                    .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
-            return StatsManager.PULL_SUCCESS;
-        } else {
-            Rlog.w(TAG, "RCS_SIP_MESSAGE_RESPONSE pull too frequent, skipping");
-            return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private int pullSipTransportSession(List<StatsEvent> data) {
-        SipTransportSession[] persistAtoms =
-                mStorage.getSipTransportSession(MIN_COOLDOWN_MILLIS);
-        if (persistAtoms != null) {
-            Arrays.stream(persistAtoms)
-                    .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
-            return StatsManager.PULL_SUCCESS;
-        } else {
-            Rlog.w(TAG, "RCS_SIP_TRANSPORT_SESSION pull too frequent, skipping");
-            return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private int pullImsDedicatedBearerListenerEvent(List<StatsEvent> data) {
-        ImsDedicatedBearerListenerEvent[] persistAtoms =
-            mStorage.getImsDedicatedBearerListenerEvent(MIN_COOLDOWN_MILLIS);
-        if (persistAtoms != null) {
-            Arrays.stream(persistAtoms)
-                .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
-            return StatsManager.PULL_SUCCESS;
-        } else {
-            Rlog.w(TAG, "IMS_DEDICATED_BEARER_LISTENER_EVENT pull too frequent, skipping");
-            return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private int pullImsDedicatedBearerEvent(List<StatsEvent> data) {
-        ImsDedicatedBearerEvent[] persistAtoms =
-            mStorage.getImsDedicatedBearerEvent(MIN_COOLDOWN_MILLIS);
-        if (persistAtoms != null) {
-            Arrays.stream(persistAtoms)
-                .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
-            return StatsManager.PULL_SUCCESS;
-        } else {
-            Rlog.w(TAG, "IMS_DEDICATED_BEARER_EVENT pull too frequent, skipping");
-            return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private int pullImsRegistrationServiceDescStats(List<StatsEvent> data) {
-        RcsStats.getInstance().onFlushIncompleteImsRegistrationServiceDescStats();
-        ImsRegistrationServiceDescStats[] persistAtoms =
-            mStorage.getImsRegistrationServiceDescStats(MIN_COOLDOWN_MILLIS);
-        if (persistAtoms != null) {
-            Arrays.stream(persistAtoms)
-                .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
-            return StatsManager.PULL_SUCCESS;
-        } else {
-            Rlog.w(TAG, "IMS_REGISTRATION_SERVICE_DESC_STATS pull too frequent, skipping");
-            return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private int pullUceEventStats(List<StatsEvent> data) {
-        UceEventStats[] persistAtoms = mStorage.getUceEventStats(MIN_COOLDOWN_MILLIS);
-        if (persistAtoms != null) {
-            Arrays.stream(persistAtoms)
-                .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
-            return StatsManager.PULL_SUCCESS;
-        } else {
-            Rlog.w(TAG, "UCE_EVENT_STATS pull too frequent, skipping");
-            return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private int pullPresenceNotifyEvent(List<StatsEvent> data) {
-        PresenceNotifyEvent[] persistAtoms = mStorage.getPresenceNotifyEvent(MIN_COOLDOWN_MILLIS);
-        if (persistAtoms != null) {
-            Arrays.stream(persistAtoms)
-                .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
-            return StatsManager.PULL_SUCCESS;
-        } else {
-            Rlog.w(TAG, "PRESENCE_NOTIFY_EVENT pull too frequent, skipping");
-            return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private int pullGbaEvent(List<StatsEvent> data) {
-        GbaEvent[] persistAtoms = mStorage.getGbaEvent(MIN_COOLDOWN_MILLIS);
-        if (persistAtoms != null) {
-            Arrays.stream(persistAtoms)
-                .forEach(persistAtom -> data.add(buildStatsEvent(persistAtom)));
-            return StatsManager.PULL_SUCCESS;
-        } else {
-            Rlog.w(TAG, "GBA_EVENT pull too frequent, skipping");
-            return StatsManager.PULL_SKIP;
-        }
-    }
-
-    private int pullPerSimStatus(List<StatsEvent> data) {
-        int result = StatsManager.PULL_SKIP;
-        for (Phone phone : getPhonesIfAny()) {
-            PerSimStatus perSimStatus = PerSimStatus.getCurrentState(phone);
-            if (perSimStatus == null) {
-                continue;
-            }
-            StatsEvent statsEvent = TelephonyStatsLog.buildStatsEvent(
-                    PER_SIM_STATUS,
-                    phone.getPhoneId(), // simSlotIndex
-                    perSimStatus.carrierId, // carrierId
-                    perSimStatus.phoneNumberSourceUicc, // phoneNumberSourceUicc
-                    perSimStatus.phoneNumberSourceCarrier, // phoneNumberSourceCarrier
-                    perSimStatus.phoneNumberSourceIms, // phoneNumberSourceIms
-                    perSimStatus.advancedCallingSettingEnabled, // volteEnabled
-                    perSimStatus.voWiFiSettingEnabled, // wfcEnabled
-                    perSimStatus.voWiFiModeSetting, // wfcMode
-                    perSimStatus.voWiFiRoamingModeSetting, // wfcRoamingMode
-                    perSimStatus.vtSettingEnabled, // videoCallingEnabled
-                    perSimStatus.dataRoamingEnabled, // dataRoamingEnabled
-                    perSimStatus.preferredNetworkType, // allowedNetworksByUser
-                    perSimStatus.disabled2g, // is2gDisabled
-                    perSimStatus.pin1Enabled, // isPin1Enabled
-                    perSimStatus.minimumVoltageClass, // simVoltageClass
-                    perSimStatus.userModifiedApnTypes); // userModifiedApnTypeBitmask
-            data.add(statsEvent);
-            result = StatsManager.PULL_SUCCESS;
-        }
-        return result;
-    }
-
     /** Registers a pulled atom ID {@code atomId} with optional {@code policy} for pulling. */
     private void registerAtom(int atomId, @Nullable StatsManager.PullAtomMetadata policy) {
         mStatsManager.setPullAtomCallback(atomId, policy, ConcurrentUtils.DIRECT_EXECUTOR, this);
@@ -717,8 +407,7 @@
                 state.simSlotIndex,
                 state.isMultiSim,
                 state.carrierId,
-                (int) (round(state.totalTimeMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS),
-                state.isEmergencyOnly);
+                (int) (round(state.totalTimeMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS));
     }
 
     private static StatsEvent buildStatsEvent(VoiceCallRatUsage usage) {
@@ -766,8 +455,7 @@
                 session.mainCodecQuality,
                 session.videoEnabled,
                 session.ratAtConnected,
-                session.isMultiparty,
-                session.callDuration);
+                session.isMultiparty);
     }
 
     private static StatsEvent buildStatsEvent(IncomingSms sms) {
@@ -804,8 +492,7 @@
                 sms.isEsim,
                 sms.carrierId,
                 sms.messageId,
-                sms.retryId,
-                sms.intervalMillis);
+                sms.retryId);
     }
 
     private static StatsEvent buildStatsEvent(DataCallSession dataCallSession) {
@@ -829,8 +516,7 @@
                 dataCallSession.deactivateReason,
                 round(dataCallSession.durationMinutes, DURATION_BUCKET_MILLIS / MINUTE_IN_MILLIS),
                 dataCallSession.ongoing,
-                dataCallSession.bandAtEnd,
-                dataCallSession.handoverFailureCauses);
+                dataCallSession.bandAtEnd);
     }
 
     private static StatsEvent buildStatsEvent(ImsRegistrationStats stats) {
@@ -867,159 +553,12 @@
                 termination.count);
     }
 
-    private static StatsEvent buildStatsEvent(NetworkRequestsV2 networkRequests) {
+    private static StatsEvent buildStatsEvent(NetworkRequests networkRequests) {
         return TelephonyStatsLog.buildStatsEvent(
-                TELEPHONY_NETWORK_REQUESTS_V2,
+                TELEPHONY_NETWORK_REQUESTS,
                 networkRequests.carrierId,
-                networkRequests.capability,
-                networkRequests.requestCount);
-    }
-
-    private static StatsEvent buildStatsEvent(ImsRegistrationFeatureTagStats stats) {
-        return TelephonyStatsLog.buildStatsEvent(
-                IMS_REGISTRATION_FEATURE_TAG_STATS,
-                stats.carrierId,
-                stats.slotId,
-                stats.featureTagName,
-                stats.registrationTech,
-                (int) (round(stats.registeredMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS));
-    }
-
-    private static StatsEvent buildStatsEvent(RcsClientProvisioningStats stats) {
-        return TelephonyStatsLog.buildStatsEvent(
-                RCS_CLIENT_PROVISIONING_STATS,
-                stats.carrierId,
-                stats.slotId,
-                stats.event,
-                stats.count);
-    }
-
-    private static StatsEvent buildStatsEvent(RcsAcsProvisioningStats stats) {
-        return TelephonyStatsLog.buildStatsEvent(
-                RCS_ACS_PROVISIONING_STATS,
-                stats.carrierId,
-                stats.slotId,
-                stats.responseCode,
-                stats.responseType,
-                stats.isSingleRegistrationEnabled,
-                stats.count,
-                (int) (round(stats.stateTimerMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS));
-    }
-
-    private static StatsEvent buildStatsEvent(SipDelegateStats stats) {
-        return TelephonyStatsLog.buildStatsEvent(
-                SIP_DELEGATE_STATS,
-                stats.dimension,
-                stats.carrierId,
-                stats.slotId,
-                (int) (round(stats.uptimeMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS),
-                stats.destroyReason);
-    }
-
-    private static StatsEvent buildStatsEvent(SipTransportFeatureTagStats stats) {
-        return TelephonyStatsLog.buildStatsEvent(
-                SIP_TRANSPORT_FEATURE_TAG_STATS,
-                stats.carrierId,
-                stats.slotId,
-                stats.featureTagName,
-                stats.sipTransportDeniedReason,
-                stats.sipTransportDeregisteredReason,
-                (int) (round(stats.associatedMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS));
-    }
-
-    private static StatsEvent buildStatsEvent(SipMessageResponse stats) {
-        return TelephonyStatsLog.buildStatsEvent(
-                SIP_MESSAGE_RESPONSE,
-                stats.carrierId,
-                stats.slotId,
-                stats.sipMessageMethod,
-                stats.sipMessageResponse,
-                stats.sipMessageDirection,
-                stats.messageError,
-                stats.count);
-    }
-
-    private static StatsEvent buildStatsEvent(SipTransportSession stats) {
-        return TelephonyStatsLog.buildStatsEvent(
-                SIP_TRANSPORT_SESSION,
-                stats.carrierId,
-                stats.slotId,
-                stats.sessionMethod,
-                stats.sipMessageDirection,
-                stats.sipResponse,
-                stats.sessionCount,
-                stats.endedGracefullyCount);
-    }
-
-    private static StatsEvent buildStatsEvent(ImsDedicatedBearerListenerEvent stats) {
-        return TelephonyStatsLog.buildStatsEvent(
-                IMS_DEDICATED_BEARER_LISTENER_EVENT,
-                stats.carrierId,
-                stats.slotId,
-                stats.ratAtEnd,
-                stats.qci,
-                stats.dedicatedBearerEstablished,
-                stats.eventCount);
-    }
-
-    private static StatsEvent buildStatsEvent(ImsDedicatedBearerEvent stats) {
-        return TelephonyStatsLog.buildStatsEvent(
-                IMS_DEDICATED_BEARER_EVENT,
-                stats.carrierId,
-                stats.slotId,
-                stats.ratAtEnd,
-                stats.qci,
-                stats.bearerState,
-                stats.localConnectionInfoReceived,
-                stats.remoteConnectionInfoReceived,
-                stats.hasListeners,
-                stats.count);
-    }
-
-    private static StatsEvent buildStatsEvent(ImsRegistrationServiceDescStats stats) {
-        return TelephonyStatsLog.buildStatsEvent(
-                IMS_REGISTRATION_SERVICE_DESC_STATS,
-                stats.carrierId,
-                stats.slotId,
-                stats.serviceIdName,
-                stats.serviceIdVersion,
-                stats.registrationTech,
-                (int) (round(stats.publishedMillis, DURATION_BUCKET_MILLIS) / SECOND_IN_MILLIS));
-    }
-
-    private static StatsEvent buildStatsEvent(UceEventStats stats) {
-        return TelephonyStatsLog.buildStatsEvent(
-                UCE_EVENT_STATS,
-                stats.carrierId,
-                stats.slotId,
-                stats.type,
-                stats.successful,
-                stats.commandCode,
-                stats.networkResponse,
-                stats.count);
-    }
-
-    private static StatsEvent buildStatsEvent(PresenceNotifyEvent stats) {
-        return TelephonyStatsLog.buildStatsEvent(
-                PRESENCE_NOTIFY_EVENT,
-                stats.carrierId,
-                stats.slotId,
-                stats.reason,
-                stats.contentBodyReceived,
-                stats.rcsCapsCount,
-                stats.mmtelCapsCount,
-                stats.noCapsCount,
-                stats.count);
-    }
-
-    private static StatsEvent buildStatsEvent(GbaEvent stats) {
-        return TelephonyStatsLog.buildStatsEvent(
-                GBA_EVENT,
-                stats.carrierId,
-                stats.slotId,
-                stats.successful,
-                stats.failedReason,
-                stats.count);
+                networkRequests.enterpriseRequestCount,
+                networkRequests.enterpriseReleaseCount);
     }
 
     /** Returns all phones in {@link PhoneFactory}, or an empty array if phones not made yet. */
diff --git a/src/java/com/android/internal/telephony/metrics/NetworkRequestsStats.java b/src/java/com/android/internal/telephony/metrics/NetworkRequestsStats.java
index 26c28f0..2975e72 100644
--- a/src/java/com/android/internal/telephony/metrics/NetworkRequestsStats.java
+++ b/src/java/com/android/internal/telephony/metrics/NetworkRequestsStats.java
@@ -23,7 +23,7 @@
 
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequestsV2;
+import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequests;
 
 
 /** Metrics for the network requests. */
@@ -32,33 +32,30 @@
 
     /** Generate metrics when network request occurs. */
     public static void addNetworkRequest(NetworkRequest networkRequest, int subId) {
+        if (!networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)) {
+            // Currently only handle enterprise
+            return;
+        }
+        NetworkRequests networkRequests = new NetworkRequests();
+        networkRequests.carrierId = getCarrierId(subId);
+        networkRequests.enterpriseRequestCount = 1;
+
         PersistAtomsStorage storage = PhoneFactory.getMetricsCollector().getAtomsStorage();
+        storage.addNetworkRequests(networkRequests);
+    }
 
-        NetworkRequestsV2 networkRequestsTemplate = new NetworkRequestsV2();
-        networkRequestsTemplate.carrierId = getCarrierId(subId);
-        networkRequestsTemplate.requestCount = 1;
-
-        if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)) {
-            networkRequestsTemplate.capability =
-                    NetworkRequestsV2.NetworkCapability.PRIORITIZE_LATENCY;
-            storage.addNetworkRequestsV2(networkRequestsTemplate);
+    /** Generate metrics when network release occurs. */
+    public static void addNetworkRelease(NetworkRequest networkRequest, int subId) {
+        if (!networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)) {
+            // Currently only handle enterprise
+            return;
         }
+        NetworkRequests networkRequests = new NetworkRequests();
+        networkRequests.carrierId = getCarrierId(subId);
+        networkRequests.enterpriseReleaseCount = 1;
 
-        if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)) {
-            networkRequestsTemplate.capability =
-                    NetworkRequestsV2.NetworkCapability.PRIORITIZE_BANDWIDTH;
-            storage.addNetworkRequestsV2(networkRequestsTemplate);
-        }
-
-        if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
-            networkRequestsTemplate.capability = NetworkRequestsV2.NetworkCapability.CBS;
-            storage.addNetworkRequestsV2(networkRequestsTemplate);
-        }
-
-        if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)) {
-            networkRequestsTemplate.capability = NetworkRequestsV2.NetworkCapability.ENTERPRISE;
-            storage.addNetworkRequestsV2(networkRequestsTemplate);
-        }
+        PersistAtomsStorage storage = PhoneFactory.getMetricsCollector().getAtomsStorage();
+        storage.addNetworkRequests(networkRequests);
     }
 
     /** Returns the carrier ID of the given subscription id. */
diff --git a/src/java/com/android/internal/telephony/metrics/PerSimStatus.java b/src/java/com/android/internal/telephony/metrics/PerSimStatus.java
deleted file mode 100644
index 5e348a0..0000000
--- a/src/java/com/android/internal/telephony/metrics/PerSimStatus.java
+++ /dev/null
@@ -1,272 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.metrics;
-
-import static android.provider.Telephony.Carriers.CONTENT_URI;
-import static android.telephony.PhoneNumberUtils.areSamePhoneNumber;
-import static android.telephony.SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER;
-import static android.telephony.SubscriptionManager.PHONE_NUMBER_SOURCE_IMS;
-import static android.telephony.SubscriptionManager.PHONE_NUMBER_SOURCE_UICC;
-
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_B;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_C;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_UNKNOWN;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__CELLULAR_PREFERRED;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__UNKNOWN;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__WIFI_ONLY;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__WIFI_PREFERRED;
-
-import android.annotation.Nullable;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.Telephony;
-import android.telephony.SubscriptionInfo;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.ims.ImsManager;
-import android.telephony.ims.ImsMmTelManager;
-import android.text.TextUtils;
-
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.SubscriptionController;
-import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.uicc.UiccSlot;
-
-import java.util.Optional;
-
-/** Stores the per SIM status. */
-public class PerSimStatus {
-    private static final long BITMASK_2G =
-            TelephonyManager.NETWORK_TYPE_BITMASK_GSM
-                    | TelephonyManager.NETWORK_TYPE_BITMASK_GPRS
-                    | TelephonyManager.NETWORK_TYPE_BITMASK_EDGE
-                    | TelephonyManager.NETWORK_TYPE_BITMASK_CDMA
-                    | TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT;
-
-    public final int carrierId;
-    public final int phoneNumberSourceUicc;
-    public final int phoneNumberSourceCarrier;
-    public final int phoneNumberSourceIms;
-    public final boolean advancedCallingSettingEnabled;
-    public final boolean voWiFiSettingEnabled;
-    public final int voWiFiModeSetting;
-    public final int voWiFiRoamingModeSetting;
-    public final boolean vtSettingEnabled;
-    public final boolean dataRoamingEnabled;
-    public final long preferredNetworkType;
-    public final boolean disabled2g;
-    public final boolean pin1Enabled;
-    public final int minimumVoltageClass;
-    public final int userModifiedApnTypes;
-
-    /** Returns the current sim status of the given {@link Phone}. */
-    @Nullable
-    public static PerSimStatus getCurrentState(Phone phone) {
-        int[] numberIds = getNumberIds(phone);
-        if (numberIds == null) return null;
-        ImsMmTelManager imsMmTelManager = getImsMmTelManager(phone);
-        IccCard iccCard = phone.getIccCard();
-        return new PerSimStatus(
-                phone.getCarrierId(),
-                numberIds[0],
-                numberIds[1],
-                numberIds[2],
-                imsMmTelManager == null ? false : imsMmTelManager.isAdvancedCallingSettingEnabled(),
-                imsMmTelManager == null ? false : imsMmTelManager.isVoWiFiSettingEnabled(),
-                imsMmTelManager == null
-                        ? PER_SIM_STATUS__WFC_MODE__UNKNOWN
-                        : wifiCallingModeToProtoEnum(imsMmTelManager.getVoWiFiModeSetting()),
-                imsMmTelManager == null
-                        ? PER_SIM_STATUS__WFC_MODE__UNKNOWN
-                        : wifiCallingModeToProtoEnum(imsMmTelManager.getVoWiFiRoamingModeSetting()),
-                imsMmTelManager == null ? false : imsMmTelManager.isVtSettingEnabled(),
-                phone.getDataRoamingEnabled(),
-                phone.getAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER),
-                is2gDisabled(phone),
-                iccCard == null ? false : iccCard.getIccLockEnabled(),
-                getMinimumVoltageClass(phone),
-                getUserModifiedApnTypes(phone));
-    }
-
-    private PerSimStatus(
-            int carrierId,
-            int phoneNumberSourceUicc,
-            int phoneNumberSourceCarrier,
-            int phoneNumberSourceIms,
-            boolean advancedCallingSettingEnabled,
-            boolean voWiFiSettingEnabled,
-            int voWiFiModeSetting,
-            int voWiFiRoamingModeSetting,
-            boolean vtSettingEnabled,
-            boolean dataRoamingEnabled,
-            long preferredNetworkType,
-            boolean disabled2g,
-            boolean pin1Enabled,
-            int minimumVoltageClass,
-            int userModifiedApnTypes) {
-        this.carrierId = carrierId;
-        this.phoneNumberSourceUicc = phoneNumberSourceUicc;
-        this.phoneNumberSourceCarrier = phoneNumberSourceCarrier;
-        this.phoneNumberSourceIms = phoneNumberSourceIms;
-        this.advancedCallingSettingEnabled = advancedCallingSettingEnabled;
-        this.voWiFiSettingEnabled = voWiFiSettingEnabled;
-        this.voWiFiModeSetting = voWiFiModeSetting;
-        this.voWiFiRoamingModeSetting = voWiFiRoamingModeSetting;
-        this.vtSettingEnabled = vtSettingEnabled;
-        this.dataRoamingEnabled = dataRoamingEnabled;
-        this.preferredNetworkType = preferredNetworkType;
-        this.disabled2g = disabled2g;
-        this.pin1Enabled = pin1Enabled;
-        this.minimumVoltageClass = minimumVoltageClass;
-        this.userModifiedApnTypes = userModifiedApnTypes;
-    }
-
-    @Nullable
-    private static ImsMmTelManager getImsMmTelManager(Phone phone) {
-        ImsManager imsManager = phone.getContext().getSystemService(ImsManager.class);
-        if (imsManager == null) {
-            return null;
-        }
-        try {
-            return imsManager.getImsMmTelManager(phone.getSubId());
-        } catch (IllegalArgumentException e) {
-            return null; // Invalid subId
-        }
-    }
-
-    /**
-     * Returns an array of integer ids representing phone numbers. If number is empty then id will
-     * be 0. Two same numbers will have same id, and different numbers will have different ids. For
-     * example, [1, 0, 1] means that uicc and ims numbers are the same while carrier number is empty
-     * and [1, 2, 3] means all numbers are different.
-     *
-     * <ul>
-     *   <li>Index 0: id associated with {@code PHONE_NUMBER_SOURCE_UICC}.</li>
-     *   <li>Index 1: id associated with {@code PHONE_NUMBER_SOURCE_CARRIER}.</li>
-     *   <li>Index 2: id associated with {@code PHONE_NUMBER_SOURCE_IMS}.</li>
-     * </ul>
-     */
-    @Nullable
-    private static int[] getNumberIds(Phone phone) {
-        SubscriptionController subscriptionController = SubscriptionController.getInstance();
-        if (subscriptionController == null) {
-            return null;
-        }
-        int subId = phone.getSubId();
-        String countryIso =
-                Optional.ofNullable(subscriptionController.getSubscriptionInfo(subId))
-                        .map(SubscriptionInfo::getCountryIso)
-                        .orElse("");
-        // numbersFromAllSources[] - phone numbers from each sources:
-        String[] numbersFromAllSources =
-                new String[] {
-                    subscriptionController.getPhoneNumber(
-                            subId, PHONE_NUMBER_SOURCE_UICC, null, null), // 0
-                    subscriptionController.getPhoneNumber(
-                            subId, PHONE_NUMBER_SOURCE_CARRIER, null, null), // 1
-                    subscriptionController.getPhoneNumber(
-                            subId, PHONE_NUMBER_SOURCE_IMS, null, null), // 2
-                };
-        int[] numberIds = new int[numbersFromAllSources.length]; // default value 0
-        for (int i = 0, idForNextUniqueNumber = 1; i < numberIds.length; i++) {
-            if (TextUtils.isEmpty(numbersFromAllSources[i])) {
-                // keep id 0 if number not available
-                continue;
-            }
-            // the number is available:
-            // try to find the same number from other sources and reuse the id
-            for (int j = 0; j < i; j++) {
-                if (!TextUtils.isEmpty(numbersFromAllSources[j])
-                        && areSamePhoneNumber(
-                                numbersFromAllSources[i], numbersFromAllSources[j], countryIso)) {
-                    numberIds[i] = numberIds[j];
-                }
-            }
-            // didn't find same number (otherwise should not be id 0), assign a new id
-            if (numberIds[i] == 0) {
-                numberIds[i] = idForNextUniqueNumber++;
-            }
-        }
-        return numberIds;
-    }
-
-    /**
-     * Returns {@code true} if 2G cellular network is disabled (Allow 2G toggle in the settings).
-     */
-    private static boolean is2gDisabled(Phone phone) {
-        return (phone.getAllowedNetworkTypes(
-                                TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G)
-                        & BITMASK_2G)
-                == 0;
-    }
-
-    /** Converts {@link ImsMmTelManager.WifiCallingMode} to the value of PerSimStatus WfcMode. */
-    private static int wifiCallingModeToProtoEnum(@ImsMmTelManager.WiFiCallingMode int mode) {
-        switch (mode) {
-            case ImsMmTelManager.WIFI_MODE_WIFI_ONLY:
-                return PER_SIM_STATUS__WFC_MODE__WIFI_ONLY;
-            case ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED:
-                return PER_SIM_STATUS__WFC_MODE__CELLULAR_PREFERRED;
-            case ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED:
-                return PER_SIM_STATUS__WFC_MODE__WIFI_PREFERRED;
-            default:
-                return PER_SIM_STATUS__WFC_MODE__UNKNOWN;
-        }
-    }
-
-    /** Returns the minimum voltage class supported by the UICC. */
-    private static int getMinimumVoltageClass(Phone phone) {
-        UiccSlot uiccSlot = UiccController.getInstance().getUiccSlotForPhone(phone.getPhoneId());
-        if (uiccSlot == null) {
-            return PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_UNKNOWN;
-        }
-        switch (uiccSlot.getMinimumVoltageClass()) {
-            case UiccSlot.VOLTAGE_CLASS_A:
-                return PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A;
-            case UiccSlot.VOLTAGE_CLASS_B:
-                return PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_B;
-            case UiccSlot.VOLTAGE_CLASS_C:
-                return PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_C;
-            default:
-                return PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_UNKNOWN;
-        }
-    }
-
-    /** Returns the bitmask representing types of APNs modified by user. */
-    private static int getUserModifiedApnTypes(Phone phone) {
-        String[] projections = {Telephony.Carriers.TYPE};
-        String selection = Telephony.Carriers.EDITED_STATUS + "=?";
-        String[] selectionArgs = {Integer.toString(Telephony.Carriers.USER_EDITED)};
-        try (Cursor cursor =
-                phone.getContext()
-                        .getContentResolver()
-                        .query(
-                                Uri.withAppendedPath(CONTENT_URI, "subId/" + phone.getSubId()),
-                                projections,
-                                selection,
-                                selectionArgs,
-                                null)) {
-            int bitmask = 0;
-            while (cursor != null && cursor.moveToNext()) {
-                bitmask |= ApnSetting.getApnTypesBitmaskFromString(cursor.getString(0));
-            }
-            return bitmask;
-        }
-    }
-}
diff --git a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
index 2554463..7265f84 100644
--- a/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
+++ b/src/java/com/android/internal/telephony/metrics/PersistAtomsStorage.java
@@ -16,11 +16,8 @@
 
 package com.android.internal.telephony.metrics;
 
-import static android.text.format.DateUtils.DAY_IN_MILLIS;
-
 import android.annotation.Nullable;
 import android.content.Context;
-import android.content.pm.PackageManager;
 import android.os.Build;
 import android.os.Handler;
 import android.os.HandlerThread;
@@ -31,25 +28,12 @@
 import com.android.internal.telephony.nano.PersistAtomsProto.CellularDataServiceSwitch;
 import com.android.internal.telephony.nano.PersistAtomsProto.CellularServiceState;
 import com.android.internal.telephony.nano.PersistAtomsProto.DataCallSession;
-import com.android.internal.telephony.nano.PersistAtomsProto.GbaEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerListenerEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationFeatureTagStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationServiceDescStats;
 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationStats;
 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationTermination;
 import com.android.internal.telephony.nano.PersistAtomsProto.IncomingSms;
-import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequestsV2;
+import com.android.internal.telephony.nano.PersistAtomsProto.NetworkRequests;
 import com.android.internal.telephony.nano.PersistAtomsProto.OutgoingSms;
 import com.android.internal.telephony.nano.PersistAtomsProto.PersistAtoms;
-import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.RcsClientProvisioningStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipDelegateStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipMessageResponse;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportFeatureTagStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportSession;
-import com.android.internal.telephony.nano.PersistAtomsProto.UceEventStats;
 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallRatUsage;
 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallSession;
 import com.android.internal.util.ArrayUtils;
@@ -87,73 +71,34 @@
     private static final int SAVE_TO_FILE_DELAY_FOR_GET_MILLIS = 500;
 
     /** Maximum number of call sessions to store between pulls. */
-    private final int mMaxNumVoiceCallSessions;
+    private static final int MAX_NUM_CALL_SESSIONS = 50;
 
     /**
      * Maximum number of SMS to store between pulls. Incoming messages and outgoing messages are
      * counted separately.
      */
-    private final int mMaxNumSms;
+    private static final int MAX_NUM_SMS = 25;
 
     /**
      * Maximum number of carrier ID mismatch events stored on the device to avoid sending duplicated
      * metrics.
      */
-    private final int mMaxNumCarrierIdMismatches;
+    private static final int MAX_CARRIER_ID_MISMATCH = 40;
 
     /** Maximum number of data call sessions to store during pulls. */
-    private final int mMaxNumDataCallSessions;
+    private static final int MAX_NUM_DATA_CALL_SESSIONS = 15;
 
     /** Maximum number of service states to store between pulls. */
-    private final int mMaxNumCellularServiceStates;
+    private static final int MAX_NUM_CELLULAR_SERVICE_STATES = 50;
 
     /** Maximum number of data service switches to store between pulls. */
-    private final int mMaxNumCellularDataSwitches;
+    private static final int MAX_NUM_CELLULAR_DATA_SERVICE_SWITCHES = 50;
 
     /** Maximum number of IMS registration stats to store between pulls. */
-    private final int mMaxNumImsRegistrationStats;
+    private static final int MAX_NUM_IMS_REGISTRATION_STATS = 10;
 
     /** Maximum number of IMS registration terminations to store between pulls. */
-    private final int mMaxNumImsRegistrationTerminations;
-
-    /** Maximum number of IMS Registration Feature Tags to store between pulls. */
-    private final int mMaxNumImsRegistrationFeatureStats;
-
-    /** Maximum number of RCS Client Provisioning to store between pulls. */
-    private final int mMaxNumRcsClientProvisioningStats;
-
-    /** Maximum number of RCS Acs Provisioning to store between pulls. */
-    private final int mMaxNumRcsAcsProvisioningStats;
-
-    /** Maximum number of Sip Message Response to store between pulls. */
-    private final int mMaxNumSipMessageResponseStats;
-
-    /** Maximum number of Sip Transport Session to store between pulls. */
-    private final int mMaxNumSipTransportSessionStats;
-
-    /** Maximum number of Sip Delegate to store between pulls. */
-    private final int mMaxNumSipDelegateStats;
-
-    /** Maximum number of Sip Transport Feature Tag to store between pulls. */
-    private final int mMaxNumSipTransportFeatureTagStats;
-
-    /** Maximum number of Dedicated Bearer Listener Event to store between pulls. */
-    private final int mMaxNumDedicatedBearerListenerEventStats;
-
-    /** Maximum number of Dedicated Bearer Event to store between pulls. */
-    private final int mMaxNumDedicatedBearerEventStats;
-
-    /** Maximum number of IMS Registration Service Desc to store between pulls. */
-    private final int mMaxNumImsRegistrationServiceDescStats;
-
-    /** Maximum number of UCE Event to store between pulls. */
-    private final int mMaxNumUceEventStats;
-
-    /** Maximum number of Presence Notify Event to store between pulls. */
-    private final int mMaxNumPresenceNotifyEventStats;
-
-    /** Maximum number of GBA Event to store between pulls. */
-    private final int mMaxNumGbaEventStats;
+    private static final int MAX_NUM_IMS_REGISTRATION_TERMINATIONS = 10;
 
     /** Stores persist atoms and persist states of the puller. */
     @VisibleForTesting protected final PersistAtoms mAtoms;
@@ -179,54 +124,6 @@
 
     public PersistAtomsStorage(Context context) {
         mContext = context;
-
-        if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_RAM_LOW)) {
-            Rlog.i(TAG, "Low RAM device");
-            mMaxNumVoiceCallSessions = 10;
-            mMaxNumSms = 5;
-            mMaxNumCarrierIdMismatches = 8;
-            mMaxNumDataCallSessions = 5;
-            mMaxNumCellularServiceStates = 10;
-            mMaxNumCellularDataSwitches = 5;
-            mMaxNumImsRegistrationStats = 5;
-            mMaxNumImsRegistrationTerminations = 5;
-            mMaxNumImsRegistrationFeatureStats = 15;
-            mMaxNumRcsClientProvisioningStats = 5;
-            mMaxNumRcsAcsProvisioningStats = 5;
-            mMaxNumSipMessageResponseStats = 10;
-            mMaxNumSipTransportSessionStats = 10;
-            mMaxNumSipDelegateStats = 5;
-            mMaxNumSipTransportFeatureTagStats = 15;
-            mMaxNumDedicatedBearerListenerEventStats = 5;
-            mMaxNumDedicatedBearerEventStats = 5;
-            mMaxNumImsRegistrationServiceDescStats = 15;
-            mMaxNumUceEventStats = 5;
-            mMaxNumPresenceNotifyEventStats = 10;
-            mMaxNumGbaEventStats = 5;
-        } else {
-            mMaxNumVoiceCallSessions = 50;
-            mMaxNumSms = 25;
-            mMaxNumCarrierIdMismatches = 40;
-            mMaxNumDataCallSessions = 15;
-            mMaxNumCellularServiceStates = 50;
-            mMaxNumCellularDataSwitches = 50;
-            mMaxNumImsRegistrationStats = 10;
-            mMaxNumImsRegistrationTerminations = 10;
-            mMaxNumImsRegistrationFeatureStats = 25;
-            mMaxNumRcsClientProvisioningStats = 10;
-            mMaxNumRcsAcsProvisioningStats = 10;
-            mMaxNumSipMessageResponseStats = 25;
-            mMaxNumSipTransportSessionStats = 25;
-            mMaxNumSipDelegateStats = 10;
-            mMaxNumSipTransportFeatureTagStats = 25;
-            mMaxNumDedicatedBearerListenerEventStats = 10;
-            mMaxNumDedicatedBearerEventStats = 10;
-            mMaxNumImsRegistrationServiceDescStats = 25;
-            mMaxNumUceEventStats = 25;
-            mMaxNumPresenceNotifyEventStats = 50;
-            mMaxNumGbaEventStats = 10;
-        }
-
         mAtoms = loadAtomsFromFile();
         mVoiceCallRatTracker = VoiceCallRatTracker.fromProto(mAtoms.voiceCallRatUsage);
 
@@ -239,7 +136,7 @@
     /** Adds a call to the storage. */
     public synchronized void addVoiceCallSession(VoiceCallSession call) {
         mAtoms.voiceCallSession =
-                insertAtRandomPlace(mAtoms.voiceCallSession, call, mMaxNumVoiceCallSessions);
+                insertAtRandomPlace(mAtoms.voiceCallSession, call, MAX_NUM_CALL_SESSIONS);
         saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
 
         Rlog.d(TAG, "Add new voice call session: " + call.toString());
@@ -254,7 +151,7 @@
 
     /** Adds an incoming SMS to the storage. */
     public synchronized void addIncomingSms(IncomingSms sms) {
-        mAtoms.incomingSms = insertAtRandomPlace(mAtoms.incomingSms, sms, mMaxNumSms);
+        mAtoms.incomingSms = insertAtRandomPlace(mAtoms.incomingSms, sms, MAX_NUM_SMS);
         saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
 
         // To be removed
@@ -272,7 +169,7 @@
             }
         }
 
-        mAtoms.outgoingSms = insertAtRandomPlace(mAtoms.outgoingSms, sms, mMaxNumSms);
+        mAtoms.outgoingSms = insertAtRandomPlace(mAtoms.outgoingSms, sms, MAX_NUM_SMS);
         saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
 
         // To be removed
@@ -290,7 +187,7 @@
             state.lastUsedMillis = getWallTimeMillis();
             mAtoms.cellularServiceState =
                     insertAtRandomPlace(
-                            mAtoms.cellularServiceState, state, mMaxNumCellularServiceStates);
+                            mAtoms.cellularServiceState, state, MAX_NUM_CELLULAR_SERVICE_STATES);
         }
 
         if (serviceSwitch != null) {
@@ -304,7 +201,7 @@
                         insertAtRandomPlace(
                                 mAtoms.cellularDataServiceSwitch,
                                 serviceSwitch,
-                                mMaxNumCellularDataSwitches);
+                                MAX_NUM_CELLULAR_DATA_SERVICE_SWITCHES);
             }
         }
 
@@ -313,17 +210,8 @@
 
     /** Adds a data call session to the storage. */
     public synchronized void addDataCallSession(DataCallSession dataCall) {
-        int index = findIndex(dataCall);
-        if (index >= 0) {
-            DataCallSession existingCall = mAtoms.dataCallSession[index];
-            dataCall.ratSwitchCount += existingCall.ratSwitchCount;
-            dataCall.durationMinutes += existingCall.durationMinutes;
-            mAtoms.dataCallSession[index] = dataCall;
-        } else {
-            mAtoms.dataCallSession =
-                    insertAtRandomPlace(mAtoms.dataCallSession, dataCall, mMaxNumDataCallSessions);
-        }
-
+        mAtoms.dataCallSession =
+                insertAtRandomPlace(mAtoms.dataCallSession, dataCall, MAX_NUM_DATA_CALL_SESSIONS);
         saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
     }
 
@@ -340,14 +228,14 @@
         }
         // Add the new CarrierIdMismatch at the end of the array, so that the same atom will not be
         // sent again in future.
-        if (mAtoms.carrierIdMismatch.length == mMaxNumCarrierIdMismatches) {
+        if (mAtoms.carrierIdMismatch.length == MAX_CARRIER_ID_MISMATCH) {
             System.arraycopy(
                     mAtoms.carrierIdMismatch,
                     1,
                     mAtoms.carrierIdMismatch,
                     0,
-                    mMaxNumCarrierIdMismatches - 1);
-            mAtoms.carrierIdMismatch[mMaxNumCarrierIdMismatches - 1] = carrierIdMismatch;
+                    MAX_CARRIER_ID_MISMATCH - 1);
+            mAtoms.carrierIdMismatch[MAX_CARRIER_ID_MISMATCH - 1] = carrierIdMismatch;
         } else {
             int newLength = mAtoms.carrierIdMismatch.length + 1;
             mAtoms.carrierIdMismatch = Arrays.copyOf(mAtoms.carrierIdMismatch, newLength);
@@ -375,7 +263,7 @@
             stats.lastUsedMillis = getWallTimeMillis();
             mAtoms.imsRegistrationStats =
                     insertAtRandomPlace(
-                            mAtoms.imsRegistrationStats, stats, mMaxNumImsRegistrationStats);
+                            mAtoms.imsRegistrationStats, stats, MAX_NUM_IMS_REGISTRATION_STATS);
         }
         saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
     }
@@ -392,7 +280,7 @@
                     insertAtRandomPlace(
                             mAtoms.imsRegistrationTermination,
                             termination,
-                            mMaxNumImsRegistrationTerminations);
+                            MAX_NUM_IMS_REGISTRATION_TERMINATIONS);
         }
         saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
     }
@@ -412,191 +300,16 @@
         }
     }
 
-    /** Adds a new {@link NetworkRequestsV2} to the storage. */
-    public synchronized void addNetworkRequestsV2(NetworkRequestsV2 networkRequests) {
-        NetworkRequestsV2 existingMetrics = find(networkRequests);
+    /** Adds a new {@link NetworkRequests} to the storage. */
+    public synchronized void addNetworkRequests(NetworkRequests networkRequests) {
+        NetworkRequests existingMetrics = find(networkRequests);
         if (existingMetrics != null) {
-            existingMetrics.requestCount += networkRequests.requestCount;
+            existingMetrics.enterpriseRequestCount += networkRequests.enterpriseRequestCount;
+            existingMetrics.enterpriseReleaseCount += networkRequests.enterpriseReleaseCount;
         } else {
-            NetworkRequestsV2 newMetrics = new NetworkRequestsV2();
-            newMetrics.capability = networkRequests.capability;
-            newMetrics.carrierId = networkRequests.carrierId;
-            newMetrics.requestCount = networkRequests.requestCount;
-            int newLength = mAtoms.networkRequestsV2.length + 1;
-            mAtoms.networkRequestsV2 = Arrays.copyOf(mAtoms.networkRequestsV2, newLength);
-            mAtoms.networkRequestsV2[newLength - 1] = newMetrics;
-        }
-        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
-    }
-
-    /** Adds a new {@link ImsRegistrationFeatureTagStats} to the storage. */
-    public synchronized void addImsRegistrationFeatureTagStats(
-                ImsRegistrationFeatureTagStats stats) {
-        ImsRegistrationFeatureTagStats existingStats = find(stats);
-        if (existingStats != null) {
-            existingStats.registeredMillis += stats.registeredMillis;
-        } else {
-            mAtoms.imsRegistrationFeatureTagStats =
-                insertAtRandomPlace(mAtoms.imsRegistrationFeatureTagStats,
-                    stats, mMaxNumImsRegistrationFeatureStats);
-        }
-        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
-    }
-
-    /** Adds a new {@link RcsClientProvisioningStats} to the storage. */
-    public synchronized void addRcsClientProvisioningStats(RcsClientProvisioningStats stats) {
-        RcsClientProvisioningStats existingStats = find(stats);
-        if (existingStats != null) {
-            existingStats.count += 1;
-        } else {
-            mAtoms.rcsClientProvisioningStats =
-                insertAtRandomPlace(mAtoms.rcsClientProvisioningStats, stats,
-                        mMaxNumRcsClientProvisioningStats);
-        }
-        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
-    }
-
-    /** Adds a new {@link RcsAcsProvisioningStats} to the storage. */
-    public synchronized void addRcsAcsProvisioningStats(RcsAcsProvisioningStats stats) {
-        RcsAcsProvisioningStats existingStats = find(stats);
-        if (existingStats != null) {
-            existingStats.count += 1;
-            existingStats.stateTimerMillis += stats.stateTimerMillis;
-        } else {
-            // prevent that wrong count from caller effects total count
-            stats.count = 1;
-            mAtoms.rcsAcsProvisioningStats =
-                insertAtRandomPlace(mAtoms.rcsAcsProvisioningStats, stats,
-                        mMaxNumRcsAcsProvisioningStats);
-        }
-        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
-    }
-
-    /** Adds a new {@link SipDelegateStats} to the storage. */
-    public synchronized void addSipDelegateStats(SipDelegateStats stats) {
-        mAtoms.sipDelegateStats = insertAtRandomPlace(mAtoms.sipDelegateStats, stats,
-                mMaxNumSipDelegateStats);
-        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
-    }
-
-    /** Adds a new {@link SipTransportFeatureTagStats} to the storage. */
-    public synchronized void addSipTransportFeatureTagStats(SipTransportFeatureTagStats stats) {
-        SipTransportFeatureTagStats lastStat = find(stats);
-        if (lastStat != null) {
-            lastStat.associatedMillis += stats.associatedMillis;
-        } else {
-            mAtoms.sipTransportFeatureTagStats =
-                    insertAtRandomPlace(mAtoms.sipTransportFeatureTagStats, stats,
-                            mMaxNumSipTransportFeatureTagStats);
-        }
-        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
-    }
-
-    /** Adds a new {@link SipMessageResponse} to the storage. */
-    public synchronized void addSipMessageResponse(SipMessageResponse stats) {
-        SipMessageResponse existingStats = find(stats);
-        if (existingStats != null) {
-            existingStats.count += 1;
-        } else {
-            mAtoms.sipMessageResponse = insertAtRandomPlace(mAtoms.sipMessageResponse, stats,
-                    mMaxNumSipMessageResponseStats);
-        }
-        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
-    }
-
-    /** Adds a new {@link SipTransportSession} to the storage. */
-    public synchronized void addCompleteSipTransportSession(SipTransportSession stats) {
-        SipTransportSession existingStats = find(stats);
-        if (existingStats != null) {
-            existingStats.sessionCount += 1;
-            if (stats.isEndedGracefully) {
-                existingStats.endedGracefullyCount += 1;
-            }
-        } else {
-            mAtoms.sipTransportSession =
-                    insertAtRandomPlace(mAtoms.sipTransportSession, stats,
-                            mMaxNumSipTransportSessionStats);
-        }
-        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
-    }
-
-    /** Adds a new {@link ImsDedicatedBearerListenerEvent} to the storage. */
-    public synchronized void addImsDedicatedBearerListenerEvent(
-                ImsDedicatedBearerListenerEvent stats) {
-        ImsDedicatedBearerListenerEvent existingStats = find(stats);
-        if (existingStats != null) {
-            existingStats.eventCount += 1;
-        } else {
-            mAtoms.imsDedicatedBearerListenerEvent =
-                insertAtRandomPlace(mAtoms.imsDedicatedBearerListenerEvent,
-                    stats, mMaxNumDedicatedBearerListenerEventStats);
-        }
-        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
-    }
-
-    /** Adds a new {@link ImsDedicatedBearerEvent} to the storage. */
-    public synchronized void addImsDedicatedBearerEvent(ImsDedicatedBearerEvent stats) {
-        ImsDedicatedBearerEvent existingStats = find(stats);
-        if (existingStats != null) {
-            existingStats.count += 1;
-        } else {
-            mAtoms.imsDedicatedBearerEvent =
-                insertAtRandomPlace(mAtoms.imsDedicatedBearerEvent, stats,
-                        mMaxNumDedicatedBearerEventStats);
-        }
-        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
-    }
-
-    /** Adds a new {@link ImsRegistrationServiceDescStats} to the storage. */
-    public synchronized void addImsRegistrationServiceDescStats(
-            ImsRegistrationServiceDescStats stats) {
-        ImsRegistrationServiceDescStats existingStats = find(stats);
-        if (existingStats != null) {
-            existingStats.publishedMillis += stats.publishedMillis;
-        } else {
-            mAtoms.imsRegistrationServiceDescStats =
-                insertAtRandomPlace(mAtoms.imsRegistrationServiceDescStats,
-                    stats, mMaxNumImsRegistrationServiceDescStats);
-        }
-        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
-    }
-
-    /** Adds a new {@link UceEventStats} to the storage. */
-    public synchronized void addUceEventStats(UceEventStats stats) {
-        UceEventStats existingStats = find(stats);
-        if (existingStats != null) {
-            existingStats.count += 1;
-        } else {
-            mAtoms.uceEventStats =
-                insertAtRandomPlace(mAtoms.uceEventStats, stats, mMaxNumUceEventStats);
-        }
-        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
-    }
-
-    /** Adds a new {@link PresenceNotifyEvent} to the storage. */
-    public synchronized void addPresenceNotifyEvent(PresenceNotifyEvent stats) {
-        PresenceNotifyEvent existingStats = find(stats);
-        if (existingStats != null) {
-            existingStats.rcsCapsCount += stats.rcsCapsCount;
-            existingStats.mmtelCapsCount += stats.mmtelCapsCount;
-            existingStats.noCapsCount += stats.noCapsCount;
-            existingStats.count += stats.count;
-        } else {
-            mAtoms.presenceNotifyEvent =
-                insertAtRandomPlace(mAtoms.presenceNotifyEvent, stats,
-                        mMaxNumPresenceNotifyEventStats);
-        }
-        saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
-    }
-
-    /** Adds a new {@link GbaEvent} to the storage. */
-    public synchronized void addGbaEvent(GbaEvent stats) {
-        GbaEvent existingStats = find(stats);
-        if (existingStats != null) {
-            existingStats.count += 1;
-        } else {
-            mAtoms.gbaEvent =
-                insertAtRandomPlace(mAtoms.gbaEvent, stats, mMaxNumGbaEventStats);
+            int newLength = mAtoms.networkRequests.length + 1;
+            mAtoms.networkRequests = Arrays.copyOf(mAtoms.networkRequests, newLength);
+            mAtoms.networkRequests[newLength - 1] = networkRequests;
         }
         saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_UPDATE_MILLIS);
     }
@@ -681,10 +394,6 @@
             DataCallSession[] previousDataCallSession = mAtoms.dataCallSession;
             mAtoms.dataCallSession = new DataCallSession[0];
             saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            for (DataCallSession dataCallSession : previousDataCallSession) {
-                // sort to de-correlate any potential pattern for UII concern
-                Arrays.sort(dataCallSession.handoverFailureCauses);
-            }
             return previousDataCallSession;
         } else {
             return null;
@@ -732,20 +441,19 @@
     }
 
     /**
-     * Returns and clears the IMS registration statistics normalized to 24h cycle if last
-     * pulled longer than {@code minIntervalMillis} ago, otherwise returns {@code null}.
+     * Returns and clears the IMS registration statistics if last pulled longer than {@code
+     * minIntervalMillis} ago, otherwise returns {@code null}.
      */
     @Nullable
     public synchronized ImsRegistrationStats[] getImsRegistrationStats(long minIntervalMillis) {
-        long intervalMillis =
-                getWallTimeMillis() - mAtoms.imsRegistrationStatsPullTimestampMillis;
-        if (intervalMillis > minIntervalMillis) {
+        if (getWallTimeMillis() - mAtoms.imsRegistrationStatsPullTimestampMillis
+                > minIntervalMillis) {
             mAtoms.imsRegistrationStatsPullTimestampMillis = getWallTimeMillis();
             ImsRegistrationStats[] previousStats = mAtoms.imsRegistrationStats;
             Arrays.stream(previousStats).forEach(stats -> stats.lastUsedMillis = 0L);
             mAtoms.imsRegistrationStats = new ImsRegistrationStats[0];
             saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return normalizeData(previousStats, intervalMillis);
+            return previousStats;
         } else {
             return null;
         }
@@ -777,11 +485,11 @@
      * minIntervalMillis} ago, otherwise returns {@code null}.
      */
     @Nullable
-    public synchronized NetworkRequestsV2[] getNetworkRequestsV2(long minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.networkRequestsV2PullTimestampMillis > minIntervalMillis) {
-            mAtoms.networkRequestsV2PullTimestampMillis = getWallTimeMillis();
-            NetworkRequestsV2[] previousNetworkRequests = mAtoms.networkRequestsV2;
-            mAtoms.networkRequestsV2 = new NetworkRequestsV2[0];
+    public synchronized NetworkRequests[] getNetworkRequests(long minIntervalMillis) {
+        if (getWallTimeMillis() - mAtoms.networkRequestsPullTimestampMillis > minIntervalMillis) {
+            mAtoms.networkRequestsPullTimestampMillis = getWallTimeMillis();
+            NetworkRequests[] previousNetworkRequests = mAtoms.networkRequests;
+            mAtoms.networkRequests = new NetworkRequests[0];
             saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
             return previousNetworkRequests;
         } else {
@@ -789,259 +497,6 @@
         }
     }
 
-    /**
-     * Returns and clears the ImsRegistrationFeatureTagStats if last pulled longer than {@code
-     * minIntervalMillis} ago, otherwise returns {@code null}.
-     */
-    @Nullable
-    public synchronized ImsRegistrationFeatureTagStats[] getImsRegistrationFeatureTagStats(
-            long minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.imsRegistrationFeatureTagStatsPullTimestampMillis
-                > minIntervalMillis) {
-            mAtoms.imsRegistrationFeatureTagStatsPullTimestampMillis = getWallTimeMillis();
-            ImsRegistrationFeatureTagStats[] previousStats =
-                    mAtoms.imsRegistrationFeatureTagStats;
-            mAtoms.imsRegistrationFeatureTagStats = new ImsRegistrationFeatureTagStats[0];
-            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return previousStats;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns and clears the RcsClientProvisioningStats if last pulled longer than {@code
-     * minIntervalMillis} ago, otherwise returns {@code null}.
-     */
-    @Nullable
-    public synchronized RcsClientProvisioningStats[] getRcsClientProvisioningStats(
-            long minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.rcsClientProvisioningStatsPullTimestampMillis
-                > minIntervalMillis) {
-            mAtoms.rcsClientProvisioningStatsPullTimestampMillis = getWallTimeMillis();
-            RcsClientProvisioningStats[] previousStats = mAtoms.rcsClientProvisioningStats;
-            mAtoms.rcsClientProvisioningStats = new RcsClientProvisioningStats[0];
-            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return previousStats;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns and clears the RcsAcsProvisioningStats if last pulled longer than {@code
-     * minIntervalMillis} ago, otherwise returns {@code null}.
-     */
-    @Nullable
-    public synchronized RcsAcsProvisioningStats[] getRcsAcsProvisioningStats(
-            long minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.rcsAcsProvisioningStatsPullTimestampMillis
-                > minIntervalMillis) {
-            mAtoms.rcsAcsProvisioningStatsPullTimestampMillis = getWallTimeMillis();
-            RcsAcsProvisioningStats[] previousStats = mAtoms.rcsAcsProvisioningStats;
-            mAtoms.rcsAcsProvisioningStats = new RcsAcsProvisioningStats[0];
-            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return previousStats;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns and clears the SipDelegateStats if last pulled longer than {@code
-     * minIntervalMillis} ago, otherwise returns {@code null}.
-     */
-    @Nullable
-    public synchronized SipDelegateStats[] getSipDelegateStats(long minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.sipDelegateStatsPullTimestampMillis
-                > minIntervalMillis) {
-            mAtoms.sipDelegateStatsPullTimestampMillis = getWallTimeMillis();
-            SipDelegateStats[] previousStats = mAtoms.sipDelegateStats;
-            mAtoms.sipDelegateStats = new SipDelegateStats[0];
-            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return previousStats;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns and clears the SipTransportFeatureTagStats if last pulled longer than {@code
-     * minIntervalMillis} ago, otherwise returns {@code null}.
-     */
-    @Nullable
-    public synchronized SipTransportFeatureTagStats[] getSipTransportFeatureTagStats(
-            long minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.sipTransportFeatureTagStatsPullTimestampMillis
-                > minIntervalMillis) {
-            mAtoms.sipTransportFeatureTagStatsPullTimestampMillis = getWallTimeMillis();
-            SipTransportFeatureTagStats[] previousStats = mAtoms.sipTransportFeatureTagStats;
-            mAtoms.sipTransportFeatureTagStats = new SipTransportFeatureTagStats[0];
-            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return previousStats;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns and clears the SipMessageResponse if last pulled longer than {@code
-     * minIntervalMillis} ago, otherwise returns {@code null}.
-     */
-    @Nullable
-    public synchronized SipMessageResponse[] getSipMessageResponse(long minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.sipMessageResponsePullTimestampMillis
-                > minIntervalMillis) {
-            mAtoms.sipMessageResponsePullTimestampMillis = getWallTimeMillis();
-            SipMessageResponse[] previousStats =
-                    mAtoms.sipMessageResponse;
-            mAtoms.sipMessageResponse = new SipMessageResponse[0];
-            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return previousStats;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns and clears the SipTransportSession if last pulled longer than {@code
-     * minIntervalMillis} ago, otherwise returns {@code null}.
-     */
-    @Nullable
-    public synchronized SipTransportSession[] getSipTransportSession(long minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.sipTransportSessionPullTimestampMillis
-                > minIntervalMillis) {
-            mAtoms.sipTransportSessionPullTimestampMillis = getWallTimeMillis();
-            SipTransportSession[] previousStats =
-                    mAtoms.sipTransportSession;
-            mAtoms.sipTransportSession = new SipTransportSession[0];
-            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return previousStats;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns and clears the ImsDedicatedBearerListenerEvent if last pulled longer than {@code
-     * minIntervalMillis} ago, otherwise returns {@code null}.
-     */
-    @Nullable
-    public synchronized ImsDedicatedBearerListenerEvent[] getImsDedicatedBearerListenerEvent(
-            long minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.imsDedicatedBearerListenerEventPullTimestampMillis
-                > minIntervalMillis) {
-            mAtoms.imsDedicatedBearerListenerEventPullTimestampMillis = getWallTimeMillis();
-            ImsDedicatedBearerListenerEvent[] previousStats =
-                mAtoms.imsDedicatedBearerListenerEvent;
-            mAtoms.imsDedicatedBearerListenerEvent = new ImsDedicatedBearerListenerEvent[0];
-            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return previousStats;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns and clears the ImsDedicatedBearerEvent if last pulled longer than {@code
-     * minIntervalMillis} ago, otherwise returns {@code null}.
-     */
-    @Nullable
-    public synchronized ImsDedicatedBearerEvent[] getImsDedicatedBearerEvent(
-            long minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.imsDedicatedBearerEventPullTimestampMillis
-                  > minIntervalMillis) {
-            mAtoms.imsDedicatedBearerEventPullTimestampMillis = getWallTimeMillis();
-            ImsDedicatedBearerEvent[] previousStats =
-                mAtoms.imsDedicatedBearerEvent;
-            mAtoms.imsDedicatedBearerEvent = new ImsDedicatedBearerEvent[0];
-            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return previousStats;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns and clears the ImsRegistrationServiceDescStats if last pulled longer than {@code
-     * minIntervalMillis} ago, otherwise returns {@code null}.
-     */
-    @Nullable
-    public synchronized ImsRegistrationServiceDescStats[] getImsRegistrationServiceDescStats(long
-            minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.imsRegistrationServiceDescStatsPullTimestampMillis
-                > minIntervalMillis) {
-            mAtoms.imsRegistrationServiceDescStatsPullTimestampMillis = getWallTimeMillis();
-            ImsRegistrationServiceDescStats[] previousStats =
-                mAtoms.imsRegistrationServiceDescStats;
-            mAtoms.imsRegistrationServiceDescStats = new ImsRegistrationServiceDescStats[0];
-            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return previousStats;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns and clears the UceEventStats if last pulled longer than {@code
-     * minIntervalMillis} ago, otherwise returns {@code null}.
-     */
-    @Nullable
-    public synchronized UceEventStats[] getUceEventStats(long minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.uceEventStatsPullTimestampMillis > minIntervalMillis) {
-            mAtoms.uceEventStatsPullTimestampMillis = getWallTimeMillis();
-            UceEventStats[] previousStats = mAtoms.uceEventStats;
-            mAtoms.uceEventStats = new UceEventStats[0];
-            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return previousStats;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns and clears the PresenceNotifyEvent if last pulled longer than {@code
-     * minIntervalMillis} ago, otherwise returns {@code null}.
-     */
-    @Nullable
-    public synchronized PresenceNotifyEvent[] getPresenceNotifyEvent(long minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.presenceNotifyEventPullTimestampMillis
-                > minIntervalMillis) {
-            mAtoms.presenceNotifyEventPullTimestampMillis = getWallTimeMillis();
-            PresenceNotifyEvent[] previousStats = mAtoms.presenceNotifyEvent;
-            mAtoms.presenceNotifyEvent = new PresenceNotifyEvent[0];
-            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return previousStats;
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Returns and clears the GbaEvent if last pulled longer than {@code
-     * minIntervalMillis} ago, otherwise returns {@code null}.
-     */
-    @Nullable
-    public synchronized GbaEvent[] getGbaEvent(long minIntervalMillis) {
-        if (getWallTimeMillis() - mAtoms.gbaEventPullTimestampMillis > minIntervalMillis) {
-            mAtoms.gbaEventPullTimestampMillis = getWallTimeMillis();
-            GbaEvent[] previousStats = mAtoms.gbaEvent;
-            mAtoms.gbaEvent = new GbaEvent[0];
-            saveAtomsToFile(SAVE_TO_FILE_DELAY_FOR_GET_MILLIS);
-            return previousStats;
-        } else {
-            return null;
-        }
-    }
-
-    /** Saves a pending {@link PersistAtoms} to a file in private storage immediately. */
-    public void flushAtoms() {
-        if (mHandler.hasCallbacks(mSaveRunnable)) {
-            mHandler.removeCallbacks(mSaveRunnable);
-            saveAtomsToFileNow();
-        }
-    }
-
     /** Loads {@link PersistAtoms} from a file in private storage. */
     private PersistAtoms loadAtomsFromFile() {
         try {
@@ -1059,109 +514,40 @@
                     sanitizeAtoms(atoms.voiceCallRatUsage, VoiceCallRatUsage.class);
             atoms.voiceCallSession =
                     sanitizeAtoms(
-                            atoms.voiceCallSession,
-                            VoiceCallSession.class,
-                            mMaxNumVoiceCallSessions);
-            atoms.incomingSms = sanitizeAtoms(atoms.incomingSms, IncomingSms.class, mMaxNumSms);
-            atoms.outgoingSms = sanitizeAtoms(atoms.outgoingSms, OutgoingSms.class, mMaxNumSms);
+                            atoms.voiceCallSession, VoiceCallSession.class, MAX_NUM_CALL_SESSIONS);
+            atoms.incomingSms = sanitizeAtoms(atoms.incomingSms, IncomingSms.class, MAX_NUM_SMS);
+            atoms.outgoingSms = sanitizeAtoms(atoms.outgoingSms, OutgoingSms.class, MAX_NUM_SMS);
             atoms.carrierIdMismatch =
                     sanitizeAtoms(
                             atoms.carrierIdMismatch,
                             CarrierIdMismatch.class,
-                            mMaxNumCarrierIdMismatches);
+                            MAX_CARRIER_ID_MISMATCH);
             atoms.dataCallSession =
                     sanitizeAtoms(
                             atoms.dataCallSession,
                             DataCallSession.class,
-                            mMaxNumDataCallSessions);
+                            MAX_NUM_DATA_CALL_SESSIONS);
             atoms.cellularServiceState =
                     sanitizeAtoms(
                             atoms.cellularServiceState,
                             CellularServiceState.class,
-                            mMaxNumCellularServiceStates);
+                            MAX_NUM_CELLULAR_SERVICE_STATES);
             atoms.cellularDataServiceSwitch =
                     sanitizeAtoms(
                             atoms.cellularDataServiceSwitch,
                             CellularDataServiceSwitch.class,
-                            mMaxNumCellularDataSwitches);
+                            MAX_NUM_CELLULAR_DATA_SERVICE_SWITCHES);
             atoms.imsRegistrationStats =
                     sanitizeAtoms(
                             atoms.imsRegistrationStats,
                             ImsRegistrationStats.class,
-                            mMaxNumImsRegistrationStats);
+                            MAX_NUM_IMS_REGISTRATION_STATS);
             atoms.imsRegistrationTermination =
                     sanitizeAtoms(
                             atoms.imsRegistrationTermination,
                             ImsRegistrationTermination.class,
-                            mMaxNumImsRegistrationTerminations);
-            atoms.networkRequestsV2 =
-                    sanitizeAtoms(atoms.networkRequestsV2, NetworkRequestsV2.class);
-            atoms.imsRegistrationFeatureTagStats =
-                    sanitizeAtoms(
-                            atoms.imsRegistrationFeatureTagStats,
-                            ImsRegistrationFeatureTagStats.class,
-                            mMaxNumImsRegistrationFeatureStats);
-            atoms.rcsClientProvisioningStats =
-                    sanitizeAtoms(
-                            atoms.rcsClientProvisioningStats,
-                            RcsClientProvisioningStats.class,
-                            mMaxNumRcsClientProvisioningStats);
-            atoms.rcsAcsProvisioningStats =
-                    sanitizeAtoms(
-                            atoms.rcsAcsProvisioningStats,
-                            RcsAcsProvisioningStats.class,
-                            mMaxNumRcsAcsProvisioningStats);
-            atoms.sipDelegateStats =
-                    sanitizeAtoms(
-                            atoms.sipDelegateStats,
-                            SipDelegateStats.class,
-                            mMaxNumSipDelegateStats);
-            atoms.sipTransportFeatureTagStats =
-                    sanitizeAtoms(
-                            atoms.sipTransportFeatureTagStats,
-                            SipTransportFeatureTagStats.class,
-                            mMaxNumSipTransportFeatureTagStats);
-            atoms.sipMessageResponse =
-                    sanitizeAtoms(
-                            atoms.sipMessageResponse,
-                            SipMessageResponse.class,
-                            mMaxNumSipMessageResponseStats);
-            atoms.sipTransportSession =
-                    sanitizeAtoms(
-                            atoms.sipTransportSession,
-                            SipTransportSession.class,
-                            mMaxNumSipTransportSessionStats);
-            atoms.imsDedicatedBearerListenerEvent =
-                    sanitizeAtoms(
-                            atoms.imsDedicatedBearerListenerEvent,
-                            ImsDedicatedBearerListenerEvent.class,
-                            mMaxNumDedicatedBearerListenerEventStats);
-            atoms.imsDedicatedBearerEvent =
-                    sanitizeAtoms(
-                            atoms.imsDedicatedBearerEvent,
-                            ImsDedicatedBearerEvent.class,
-                            mMaxNumDedicatedBearerEventStats);
-            atoms.imsRegistrationServiceDescStats =
-                    sanitizeAtoms(
-                            atoms.imsRegistrationServiceDescStats,
-                            ImsRegistrationServiceDescStats.class,
-                            mMaxNumImsRegistrationServiceDescStats);
-            atoms.uceEventStats =
-                    sanitizeAtoms(
-                            atoms.uceEventStats,
-                            UceEventStats.class,
-                            mMaxNumUceEventStats);
-            atoms.presenceNotifyEvent =
-                    sanitizeAtoms(
-                            atoms.presenceNotifyEvent,
-                            PresenceNotifyEvent.class,
-                            mMaxNumPresenceNotifyEventStats);
-            atoms.gbaEvent =
-                    sanitizeAtoms(
-                            atoms.gbaEvent,
-                            GbaEvent.class,
-                            mMaxNumGbaEventStats);
-
+                            MAX_NUM_IMS_REGISTRATION_TERMINATIONS);
+            atoms.networkRequests = sanitizeAtoms(atoms.networkRequests, NetworkRequests.class);
             // out of caution, sanitize also the timestamps
             atoms.voiceCallRatUsagePullTimestampMillis =
                     sanitizeTimestamp(atoms.voiceCallRatUsagePullTimestampMillis);
@@ -1181,35 +567,8 @@
                     sanitizeTimestamp(atoms.imsRegistrationStatsPullTimestampMillis);
             atoms.imsRegistrationTerminationPullTimestampMillis =
                     sanitizeTimestamp(atoms.imsRegistrationTerminationPullTimestampMillis);
-            atoms.networkRequestsV2PullTimestampMillis =
-                    sanitizeTimestamp(atoms.networkRequestsV2PullTimestampMillis);
-            atoms.imsRegistrationFeatureTagStatsPullTimestampMillis =
-                    sanitizeTimestamp(atoms.imsRegistrationFeatureTagStatsPullTimestampMillis);
-            atoms.rcsClientProvisioningStatsPullTimestampMillis =
-                    sanitizeTimestamp(atoms.rcsClientProvisioningStatsPullTimestampMillis);
-            atoms.rcsAcsProvisioningStatsPullTimestampMillis =
-                    sanitizeTimestamp(atoms.rcsAcsProvisioningStatsPullTimestampMillis);
-            atoms.sipDelegateStatsPullTimestampMillis =
-                    sanitizeTimestamp(atoms.sipDelegateStatsPullTimestampMillis);
-            atoms.sipTransportFeatureTagStatsPullTimestampMillis =
-                    sanitizeTimestamp(atoms.sipTransportFeatureTagStatsPullTimestampMillis);
-            atoms.sipMessageResponsePullTimestampMillis =
-                    sanitizeTimestamp(atoms.sipMessageResponsePullTimestampMillis);
-            atoms.sipTransportSessionPullTimestampMillis =
-                    sanitizeTimestamp(atoms.sipTransportSessionPullTimestampMillis);
-            atoms.imsDedicatedBearerListenerEventPullTimestampMillis =
-                    sanitizeTimestamp(atoms.imsDedicatedBearerListenerEventPullTimestampMillis);
-            atoms.imsDedicatedBearerEventPullTimestampMillis =
-                    sanitizeTimestamp(atoms.imsDedicatedBearerEventPullTimestampMillis);
-            atoms.imsRegistrationServiceDescStatsPullTimestampMillis =
-                    sanitizeTimestamp(atoms.imsRegistrationServiceDescStatsPullTimestampMillis);
-            atoms.uceEventStatsPullTimestampMillis =
-                    sanitizeTimestamp(atoms.uceEventStatsPullTimestampMillis);
-            atoms.presenceNotifyEventPullTimestampMillis =
-                    sanitizeTimestamp(atoms.presenceNotifyEventPullTimestampMillis);
-            atoms.gbaEventPullTimestampMillis =
-                    sanitizeTimestamp(atoms.gbaEventPullTimestampMillis);
-
+            atoms.networkRequestsPullTimestampMillis =
+                    sanitizeTimestamp(atoms.networkRequestsPullTimestampMillis);
             return atoms;
         } catch (NoSuchFileException e) {
             Rlog.d(TAG, "PersistAtoms file not found");
@@ -1258,8 +617,7 @@
                     && state.isEndc == key.isEndc
                     && state.simSlotIndex == key.simSlotIndex
                     && state.isMultiSim == key.isMultiSim
-                    && state.carrierId == key.carrierId
-                    && state.isEmergencyOnly == key.isEmergencyOnly) {
+                    && state.carrierId == key.carrierId) {
                 return state;
             }
         }
@@ -1334,12 +692,12 @@
     }
 
     /**
-     * Returns the network requests event that has the same carrier id and capability as the given
-     * one, or {@code null} if it does not exist.
+     * Returns the network requests event that has the same carrier id as the given one,
+     * or {@code null} if it does not exist.
      */
-    private @Nullable NetworkRequestsV2 find(NetworkRequestsV2 key) {
-        for (NetworkRequestsV2 item : mAtoms.networkRequestsV2) {
-            if (item.carrierId == key.carrierId && item.capability == key.capability) {
+    private @Nullable NetworkRequests find(NetworkRequests key) {
+        for (NetworkRequests item : mAtoms.networkRequests) {
+            if (item.carrierId == key.carrierId) {
                 return item;
             }
         }
@@ -1347,226 +705,6 @@
     }
 
     /**
-     * Returns the index of data call session that has the same random dimension as the given one,
-     * or -1 if it does not exist.
-     */
-    private int findIndex(DataCallSession key) {
-        for (int i = 0; i < mAtoms.dataCallSession.length; i++) {
-            if (mAtoms.dataCallSession[i].dimension == key.dimension) {
-                return i;
-            }
-        }
-        return -1;
-    }
-    /**
-     * Returns the Dedicated Bearer Listener event that has the same carrier id, slot id, rat, qci
-     * and established state as the given one, or {@code null} if it does not exist.
-     */
-    private @Nullable ImsDedicatedBearerListenerEvent find(ImsDedicatedBearerListenerEvent key) {
-        for (ImsDedicatedBearerListenerEvent stats : mAtoms.imsDedicatedBearerListenerEvent) {
-            if (stats.carrierId == key.carrierId
-                    && stats.slotId == key.slotId
-                    && stats.ratAtEnd == key.ratAtEnd
-                    && stats.qci == key.qci
-                    && stats.dedicatedBearerEstablished == key.dedicatedBearerEstablished) {
-                return stats;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the Dedicated Bearer event that has the same carrier id, slot id, rat,
-     * qci, bearer state, local/remote connection and exsting listener as the given one,
-     * or {@code null} if it does not exist.
-     */
-    private @Nullable ImsDedicatedBearerEvent find(ImsDedicatedBearerEvent key) {
-        for (ImsDedicatedBearerEvent stats : mAtoms.imsDedicatedBearerEvent) {
-            if (stats.carrierId == key.carrierId
-                    && stats.slotId == key.slotId
-                    && stats.ratAtEnd == key.ratAtEnd
-                    && stats.qci == key.qci
-                    && stats.bearerState == key.bearerState
-                    && stats.localConnectionInfoReceived == key.localConnectionInfoReceived
-                    && stats.remoteConnectionInfoReceived == key.remoteConnectionInfoReceived
-                    && stats.hasListeners == key.hasListeners) {
-                return stats;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns the Registration Feature Tag that has the same carrier id, slot id,
-     * feature tag name or custom feature tag name and registration tech as the given one,
-     * or {@code null} if it does not exist.
-     */
-    private @Nullable ImsRegistrationFeatureTagStats find(ImsRegistrationFeatureTagStats key) {
-        for (ImsRegistrationFeatureTagStats stats : mAtoms.imsRegistrationFeatureTagStats) {
-            if (stats.carrierId == key.carrierId
-                    && stats.slotId == key.slotId
-                    && stats.featureTagName == key.featureTagName
-                    && stats.registrationTech == key.registrationTech) {
-                return stats;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns Client Provisioning that has the same carrier id, slot id and event as the given
-     * one, or {@code null} if it does not exist.
-     */
-    private @Nullable RcsClientProvisioningStats find(RcsClientProvisioningStats key) {
-        for (RcsClientProvisioningStats stats : mAtoms.rcsClientProvisioningStats) {
-            if (stats.carrierId == key.carrierId
-                    && stats.slotId == key.slotId
-                    && stats.event == key.event) {
-                return stats;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns ACS Provisioning that has the same carrier id, slot id, response code, response type
-     * and SR supported as the given one, or {@code null} if it does not exist.
-     */
-    private @Nullable RcsAcsProvisioningStats find(RcsAcsProvisioningStats key) {
-        for (RcsAcsProvisioningStats stats : mAtoms.rcsAcsProvisioningStats) {
-            if (stats.carrierId == key.carrierId
-                    && stats.slotId == key.slotId
-                    && stats.responseCode == key.responseCode
-                    && stats.responseType == key.responseType
-                    && stats.isSingleRegistrationEnabled == key.isSingleRegistrationEnabled) {
-                return stats;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns Sip Message Response that has the same carrier id, slot id, method, response,
-     * direction and error as the given one, or {@code null} if it does not exist.
-     */
-    private @Nullable SipMessageResponse find(SipMessageResponse key) {
-        for (SipMessageResponse stats : mAtoms.sipMessageResponse) {
-            if (stats.carrierId == key.carrierId
-                    && stats.slotId == key.slotId
-                    && stats.sipMessageMethod == key.sipMessageMethod
-                    && stats.sipMessageResponse == key.sipMessageResponse
-                    && stats.sipMessageDirection == key.sipMessageDirection
-                    && stats.messageError == key.messageError) {
-                return stats;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns Sip Transport Session that has the same carrier id, slot id, method, direction and
-     * response as the given one, or {@code null} if it does not exist.
-     */
-    private @Nullable SipTransportSession find(SipTransportSession key) {
-        for (SipTransportSession stats : mAtoms.sipTransportSession) {
-            if (stats.carrierId == key.carrierId
-                    && stats.slotId == key.slotId
-                    && stats.sessionMethod == key.sessionMethod
-                    && stats.sipMessageDirection == key.sipMessageDirection
-                    && stats.sipResponse == key.sipResponse) {
-                return stats;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns Registration Service Desc Stats that has the same carrier id, slot id, service id or
-     * custom service id, service id version and registration tech as the given one,
-     * or {@code null} if it does not exist.
-     */
-    private @Nullable ImsRegistrationServiceDescStats find(ImsRegistrationServiceDescStats key) {
-        for (ImsRegistrationServiceDescStats stats : mAtoms.imsRegistrationServiceDescStats) {
-            if (stats.carrierId == key.carrierId
-                    && stats.slotId == key.slotId
-                    && stats.serviceIdName == key.serviceIdName
-                    && stats.serviceIdVersion == key.serviceIdVersion
-                    && stats.registrationTech == key.registrationTech) {
-                return stats;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns UCE Event Stats that has the same carrier id, slot id, event result, command code and
-     * network response as the given one, or {@code null} if it does not exist.
-     */
-    private @Nullable UceEventStats find(UceEventStats key) {
-        for (UceEventStats stats : mAtoms.uceEventStats) {
-            if (stats.carrierId == key.carrierId
-                    && stats.slotId == key.slotId
-                    && stats.type == key.type
-                    && stats.successful == key.successful
-                    && stats.commandCode == key.commandCode
-                    && stats.networkResponse == key.networkResponse) {
-                return stats;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns Presence Notify Event that has the same carrier id, slot id, reason and body in
-     * response as the given one, or {@code null} if it does not exist.
-     */
-    private @Nullable PresenceNotifyEvent find(PresenceNotifyEvent key) {
-        for (PresenceNotifyEvent stats : mAtoms.presenceNotifyEvent) {
-            if (stats.carrierId == key.carrierId
-                    && stats.slotId == key.slotId
-                    && stats.reason == key.reason
-                    && stats.contentBodyReceived == key.contentBodyReceived) {
-                return stats;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns GBA Event that has the same carrier id, slot id, result of operation and fail reason
-     * as the given one, or {@code null} if it does not exist.
-     */
-    private @Nullable GbaEvent find(GbaEvent key) {
-        for (GbaEvent stats : mAtoms.gbaEvent) {
-            if (stats.carrierId == key.carrierId
-                    && stats.slotId == key.slotId
-                    && stats.successful == key.successful
-                    && stats.failedReason == key.failedReason) {
-                return stats;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Returns Sip Transport Feature Tag Stats that has the same carrier id, slot id, feature tag
-     * name, deregister reason, denied reason and feature tag name or custom feature tag name as
-     * the given one, or {@code null} if it does not exist.
-     */
-    private @Nullable SipTransportFeatureTagStats find(SipTransportFeatureTagStats key) {
-        for (SipTransportFeatureTagStats stat: mAtoms.sipTransportFeatureTagStats) {
-            if (stat.carrierId == key.carrierId
-                    && stat.slotId == key.slotId
-                    && stat.featureTagName == key.featureTagName
-                    && stat.sipTransportDeregisteredReason == key.sipTransportDeregisteredReason
-                    && stat.sipTransportDeniedReason == key.sipTransportDeniedReason) {
-                return stat;
-            }
-        }
-        return null;
-    }
-
-    /**
      * Inserts a new element in a random position in an array with a maximum size, replacing the
      * least recent item if possible.
      */
@@ -1590,7 +728,6 @@
     /** Returns index of the item suitable for eviction when the array is full. */
     private static <T> int findItemToEvict(T[] array) {
         if (array instanceof CellularServiceState[]) {
-            // Evict the item that was used least recently
             CellularServiceState[] arr = (CellularServiceState[]) array;
             return IntStream.range(0, arr.length)
                     .reduce((i, j) -> arr[i].lastUsedMillis < arr[j].lastUsedMillis ? i : j)
@@ -1598,7 +735,6 @@
         }
 
         if (array instanceof CellularDataServiceSwitch[]) {
-            // Evict the item that was used least recently
             CellularDataServiceSwitch[] arr = (CellularDataServiceSwitch[]) array;
             return IntStream.range(0, arr.length)
                     .reduce((i, j) -> arr[i].lastUsedMillis < arr[j].lastUsedMillis ? i : j)
@@ -1606,7 +742,6 @@
         }
 
         if (array instanceof ImsRegistrationStats[]) {
-            // Evict the item that was used least recently
             ImsRegistrationStats[] arr = (ImsRegistrationStats[]) array;
             return IntStream.range(0, arr.length)
                     .reduce((i, j) -> arr[i].lastUsedMillis < arr[j].lastUsedMillis ? i : j)
@@ -1614,26 +749,12 @@
         }
 
         if (array instanceof ImsRegistrationTermination[]) {
-            // Evict the item that was used least recently
             ImsRegistrationTermination[] arr = (ImsRegistrationTermination[]) array;
             return IntStream.range(0, arr.length)
                     .reduce((i, j) -> arr[i].lastUsedMillis < arr[j].lastUsedMillis ? i : j)
                     .getAsInt();
         }
 
-        if (array instanceof VoiceCallSession[]) {
-            // For voice calls, try to keep emergency calls over regular calls.
-            VoiceCallSession[] arr = (VoiceCallSession[]) array;
-            int[] nonEmergencyCallIndexes = IntStream.range(0, arr.length)
-                    .filter(i -> !arr[i].isEmergency)
-                    .toArray();
-            if (nonEmergencyCallIndexes.length > 0) {
-                return nonEmergencyCallIndexes[sRandom.nextInt(nonEmergencyCallIndexes.length)];
-            }
-            // If all calls in the storage are emergency calls, proceed with default case
-            // even if the new call is not an emergency call.
-        }
-
         return sRandom.nextInt(array.length);
     }
 
@@ -1656,41 +777,6 @@
         return timestamp <= 0L ? getWallTimeMillis() : timestamp;
     }
 
-    /**
-     * Returns {@link ImsRegistrationStats} array with durations normalized to 24 hours
-     * depending on the interval.
-     */
-    private ImsRegistrationStats[] normalizeData(ImsRegistrationStats[] stats,
-            long intervalMillis) {
-        for (int i = 0; i < stats.length; i++) {
-            stats[i].registeredMillis =
-                    normalizeDurationTo24H(stats[i].registeredMillis, intervalMillis);
-            stats[i].voiceCapableMillis =
-                    normalizeDurationTo24H(stats[i].voiceCapableMillis, intervalMillis);
-            stats[i].voiceAvailableMillis =
-                    normalizeDurationTo24H(stats[i].voiceAvailableMillis, intervalMillis);
-            stats[i].smsCapableMillis =
-                    normalizeDurationTo24H(stats[i].smsCapableMillis, intervalMillis);
-            stats[i].smsAvailableMillis =
-                    normalizeDurationTo24H(stats[i].smsAvailableMillis, intervalMillis);
-            stats[i].videoCapableMillis =
-                    normalizeDurationTo24H(stats[i].videoCapableMillis, intervalMillis);
-            stats[i].videoAvailableMillis =
-                    normalizeDurationTo24H(stats[i].videoAvailableMillis, intervalMillis);
-            stats[i].utCapableMillis =
-                    normalizeDurationTo24H(stats[i].utCapableMillis, intervalMillis);
-            stats[i].utAvailableMillis =
-                    normalizeDurationTo24H(stats[i].utAvailableMillis, intervalMillis);
-        }
-        return stats;
-    }
-
-    /** Returns a duration normalized to 24 hours. */
-    private long normalizeDurationTo24H(long timeInMillis, long intervalMillis) {
-        long interval = intervalMillis < 1000 ? 1 : intervalMillis / 1000;
-        return ((timeInMillis / 1000) * (DAY_IN_MILLIS / 1000) / interval) * 1000;
-    }
-
     /** Returns an empty PersistAtoms with pull timestamp set to current time. */
     private PersistAtoms makeNewPersistAtoms() {
         PersistAtoms atoms = new PersistAtoms();
@@ -1708,21 +794,6 @@
         atoms.imsRegistrationStatsPullTimestampMillis = currentTime;
         atoms.imsRegistrationTerminationPullTimestampMillis = currentTime;
         atoms.networkRequestsPullTimestampMillis = currentTime;
-        atoms.networkRequestsV2PullTimestampMillis = currentTime;
-        atoms.imsRegistrationFeatureTagStatsPullTimestampMillis = currentTime;
-        atoms.rcsClientProvisioningStatsPullTimestampMillis = currentTime;
-        atoms.rcsAcsProvisioningStatsPullTimestampMillis = currentTime;
-        atoms.sipDelegateStatsPullTimestampMillis = currentTime;
-        atoms.sipTransportFeatureTagStatsPullTimestampMillis = currentTime;
-        atoms.sipMessageResponsePullTimestampMillis = currentTime;
-        atoms.sipTransportSessionPullTimestampMillis = currentTime;
-        atoms.imsDedicatedBearerListenerEventPullTimestampMillis = currentTime;
-        atoms.imsDedicatedBearerEventPullTimestampMillis = currentTime;
-        atoms.imsRegistrationServiceDescStatsPullTimestampMillis = currentTime;
-        atoms.uceEventStatsPullTimestampMillis = currentTime;
-        atoms.presenceNotifyEventPullTimestampMillis = currentTime;
-        atoms.gbaEventPullTimestampMillis = currentTime;
-
         Rlog.d(TAG, "created new PersistAtoms");
         return atoms;
     }
diff --git a/src/java/com/android/internal/telephony/metrics/RcsStats.java b/src/java/com/android/internal/telephony/metrics/RcsStats.java
deleted file mode 100644
index de77b12..0000000
--- a/src/java/com/android/internal/telephony/metrics/RcsStats.java
+++ /dev/null
@@ -1,1860 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.metrics;
-
-import static android.text.format.DateUtils.SECOND_IN_MILLIS;
-
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CALL_COMPOSER;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHATBOT;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHATBOT_ROLE;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHATBOT_STANDALONE;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHAT_V1;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHAT_V2;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CUSTOM;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_FT;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_FT_OVER_SMS;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_GEO_PUSH;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_GEO_PUSH_VIA_SMS;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_MMTEL;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_POST_CALL;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_SHARED_MAP;
-import static com.android.internal.telephony.TelephonyStatsLog.IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_SHARED_SKETCH;
-import static com.android.internal.telephony.TelephonyStatsLog.PRESENCE_NOTIFY_EVENT__REASON__REASON_CUSTOM;
-import static com.android.internal.telephony.TelephonyStatsLog.PRESENCE_NOTIFY_EVENT__REASON__REASON_DEACTIVATED;
-import static com.android.internal.telephony.TelephonyStatsLog.PRESENCE_NOTIFY_EVENT__REASON__REASON_GIVEUP;
-import static com.android.internal.telephony.TelephonyStatsLog.PRESENCE_NOTIFY_EVENT__REASON__REASON_NORESOURCE;
-import static com.android.internal.telephony.TelephonyStatsLog.PRESENCE_NOTIFY_EVENT__REASON__REASON_PROBATION;
-import static com.android.internal.telephony.TelephonyStatsLog.PRESENCE_NOTIFY_EVENT__REASON__REASON_REJECTED;
-import static com.android.internal.telephony.TelephonyStatsLog.PRESENCE_NOTIFY_EVENT__REASON__REASON_TIMEOUT;
-import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR;
-import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PRE_PROVISIONING_XML;
-import static com.android.internal.telephony.TelephonyStatsLog.UCE_EVENT_STATS__TYPE__INCOMING_OPTION;
-import static com.android.internal.telephony.TelephonyStatsLog.UCE_EVENT_STATS__TYPE__OUTGOING_OPTION;
-import static com.android.internal.telephony.TelephonyStatsLog.UCE_EVENT_STATS__TYPE__PUBLISH;
-import static com.android.internal.telephony.TelephonyStatsLog.UCE_EVENT_STATS__TYPE__SUBSCRIBE;
-
-import android.annotation.NonNull;
-import android.os.Binder;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
-import android.telephony.TelephonyProtoEnums;
-import android.telephony.ims.FeatureTagState;
-import android.telephony.ims.RcsContactPresenceTuple;
-import android.telephony.ims.RcsContactUceCapability;
-import android.telephony.ims.aidl.IRcsConfigCallback;
-import android.util.Base64;
-import android.util.IndentingPrintWriter;
-
-import com.android.ims.rcs.uce.UceStatsWriter;
-import com.android.ims.rcs.uce.UceStatsWriter.UceStatsCallback;
-import com.android.ims.rcs.uce.util.FeatureTags;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.nano.PersistAtomsProto;
-import com.android.internal.telephony.nano.PersistAtomsProto.GbaEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerListenerEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationFeatureTagStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationServiceDescStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.RcsClientProvisioningStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipDelegateStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipMessageResponse;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportFeatureTagStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportSession;
-import com.android.internal.telephony.nano.PersistAtomsProto.UceEventStats;
-import com.android.telephony.Rlog;
-
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.Set;
-
-/** Tracks RCS provisioning, sip transport, UCE metrics for phone. */
-public class RcsStats {
-    private static final String TAG = RcsStats.class.getSimpleName();
-    private static final long MIN_DURATION_MILLIS = 1L * SECOND_IN_MILLIS;
-    private final PersistAtomsStorage mAtomsStorage =
-            PhoneFactory.getMetricsCollector().getAtomsStorage();
-    private static final Random RANDOM = new Random();
-
-    private UceStatsWriterCallback mCallback;
-    private static RcsStats sInstance;
-
-    public static final int NONE = -1;
-    public static final int STATE_REGISTERED = 0;
-    public static final int STATE_DEREGISTERED = 1;
-    public static final int STATE_DENIED = 2;
-
-    private static final String SIP_REQUEST_MESSAGE_TYPE_INVITE = "INVITE";
-    private static final String SIP_REQUEST_MESSAGE_TYPE_ACK = "ACK";
-    private static final String SIP_REQUEST_MESSAGE_TYPE_OPTIONS = "OPTIONS";
-    private static final String SIP_REQUEST_MESSAGE_TYPE_BYE = "BYE";
-    private static final String SIP_REQUEST_MESSAGE_TYPE_CANCEL = "CANCEL";
-    private static final String SIP_REQUEST_MESSAGE_TYPE_REGISTER = "REGISTER";
-    private static final String SIP_REQUEST_MESSAGE_TYPE_PRACK = "PRACK";
-    private static final String SIP_REQUEST_MESSAGE_TYPE_SUBSCRIBE = "SUBSCRIBE";
-    private static final String SIP_REQUEST_MESSAGE_TYPE_NOTIFY = "NOTIFY";
-    private static final String SIP_REQUEST_MESSAGE_TYPE_PUBLISH = "PUBLISH";
-    private static final String SIP_REQUEST_MESSAGE_TYPE_INFO = "INFO";
-    private static final String SIP_REQUEST_MESSAGE_TYPE_REFER = "REFER";
-    private static final String SIP_REQUEST_MESSAGE_TYPE_MESSAGE = "MESSAGE";
-    private static final String SIP_REQUEST_MESSAGE_TYPE_UPDATE = "UPDATE";
-
-    /**
-     * Describe Feature Tags
-     * See frameworks/opt/net/ims/src/java/com/android/ims/rcs/uce/util/FeatureTags.java
-     * and int value matching the Feature Tags
-     * See stats/enums/telephony/enums.proto
-     */
-    private static final Map<String, Integer> FEATURE_TAGS = new HashMap<>();
-
-    static {
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_STANDALONE_MSG.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_STANDALONE_MSG);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_CHAT_IM.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_CHAT_IM);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_CHAT_SESSION.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_CHAT_SESSION);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_FILE_TRANSFER.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_FILE_TRANSFER);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_FILE_TRANSFER_VIA_SMS.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_FILE_TRANSFER_VIA_SMS);
-        FEATURE_TAGS.put(
-                FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING);
-        FEATURE_TAGS.put(
-                FeatureTags.FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_CALL_COMPOSER_VIA_TELEPHONY);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_POST_CALL.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_POST_CALL);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_SHARED_MAP.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_SHARED_MAP);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_SHARED_SKETCH.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_SHARED_SKETCH);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_GEO_PUSH.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_GEO_PUSH);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_GEO_PUSH_VIA_SMS.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_GEO_PUSH_VIA_SMS);
-        FEATURE_TAGS.put(
-                FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION);
-        String FeatureTag = FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG;
-        FEATURE_TAGS.put(FeatureTag.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG);
-        FEATURE_TAGS.put(
-                FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_CHATBOT_VERSION_SUPPORTED);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_CHATBOT_ROLE.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_CHATBOT_ROLE);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_MMTEL.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_MMTEL);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_VIDEO.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_VIDEO);
-        FEATURE_TAGS.put(FeatureTags.FEATURE_TAG_PRESENCE.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_PRESENCE);
-    }
-
-    /**
-     * Describe Service IDs
-     * See frameworks/base/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
-     * and int value matching the service IDs
-     * See frameworks/proto_logging/stats/atoms.proto
-     */
-    private static final Map<String, Integer> SERVICE_IDS = new HashMap<>();
-
-    static {
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_MMTEL.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_MMTEL);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHAT_V1.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHAT_V1);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHAT_V2.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHAT_V2);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_FT.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_FT);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_FT_OVER_SMS.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_FT_OVER_SMS);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_GEO_PUSH.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_GEO_PUSH);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_GEO_PUSH_VIA_SMS.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_GEO_PUSH_VIA_SMS);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CALL_COMPOSER.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CALL_COMPOSER);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_POST_CALL.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_POST_CALL);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_SHARED_MAP.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_SHARED_MAP);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_SHARED_SKETCH.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_SHARED_SKETCH);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHATBOT.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHATBOT);
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHATBOT_STANDALONE.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHATBOT_STANDALONE
-        );
-        SERVICE_IDS.put(RcsContactPresenceTuple.SERVICE_ID_CHATBOT_ROLE.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CHATBOT_ROLE);
-    }
-
-    /**
-     * Describe Message Method Type
-     * See stats/enums/telephony/enums.proto
-     */
-    private static final Map<String, Integer> MESSAGE_TYPE = new HashMap<>();
-
-    static {
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_INVITE.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_INVITE);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_ACK.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_ACK);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_OPTIONS.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_OPTIONS);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_BYE.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_BYE);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_CANCEL.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_CANCEL);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_REGISTER.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_REGISTER);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_PRACK.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_PRACK);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_SUBSCRIBE.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_SUBSCRIBE);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_NOTIFY.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_NOTIFY);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_PUBLISH.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_PUBLISH);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_INFO.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_INFO);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_REFER.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_REFER);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_MESSAGE.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_MESSAGE);
-        MESSAGE_TYPE.put(SIP_REQUEST_MESSAGE_TYPE_UPDATE.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_UPDATE);
-    }
-
-    /**
-     * Describe Reasons
-     * See frameworks/opt/net/ims/src/java/com/android/ims/rcs/uce/request/
-     * SubscriptionTerminatedHelper.java
-     * and int value matching the Reasons
-     * See frameworks/proto_logging/stats/atoms.proto
-     */
-    private static final Map<String, Integer> NOTIFY_REASONS = new HashMap<>();
-
-    static {
-        NOTIFY_REASONS.put("deactivated", PRESENCE_NOTIFY_EVENT__REASON__REASON_DEACTIVATED);
-        NOTIFY_REASONS.put("probation", PRESENCE_NOTIFY_EVENT__REASON__REASON_PROBATION);
-        NOTIFY_REASONS.put("rejected", PRESENCE_NOTIFY_EVENT__REASON__REASON_REJECTED);
-        NOTIFY_REASONS.put("timeout", PRESENCE_NOTIFY_EVENT__REASON__REASON_TIMEOUT);
-        NOTIFY_REASONS.put("giveup", PRESENCE_NOTIFY_EVENT__REASON__REASON_GIVEUP);
-        NOTIFY_REASONS.put("noresource", PRESENCE_NOTIFY_EVENT__REASON__REASON_NORESOURCE);
-    }
-
-    /**
-     * Describe Rcs Capability set
-     * See frameworks/base/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
-     */
-    private static final HashSet<String> RCS_SERVICE_ID_SET = new HashSet<>();
-    static {
-        RCS_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_CHAT_V1);
-        RCS_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_CHAT_V2);
-        RCS_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_FT);
-        RCS_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_FT_OVER_SMS);
-        RCS_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_GEO_PUSH);
-        RCS_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_GEO_PUSH_VIA_SMS);
-        RCS_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_SHARED_MAP);
-        RCS_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_SHARED_SKETCH);
-        RCS_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_CHATBOT);
-        RCS_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_CHATBOT_STANDALONE);
-        RCS_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_CHATBOT_ROLE);
-    }
-
-    /**
-     * Describe Mmtel Capability set
-     * See frameworks/base/telephony/java/android/telephony/ims/RcsContactPresenceTuple.java
-     */
-    private static final HashSet<String> MMTEL_SERVICE_ID_SET = new HashSet<>();
-    static {
-        MMTEL_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_MMTEL);
-        MMTEL_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_CALL_COMPOSER);
-        MMTEL_SERVICE_ID_SET.add(RcsContactPresenceTuple.SERVICE_ID_POST_CALL);
-    }
-
-    private static final Map<Long, Integer> sSubscribeTaskIds = new HashMap<>();
-    private static final int SUBSCRIBE_SUCCESS = 1;
-    private static final int SUBSCRIBE_NOTIFY = 2;
-
-    @VisibleForTesting
-    protected final Map<Integer, ImsDedicatedBearerListenerEvent> mDedicatedBearerListenerEventMap =
-            new HashMap<>();
-    @VisibleForTesting
-    protected final List<RcsAcsProvisioningStats> mRcsAcsProvisioningStatsList =
-            new ArrayList<RcsAcsProvisioningStats>();
-    @VisibleForTesting
-    protected final HashMap<Integer, RcsProvisioningCallback> mRcsProvisioningCallbackMap =
-            new HashMap<>();
-
-    // Maps feature tag name -> ImsRegistrationFeatureTagStats.
-    private final List<ImsRegistrationFeatureTagStats> mImsRegistrationFeatureTagStatsList =
-            new ArrayList<>();
-
-    // Maps service id -> ImsRegistrationServiceDescStats.
-    @VisibleForTesting
-    protected final List<ImsRegistrationServiceDescStats> mImsRegistrationServiceDescStatsList =
-            new ArrayList<>();
-
-    private List<LastSipDelegateStat> mLastSipDelegateStatList = new ArrayList<>();
-    private HashMap<Integer, SipTransportFeatureTags> mLastFeatureTagStatMap = new HashMap<>();
-    private ArrayList<SipMessageArray> mSipMessageArray = new ArrayList<>();
-    private ArrayList<SipTransportSessionArray> mSipTransportSessionArray = new ArrayList<>();
-    private SipTransportSessionArray mSipTransportSession;
-    private SipMessageArray mSipMessage;
-
-    private class LastSipDelegateStat {
-        public int mSubId;
-        public SipDelegateStats mLastStat;
-        private Set<String> mSupportedTags;
-
-        LastSipDelegateStat(int subId, Set<String> supportedTags) {
-            mSubId = subId;
-            mSupportedTags = supportedTags;
-        }
-
-        public void createSipDelegateStat(int subId) {
-            mLastStat = getDefaultSipDelegateStat(subId);
-            mLastStat.uptimeMillis = getWallTimeMillis();
-            mLastStat.destroyReason = NONE;
-        }
-
-        public void setSipDelegateDestroyReason(int destroyReason) {
-            mLastStat.destroyReason = destroyReason;
-        }
-
-        public boolean isDestroyed() {
-            return mLastStat.destroyReason > NONE;
-        }
-
-        public void conclude(long now) {
-            long duration = now - mLastStat.uptimeMillis;
-            if (duration < MIN_DURATION_MILLIS) {
-                logd("concludeSipDelegateStat: discarding transient stats,"
-                        + " duration= " + duration);
-            } else {
-                mLastStat.uptimeMillis = duration;
-                mAtomsStorage.addSipDelegateStats(copyOf(mLastStat));
-            }
-            mLastStat.uptimeMillis = now;
-        }
-
-        public boolean compare(int subId, Set<String> supportedTags) {
-            if (subId != mSubId || supportedTags == null || supportedTags.isEmpty()) {
-                return false;
-            }
-            for (String tag : supportedTags) {
-                if (!mSupportedTags.contains(tag)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        private SipDelegateStats getDefaultSipDelegateStat(int subId) {
-            SipDelegateStats stat = new SipDelegateStats();
-            stat.dimension = RANDOM.nextInt();
-            stat.carrierId = getCarrierId(subId);
-            stat.slotId = getSlotId(subId);
-            return stat;
-        }
-    }
-
-    private static SipDelegateStats copyOf(@NonNull SipDelegateStats source) {
-        SipDelegateStats newStat = new SipDelegateStats();
-
-        newStat.dimension = source.dimension;
-        newStat.slotId = source.slotId;
-        newStat.carrierId = source.carrierId;
-        newStat.destroyReason = source.destroyReason;
-        newStat.uptimeMillis = source.uptimeMillis;
-
-        return newStat;
-    }
-
-    private class SipTransportFeatureTags {
-        private HashMap<String, LastFeatureTagState> mFeatureTagMap;
-        private int mSubId;
-
-        private class LastFeatureTagState {
-            public long timeStamp;
-            public int carrierId;
-            public int slotId;
-            public int state;
-            public int reason;
-
-            LastFeatureTagState(int carrierId, int slotId, int state, int reason, long timeStamp) {
-                this.carrierId = carrierId;
-                this.slotId = slotId;
-                this.state = state;
-                this.reason = reason;
-                this.timeStamp = timeStamp;
-            }
-
-            public void update(int state, int reason, long timeStamp) {
-                this.state = state;
-                this.reason = reason;
-                this.timeStamp = timeStamp;
-            }
-
-            public void update(long timeStamp) {
-                this.timeStamp = timeStamp;
-            }
-        }
-
-        SipTransportFeatureTags(int subId) {
-            mFeatureTagMap = new HashMap<>();
-            mSubId = subId;
-        }
-
-        public HashMap<String, LastFeatureTagState> getLastTagStates() {
-            return mFeatureTagMap;
-        }
-
-        /*** Create or update featureTags whenever feature Tag states are changed */
-        public synchronized void updateLastFeatureTagState(String tagName, int state, int reason,
-                long timeStamp) {
-            int carrierId = getCarrierId(mSubId);
-            int slotId = getSlotId(mSubId);
-            if (mFeatureTagMap.containsKey(tagName)) {
-                LastFeatureTagState lastFeatureTagState = mFeatureTagMap.get(tagName);
-                if (lastFeatureTagState != null) {
-                    addFeatureTagStat(tagName, lastFeatureTagState, timeStamp);
-                    lastFeatureTagState.update(state, reason, timeStamp);
-                } else {
-                    create(tagName, carrierId, slotId, state, reason, timeStamp);
-                }
-
-            } else {
-                create(tagName, carrierId, slotId, state, reason, timeStamp);
-            }
-        }
-
-        /** Update current featureTags associated to active SipDelegates when metrics is pulled */
-        public synchronized void conclude(long timeStamp) {
-            HashMap<String, LastFeatureTagState> featureTagsCopy = new HashMap<>();
-            featureTagsCopy.putAll(mFeatureTagMap);
-            for (Map.Entry<String, LastFeatureTagState> last : featureTagsCopy.entrySet()) {
-                String tagName = last.getKey();
-                LastFeatureTagState lastFeatureTagState = last.getValue();
-                addFeatureTagStat(tagName, lastFeatureTagState, timeStamp);
-                updateTimeStamp(mSubId, tagName, timeStamp);
-            }
-        }
-
-        /** Finalizes the durations of the current featureTags associated to active SipDelegates */
-        private synchronized boolean addFeatureTagStat(@NonNull String tagName,
-                @NonNull LastFeatureTagState lastFeatureTagState, long now) {
-            long duration = now - lastFeatureTagState.timeStamp;
-            if (duration < MIN_DURATION_MILLIS
-                    || !isValidCarrierId(lastFeatureTagState.carrierId)) {
-                logd("conclude: discarding transient stats, duration= " + duration
-                        + ", carrierId = " + lastFeatureTagState.carrierId);
-            } else {
-                SipTransportFeatureTagStats sipFeatureTagStat = new SipTransportFeatureTagStats();
-                switch (lastFeatureTagState.state) {
-                    case STATE_DENIED:
-                        sipFeatureTagStat.sipTransportDeniedReason = lastFeatureTagState.reason;
-                        sipFeatureTagStat.sipTransportDeregisteredReason = NONE;
-                        break;
-                    case STATE_DEREGISTERED:
-                        sipFeatureTagStat.sipTransportDeniedReason = NONE;
-                        sipFeatureTagStat.sipTransportDeregisteredReason =
-                                lastFeatureTagState.reason;
-                        break;
-                    default:
-                        sipFeatureTagStat.sipTransportDeniedReason = NONE;
-                        sipFeatureTagStat.sipTransportDeregisteredReason = NONE;
-                        break;
-                }
-
-                sipFeatureTagStat.carrierId = lastFeatureTagState.carrierId;
-                sipFeatureTagStat.slotId = lastFeatureTagState.slotId;
-                sipFeatureTagStat.associatedMillis = duration;
-                sipFeatureTagStat.featureTagName = convertTagNameToValue(tagName);
-                mAtomsStorage.addSipTransportFeatureTagStats(sipFeatureTagStat);
-                return true;
-            }
-            return false;
-        }
-
-        private void updateTimeStamp(int subId, String tagName, long timeStamp) {
-            SipTransportFeatureTags sipTransportFeatureTags = mLastFeatureTagStatMap.get(subId);
-            if (sipTransportFeatureTags != null) {
-                HashMap<String, LastFeatureTagState> lastTagStates =
-                        sipTransportFeatureTags.getLastTagStates();
-                if (lastTagStates != null && lastTagStates.containsKey(tagName)) {
-                    LastFeatureTagState lastFeatureTagState = lastTagStates.get(tagName);
-                    if (lastFeatureTagState != null) {
-                        lastFeatureTagState.update(timeStamp);
-                    }
-                }
-            }
-        }
-
-        private LastFeatureTagState create(String tagName, int carrierId, int slotId, int state,
-                int reason, long timeStamp) {
-            LastFeatureTagState lastFeatureTagState = new LastFeatureTagState(carrierId, slotId,
-                    state, reason, timeStamp);
-            mFeatureTagMap.put(tagName, lastFeatureTagState);
-            return lastFeatureTagState;
-        }
-    }
-
-    class UceStatsWriterCallback implements UceStatsCallback {
-        private RcsStats mRcsStats;
-
-        UceStatsWriterCallback(RcsStats rcsStats) {
-            logd("created Callback");
-            mRcsStats = rcsStats;
-        }
-
-        public void onImsRegistrationFeatureTagStats(int subId, List<String> featureTagList,
-                int registrationTech) {
-            mRcsStats.onImsRegistrationFeatureTagStats(subId, featureTagList, registrationTech);
-        }
-
-        public void onStoreCompleteImsRegistrationFeatureTagStats(int subId) {
-            mRcsStats.onStoreCompleteImsRegistrationFeatureTagStats(subId);
-        }
-
-        public void onImsRegistrationServiceDescStats(int subId, List<String> serviceIdList,
-                List<String> serviceIdVersionList, int registrationTech) {
-            mRcsStats.onImsRegistrationServiceDescStats(subId, serviceIdList, serviceIdVersionList,
-                    registrationTech);
-        }
-
-        public void onSubscribeResponse(int subId, long taskId, int networkResponse) {
-            if (networkResponse >= 200 && networkResponse <= 299) {
-                if (!sSubscribeTaskIds.containsKey(taskId)) {
-                    sSubscribeTaskIds.put(taskId, SUBSCRIBE_SUCCESS);
-                }
-            }
-            mRcsStats.onUceEventStats(subId, UCE_EVENT_STATS__TYPE__SUBSCRIBE,
-                    true, 0, networkResponse);
-        }
-
-        public void onUceEvent(int subId, int type, boolean successful, int commandCode,
-                int networkResponse) {
-            int eventType = 0;
-            switch (type) {
-                case UceStatsWriter.PUBLISH_EVENT:
-                    eventType = UCE_EVENT_STATS__TYPE__PUBLISH;
-                    break;
-                case UceStatsWriter.SUBSCRIBE_EVENT:
-                    eventType = UCE_EVENT_STATS__TYPE__SUBSCRIBE;
-                    break;
-                case UceStatsWriter.INCOMING_OPTION_EVENT:
-                    eventType = UCE_EVENT_STATS__TYPE__INCOMING_OPTION;
-                    break;
-                case UceStatsWriter.OUTGOING_OPTION_EVENT:
-                    eventType = UCE_EVENT_STATS__TYPE__OUTGOING_OPTION;
-                    break;
-                default:
-                    return;
-            }
-            mRcsStats.onUceEventStats(subId, eventType, successful, commandCode, networkResponse);
-        }
-
-        public void onSubscribeTerminated(int subId, long taskId, String reason) {
-            if (sSubscribeTaskIds.containsKey(taskId)) {
-                int previousSubscribeStatus = sSubscribeTaskIds.get(taskId);
-                sSubscribeTaskIds.remove(taskId);
-                // The device received a success response related to the subscription request.
-                // However, PIDF was not received due to reason value.
-                if (previousSubscribeStatus == SUBSCRIBE_SUCCESS) {
-                    mRcsStats.onPresenceNotifyEvent(subId, reason, false,
-                            false, false, false);
-                }
-            }
-        }
-
-        public void onPresenceNotifyEvent(int subId, long taskId,
-                List<RcsContactUceCapability> updatedCapList) {
-            if (updatedCapList == null || updatedCapList.isEmpty()) {
-                return;
-            }
-            if (sSubscribeTaskIds.containsKey(taskId)) {
-                sSubscribeTaskIds.replace(taskId, SUBSCRIBE_NOTIFY);
-            }
-            for (RcsContactUceCapability capability : updatedCapList) {
-                boolean rcsCap = false;
-                boolean mmtelCap = false;
-                boolean noCap = true;
-                List<RcsContactPresenceTuple> tupleList = capability.getCapabilityTuples();
-                if (tupleList.isEmpty()) {
-                    noCap = true;
-                    mRcsStats.onPresenceNotifyEvent(subId, "", true,
-                            rcsCap, mmtelCap, noCap);
-                    continue;
-                }
-                for (RcsContactPresenceTuple tuple : tupleList) {
-                    String serviceId = tuple.getServiceId();
-                    if (RCS_SERVICE_ID_SET.contains(serviceId)) {
-                        rcsCap = true;
-                        noCap = false;
-                    } else if (MMTEL_SERVICE_ID_SET.contains(serviceId)) {
-                        if (serviceId.equals(RcsContactPresenceTuple.SERVICE_ID_CALL_COMPOSER)) {
-                            if ("1.0".equals(tuple.getServiceVersion())) {
-                                rcsCap = true;
-                                noCap = false;
-                                continue;
-                            }
-                        }
-                        mmtelCap = true;
-                        noCap = false;
-                    }
-                }
-                mRcsStats.onPresenceNotifyEvent(subId, "", true, rcsCap,
-                        mmtelCap, noCap);
-            }
-        }
-
-        public void onStoreCompleteImsRegistrationServiceDescStats(int subId) {
-            mRcsStats.onStoreCompleteImsRegistrationServiceDescStats(subId);
-        }
-    }
-
-    /** Callback class to receive RCS ACS result and to store metrics. */
-    public class RcsProvisioningCallback extends IRcsConfigCallback.Stub {
-        private RcsStats mRcsStats;
-        private int mSubId;
-        private boolean mEnableSingleRegistration;
-        private boolean mRegistered;
-
-        RcsProvisioningCallback(RcsStats rcsStats, int subId, boolean enableSingleRegistration) {
-            logd("created RcsProvisioningCallback");
-            mRcsStats = rcsStats;
-            mSubId = subId;
-            mEnableSingleRegistration = enableSingleRegistration;
-            mRegistered = false;
-        }
-
-        public synchronized void setEnableSingleRegistration(boolean enableSingleRegistration) {
-            mEnableSingleRegistration = enableSingleRegistration;
-        }
-
-        public boolean getRegistered() {
-            return mRegistered;
-        }
-
-        public void setRegistered(boolean registered) {
-            mRegistered = registered;
-        }
-
-        @Override
-        public void onConfigurationChanged(byte[] config) {
-            // this callback will not be handled.
-        }
-
-        @Override
-        public void onAutoConfigurationErrorReceived(int errorCode, String errorString) {
-            final long callingIdentity = Binder.clearCallingIdentity();
-            try {
-                mRcsStats.onRcsAcsProvisioningStats(mSubId, errorCode,
-                        RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR,
-                        mEnableSingleRegistration);
-            } finally {
-                restoreCallingIdentity(callingIdentity);
-            }
-        }
-
-        @Override
-        public void onConfigurationReset() {
-            // this callback will not be handled.
-        }
-
-        @Override
-        public void onRemoved() {
-            final long callingIdentity = Binder.clearCallingIdentity();
-            try {
-                // store cached metrics
-                mRcsStats.onStoreCompleteRcsAcsProvisioningStats(mSubId);
-               // remove this obj from Map
-                mRcsStats.removeRcsProvisioningCallback(mSubId);
-            } finally {
-                restoreCallingIdentity(callingIdentity);
-            }
-        }
-
-        @Override
-        public void onPreProvisioningReceived(byte[] config) {
-            final long callingIdentity = Binder.clearCallingIdentity();
-            try {
-                // Receiving pre provisioning means http 200 OK with body.
-                mRcsStats.onRcsAcsProvisioningStats(mSubId, 200,
-                        RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PRE_PROVISIONING_XML,
-                        mEnableSingleRegistration);
-            } finally {
-                restoreCallingIdentity(callingIdentity);
-            }
-        }
-    };
-
-    private class SipMessageArray {
-        private String mMethod;
-        private String mCallId;
-        private int mDirection;
-
-        SipMessageArray(String method, int direction, String callId) {
-            this.mMethod = method;
-            this.mCallId = callId;
-            this.mDirection = direction;
-        }
-
-        private synchronized void addSipMessageStat(
-                @NonNull int subId, @NonNull String sipMessageMethod,
-                int sipMessageResponse, int sipMessageDirection, int messageError) {
-            int carrierId = getCarrierId(subId);
-            if (!isValidCarrierId(carrierId)) {
-                return;
-            }
-            SipMessageResponse proto = new SipMessageResponse();
-            proto.carrierId = carrierId;
-            proto.slotId = getSlotId(subId);
-            proto.sipMessageMethod = convertMessageTypeToValue(sipMessageMethod);
-            proto.sipMessageResponse = sipMessageResponse;
-            proto.sipMessageDirection = sipMessageDirection;
-            proto.messageError = messageError;
-            proto.count = 1;
-            mAtomsStorage.addSipMessageResponse(proto);
-        }
-    }
-
-    private class SipTransportSessionArray {
-        private String mMethod;
-        private String mCallId;
-        private int mDirection;
-        private int mSipResponse;
-
-        SipTransportSessionArray(String method, int direction, String callId) {
-            this.mMethod = method;
-            this.mCallId = callId;
-            this.mDirection = direction;
-            this.mSipResponse = 0;
-        }
-
-        private synchronized void addSipTransportSessionStat(
-                @NonNull int subId, @NonNull String sessionMethod, int sipMessageDirection,
-                int sipResponse, boolean isEndedGracefully) {
-            int carrierId = getCarrierId(subId);
-            if (!isValidCarrierId(carrierId)) {
-                return;
-            }
-            SipTransportSession proto = new SipTransportSession();
-            proto.carrierId = carrierId;
-            proto.slotId = getSlotId(subId);
-            proto.sessionMethod = convertMessageTypeToValue(sessionMethod);
-            proto.sipMessageDirection = sipMessageDirection;
-            proto.sipResponse = sipResponse;
-            proto.sessionCount = 1;
-            proto.endedGracefullyCount = 1;
-            proto.isEndedGracefully = isEndedGracefully;
-            mAtomsStorage.addCompleteSipTransportSession(proto);
-        }
-    }
-
-    @VisibleForTesting
-    protected RcsStats() {
-        mCallback = null;
-    }
-
-    /** Gets a RcsStats instance. */
-    public static RcsStats getInstance() {
-        synchronized (RcsStats.class) {
-            if (sInstance == null) {
-                Rlog.d(TAG, "RcsStats created.");
-                sInstance = new RcsStats();
-            }
-            return sInstance;
-        }
-    }
-
-    /** register callback to UceStatsWriter. */
-    public void registerUceCallback() {
-        if (mCallback == null) {
-            mCallback = new UceStatsWriterCallback(sInstance);
-            Rlog.d(TAG, "UceStatsWriterCallback created.");
-            UceStatsWriter.init(mCallback);
-        }
-    }
-
-    /** Update or create new atom when RCS service registered. */
-    public void onImsRegistrationFeatureTagStats(int subId, List<String> featureTagList,
-            int registrationTech) {
-        synchronized (mImsRegistrationFeatureTagStatsList) {
-            int carrierId = getCarrierId(subId);
-            if (!isValidCarrierId(carrierId)) {
-                flushImsRegistrationFeatureTagStatsInvalid();
-                return;
-            }
-
-            // update cached atom if exists
-            onStoreCompleteImsRegistrationFeatureTagStats(subId);
-
-            if (featureTagList == null) {
-                Rlog.d(TAG, "featureTagNames is null or empty");
-                return;
-            }
-
-            for (String featureTag : featureTagList) {
-                ImsRegistrationFeatureTagStats proto = new ImsRegistrationFeatureTagStats();
-                proto.carrierId = carrierId;
-                proto.slotId = getSlotId(subId);
-                proto.featureTagName = convertTagNameToValue(featureTag);
-                proto.registrationTech = registrationTech;
-                proto.registeredMillis = getWallTimeMillis();
-                mImsRegistrationFeatureTagStatsList.add(proto);
-            }
-        }
-    }
-
-    /** Update duration, store and delete cached ImsRegistrationFeatureTagStats list to storage. */
-    public void onStoreCompleteImsRegistrationFeatureTagStats(int subId) {
-        synchronized (mImsRegistrationFeatureTagStatsList) {
-            int carrierId = getCarrierId(subId);
-            List<ImsRegistrationFeatureTagStats> deleteList = new ArrayList<>();
-            long now = getWallTimeMillis();
-            for (ImsRegistrationFeatureTagStats proto : mImsRegistrationFeatureTagStatsList) {
-                if (proto.carrierId == carrierId) {
-                    proto.registeredMillis = now - proto.registeredMillis;
-                    mAtomsStorage.addImsRegistrationFeatureTagStats(proto);
-                    deleteList.add(proto);
-                }
-            }
-            for (ImsRegistrationFeatureTagStats proto : deleteList) {
-                mImsRegistrationFeatureTagStatsList.remove(proto);
-            }
-        }
-    }
-
-    /** Update duration and store cached ImsRegistrationFeatureTagStats when metrics are pulled */
-    public void onFlushIncompleteImsRegistrationFeatureTagStats() {
-        synchronized (mImsRegistrationFeatureTagStatsList) {
-            long now = getWallTimeMillis();
-            for (ImsRegistrationFeatureTagStats proto : mImsRegistrationFeatureTagStatsList) {
-                ImsRegistrationFeatureTagStats newProto = copyImsRegistrationFeatureTagStats(proto);
-                // the current time is a placeholder and total registered time will be
-                // calculated when generating final atoms
-                newProto.registeredMillis = now - proto.registeredMillis;
-                mAtomsStorage.addImsRegistrationFeatureTagStats(newProto);
-                proto.registeredMillis = now;
-            }
-        }
-    }
-
-    /** Create a new atom when RCS client stat changed. */
-    public synchronized void onRcsClientProvisioningStats(int subId, int event) {
-        int carrierId = getCarrierId(subId);
-
-        if (!isValidCarrierId(carrierId)) {
-            return;
-        }
-
-        RcsClientProvisioningStats proto = new RcsClientProvisioningStats();
-        proto.carrierId = carrierId;
-        proto.slotId = getSlotId(subId);
-        proto.event = event;
-        proto.count = 1;
-        mAtomsStorage.addRcsClientProvisioningStats(proto);
-    }
-
-    /** Update or create new atom when RCS ACS stat changed. */
-    public void onRcsAcsProvisioningStats(int subId, int responseCode, int responseType,
-            boolean enableSingleRegistration) {
-
-        synchronized (mRcsAcsProvisioningStatsList) {
-            int carrierId = getCarrierId(subId);
-            if (!isValidCarrierId(carrierId)) {
-                flushRcsAcsProvisioningStatsInvalid();
-                return;
-            }
-
-            // update cached atom if exists
-            onStoreCompleteRcsAcsProvisioningStats(subId);
-
-            // create new stats to cache
-            RcsAcsProvisioningStats newStats = new RcsAcsProvisioningStats();
-            newStats.carrierId = carrierId;
-            newStats.slotId = getSlotId(subId);
-            newStats.responseCode = responseCode;
-            newStats.responseType = responseType;
-            newStats.isSingleRegistrationEnabled = enableSingleRegistration;
-            newStats.count = 1;
-            newStats.stateTimerMillis = getWallTimeMillis();
-
-            // add new stats in list
-            mRcsAcsProvisioningStatsList.add(newStats);
-        }
-    }
-
-    /** Update duration, store and delete cached RcsAcsProvisioningStats */
-    public void onStoreCompleteRcsAcsProvisioningStats(int subId) {
-        synchronized (mRcsAcsProvisioningStatsList) {
-            // find cached RcsAcsProvisioningStats based sub ID
-            RcsAcsProvisioningStats existingStats = getRcsAcsProvisioningStats(subId);
-            if (existingStats != null) {
-                existingStats.stateTimerMillis =
-                        getWallTimeMillis() - existingStats.stateTimerMillis;
-                mAtomsStorage.addRcsAcsProvisioningStats(existingStats);
-                // remove cached atom from list
-                mRcsAcsProvisioningStatsList.remove(existingStats);
-            }
-        }
-    }
-
-    /** Update duration and store cached RcsAcsProvisioningStats when metrics are pulled */
-    public void onFlushIncompleteRcsAcsProvisioningStats() {
-        synchronized (mRcsAcsProvisioningStatsList) {
-            long now = getWallTimeMillis();
-            for (RcsAcsProvisioningStats stats : mRcsAcsProvisioningStatsList) {
-                // we store a copy into atoms storage
-                // so that we can continue using the original object.
-                RcsAcsProvisioningStats proto = copyRcsAcsProvisioningStats(stats);
-                // the current time is a placeholder and total registered time will be
-                // calculated when generating final atoms
-                proto.stateTimerMillis = now - proto.stateTimerMillis;
-                mAtomsStorage.addRcsAcsProvisioningStats(proto);
-                // update cached atom's time
-                stats.stateTimerMillis = now;
-            }
-        }
-    }
-
-    /** Create SipDelegateStat when SipDelegate is created */
-    public synchronized void createSipDelegateStats(int subId, Set<String> supportedTags) {
-        if (supportedTags != null && !supportedTags.isEmpty()) {
-            LastSipDelegateStat lastState = getLastSipDelegateStat(subId, supportedTags);
-            lastState.createSipDelegateStat(subId);
-        }
-    }
-
-    /** Update destroyReason and duration of SipDelegateStat when SipDelegate is destroyed */
-    public synchronized void onSipDelegateStats(int subId, Set<String> supportedTags,
-            int destroyReason) {
-        if (supportedTags != null && !supportedTags.isEmpty()) {
-            LastSipDelegateStat lastState = getLastSipDelegateStat(subId, supportedTags);
-            lastState.setSipDelegateDestroyReason(destroyReason);
-            concludeSipDelegateStat();
-        }
-    }
-
-    /** Create/Update atoms when states of sipTransportFeatureTags are changed */
-    public synchronized void onSipTransportFeatureTagStats(
-            int subId,
-            Set<FeatureTagState> deniedTags,
-            Set<FeatureTagState> deRegiTags,
-            Set<String> regiTags) {
-        long now = getWallTimeMillis();
-        SipTransportFeatureTags sipTransportFeatureTags = getLastFeatureTags(subId);
-        if (regiTags != null && !regiTags.isEmpty()) {
-            for (String tag : regiTags) {
-                sipTransportFeatureTags.updateLastFeatureTagState(tag, STATE_REGISTERED,
-                        NONE, now);
-            }
-        }
-        if (deniedTags != null && !deniedTags.isEmpty()) {
-            for (FeatureTagState tag : deniedTags) {
-                sipTransportFeatureTags.updateLastFeatureTagState(tag.getFeatureTag(), STATE_DENIED,
-                        tag.getState(), now);
-            }
-        }
-        if (deRegiTags != null && !deRegiTags.isEmpty()) {
-            for (FeatureTagState tag : deRegiTags) {
-                sipTransportFeatureTags.updateLastFeatureTagState(
-                        tag.getFeatureTag(), STATE_DEREGISTERED, tag.getState(), now);
-            }
-        }
-    }
-
-    /** Update duration of  sipTransportFeatureTags when metrics are pulled */
-    public synchronized void concludeSipTransportFeatureTagsStat() {
-        if (mLastFeatureTagStatMap.isEmpty()) {
-            return;
-        }
-
-        long now = getWallTimeMillis();
-        HashMap<Integer, SipTransportFeatureTags> lastFeatureTagStatsCopy = new HashMap<>();
-        lastFeatureTagStatsCopy.putAll(mLastFeatureTagStatMap);
-        for (SipTransportFeatureTags sipTransportFeatureTags : lastFeatureTagStatsCopy.values()) {
-            if (sipTransportFeatureTags != null) {
-                sipTransportFeatureTags.conclude(now);
-            }
-        }
-    }
-
-    /** Request Message */
-    public synchronized void onSipMessageRequest(String callId, String sipMessageMethod,
-            int sipMessageDirection) {
-        mSipMessage = new SipMessageArray(sipMessageMethod, sipMessageDirection, callId);
-        mSipMessageArray.add(mSipMessage);
-    }
-
-    /** invalidated result when Request message is sent */
-    public synchronized void invalidatedMessageResult(int subId, String sipMessageMethod,
-            int sipMessageDirection, int messageError) {
-        mSipMessage.addSipMessageStat(subId, sipMessageMethod, 0,
-                sipMessageDirection, messageError);
-    }
-
-    /** Create a new atom when RCS SIP Message Response changed. */
-    public synchronized void onSipMessageResponse(int subId, String callId,
-            int sipMessageResponse, int messageError) {
-        SipMessageArray match = mSipMessageArray.stream()
-                .filter(d -> d.mCallId.equals(callId)).findFirst().orElse(null);
-        if (match != null) {
-            mSipMessage.addSipMessageStat(subId, match.mMethod, sipMessageResponse,
-                    match.mDirection, messageError);
-            mSipMessageArray.removeIf(d -> d.mCallId.equals(callId));
-        }
-    }
-
-    /** Request SIP Method Message */
-    public synchronized void earlySipTransportSession(String sessionMethod, String callId,
-            int sipMessageDirection) {
-        mSipTransportSession = new SipTransportSessionArray(sessionMethod,
-                sipMessageDirection, callId);
-        mSipTransportSessionArray.add(mSipTransportSession);
-    }
-
-    /** Response Message */
-    public synchronized void confirmedSipTransportSession(String callId,
-            int sipResponse) {
-        SipTransportSessionArray match = mSipTransportSessionArray.stream()
-                .filter(d -> d.mCallId.equals(callId)).findFirst().orElse(null);
-        if (match != null) {
-            match.mSipResponse = sipResponse;
-        }
-    }
-
-    /** Create a new atom when RCS SIP Transport Session changed. */
-    public synchronized void onSipTransportSessionClosed(int subId, String callId,
-            int sipResponse, boolean isEndedGracefully) {
-        SipTransportSessionArray match = mSipTransportSessionArray.stream()
-                .filter(d -> d.mCallId.equals(callId)).findFirst().orElse(null);
-        if (match != null) {
-            if (sipResponse != 0) {
-                match.mSipResponse = sipResponse;
-            }
-            mSipTransportSession.addSipTransportSessionStat(subId, match.mMethod, match.mDirection,
-                    sipResponse, isEndedGracefully);
-            mSipTransportSessionArray.removeIf(d -> d.mCallId.equals(callId));
-        }
-    }
-
-    /** Add a listener to the hashmap for waiting upcoming DedicatedBearer established event */
-    public synchronized void onImsDedicatedBearerListenerAdded(@NonNull final int listenerId,
-            @NonNull final int slotId, @NonNull final int ratAtEnd, @NonNull final int qci) {
-        int subId = getSubId(slotId);
-        int carrierId = getCarrierId(subId);
-
-        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID
-                || !isValidCarrierId(carrierId)) {
-            return;
-        }
-
-        if (mDedicatedBearerListenerEventMap.containsKey(listenerId)) {
-            return;
-        }
-
-        ImsDedicatedBearerListenerEvent preProto = new ImsDedicatedBearerListenerEvent();
-        preProto.carrierId = carrierId;
-        preProto.slotId = slotId;
-        preProto.ratAtEnd = ratAtEnd;
-        preProto.qci = qci;
-        preProto.dedicatedBearerEstablished = false;
-        preProto.eventCount = 1;
-
-        mDedicatedBearerListenerEventMap.put(listenerId, preProto);
-    }
-
-    /** update previously added atom with dedicatedBearerEstablished = true when
-     *  DedicatedBearerListener Event changed. */
-    public synchronized void onImsDedicatedBearerListenerUpdateSession(final int listenerId,
-            final int slotId, final int rat, final int qci,
-            @NonNull final boolean dedicatedBearerEstablished) {
-        int subId = getSubId(slotId);
-        int carrierId = getCarrierId(subId);
-
-        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID
-                || !isValidCarrierId(carrierId)) {
-            return;
-        }
-
-        if (mDedicatedBearerListenerEventMap.containsKey(listenerId)) {
-            ImsDedicatedBearerListenerEvent preProto =
-                    mDedicatedBearerListenerEventMap.get(listenerId);
-
-            preProto.ratAtEnd = rat;
-            preProto.qci = qci;
-            preProto.dedicatedBearerEstablished = dedicatedBearerEstablished;
-
-            mDedicatedBearerListenerEventMap.replace(listenerId, preProto);
-        } else {
-            ImsDedicatedBearerListenerEvent preProto = new ImsDedicatedBearerListenerEvent();
-            preProto.carrierId = carrierId;
-            preProto.slotId = slotId;
-            preProto.ratAtEnd = rat;
-            preProto.qci = qci;
-            preProto.dedicatedBearerEstablished = dedicatedBearerEstablished;
-            preProto.eventCount = 1;
-
-            mDedicatedBearerListenerEventMap.put(listenerId, preProto);
-        }
-    }
-
-    /** add proto to atom when listener is removed, so that I can save the status of dedicatedbearer
-     *  establishment per listener id */
-    public synchronized void onImsDedicatedBearerListenerRemoved(@NonNull final int listenerId) {
-        if (mDedicatedBearerListenerEventMap.containsKey(listenerId)) {
-
-            ImsDedicatedBearerListenerEvent newProto =
-                    mDedicatedBearerListenerEventMap.get(listenerId);
-
-            mAtomsStorage.addImsDedicatedBearerListenerEvent(newProto);
-            mDedicatedBearerListenerEventMap.remove(listenerId);
-        }
-    }
-
-    /** Create a new atom when DedicatedBearer Event changed. */
-    public synchronized void onImsDedicatedBearerEvent(int slotId, int ratAtEnd, int qci,
-            int bearerState, boolean localConnectionInfoReceived,
-            boolean remoteConnectionInfoReceived, boolean hasListeners) {
-        int subId = getSubId(slotId);
-        if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
-            return;
-        }
-
-        ImsDedicatedBearerEvent proto = new ImsDedicatedBearerEvent();
-        proto.carrierId = getCarrierId(subId);
-        proto.slotId = getSlotId(subId);
-        proto.ratAtEnd = ratAtEnd;
-        proto.qci = qci;
-        proto.bearerState = bearerState;
-        proto.localConnectionInfoReceived = localConnectionInfoReceived;
-        proto.remoteConnectionInfoReceived = remoteConnectionInfoReceived;
-        proto.hasListeners = hasListeners;
-        proto.count = 1;
-        mAtomsStorage.addImsDedicatedBearerEvent(proto);
-    }
-
-    /**
-     * Update or Create a new atom when Ims Registration Service Desc state changed.
-     * Use-related parts are already converted from UseStatsWriter based on RcsContactPresenceTuple.
-     */
-    public void onImsRegistrationServiceDescStats(int subId, List<String> serviceIdList,
-            List<String> serviceIdVersionList, int registrationTech) {
-        synchronized (mImsRegistrationServiceDescStatsList) {
-            int carrierId = getCarrierId(subId);
-            if (!isValidCarrierId(carrierId)) {
-                handleImsRegistrationServiceDescStats();
-                return;
-            }
-            // update cached atom if exists
-            onStoreCompleteImsRegistrationServiceDescStats(subId);
-
-            if (serviceIdList == null) {
-                Rlog.d(TAG, "serviceIds is null or empty");
-                return;
-            }
-
-            int index = 0;
-            for (String serviceId : serviceIdList) {
-                ImsRegistrationServiceDescStats mImsRegistrationServiceDescStats =
-                        new ImsRegistrationServiceDescStats();
-
-                mImsRegistrationServiceDescStats.carrierId = carrierId;
-                mImsRegistrationServiceDescStats.slotId = getSlotId(subId);
-                mImsRegistrationServiceDescStats.serviceIdName = convertServiceIdToValue(serviceId);
-                mImsRegistrationServiceDescStats.serviceIdVersion =
-                        Float.parseFloat(serviceIdVersionList.get(index++));
-                mImsRegistrationServiceDescStats.registrationTech = registrationTech;
-                mImsRegistrationServiceDescStatsList.add(mImsRegistrationServiceDescStats);
-            }
-        }
-    }
-
-    /** Update duration and cached of ImsRegistrationServiceDescStats when metrics are pulled */
-    public void onFlushIncompleteImsRegistrationServiceDescStats() {
-        synchronized (mImsRegistrationServiceDescStatsList) {
-            for (ImsRegistrationServiceDescStats proto : mImsRegistrationServiceDescStatsList) {
-                ImsRegistrationServiceDescStats newProto =
-                        copyImsRegistrationServiceDescStats(proto);
-                long now = getWallTimeMillis();
-                // the current time is a placeholder and total registered time will be
-                // calculated when generating final atoms
-                newProto.publishedMillis = now - proto.publishedMillis;
-                mAtomsStorage.addImsRegistrationServiceDescStats(newProto);
-                proto.publishedMillis = now;
-            }
-        }
-    }
-
-    /** Create a new atom when Uce Event Stats changed. */
-    public synchronized void onUceEventStats(int subId, int type, boolean successful,
-            int commandCode, int networkResponse) {
-        UceEventStats proto = new UceEventStats();
-
-        int carrierId = getCarrierId(subId);
-        if (!isValidCarrierId(carrierId)) {
-            handleImsRegistrationServiceDescStats();
-            return;
-        }
-        proto.carrierId = carrierId;
-        proto.slotId = getSlotId(subId);
-        proto.type = type;
-        proto.successful = successful;
-        proto.commandCode = commandCode;
-        proto.networkResponse = networkResponse;
-        proto.count = 1;
-        mAtomsStorage.addUceEventStats(proto);
-
-        /**
-         * The publishedMillis of ImsRegistrationServiceDescStat is the time gap between
-         * Publish success and Un publish.
-         * So, when the publish operation is successful, the corresponding time gap is set,
-         * and in case of failure, the cached stat is deleted.
-         */
-        if (type == UCE_EVENT_STATS__TYPE__PUBLISH) {
-            if (successful) {
-                setImsRegistrationServiceDescStatsTime(proto.carrierId);
-            } else {
-                deleteImsRegistrationServiceDescStats(proto.carrierId);
-            }
-        }
-    }
-
-    /** Create a new atom when Presence Notify Event changed. */
-    public synchronized void onPresenceNotifyEvent(int subId, String reason,
-            boolean contentBodyReceived, boolean rcsCaps, boolean mmtelCaps, boolean noCaps) {
-        PresenceNotifyEvent proto = new PresenceNotifyEvent();
-
-        int carrierId = getCarrierId(subId);
-        if (!isValidCarrierId(carrierId)) {
-            handleImsRegistrationServiceDescStats();
-            return;
-        }
-
-        proto.carrierId = carrierId;
-        proto.slotId = getSlotId(subId);
-        proto.reason = convertPresenceNotifyReason(reason);
-        proto.contentBodyReceived = contentBodyReceived;
-        proto.rcsCapsCount = rcsCaps ? 1 : 0;
-        proto.mmtelCapsCount = mmtelCaps ? 1 : 0;
-        proto.noCapsCount = noCaps ? 1 : 0;
-        proto.count = 1;
-        mAtomsStorage.addPresenceNotifyEvent(proto);
-    }
-
-    /** Update duration a created Ims Registration Desc Stat atom when Un publish event happened. */
-    public void onStoreCompleteImsRegistrationServiceDescStats(int subId) {
-        synchronized (mImsRegistrationServiceDescStatsList) {
-            int carrierId = getCarrierId(subId);
-            List<ImsRegistrationServiceDescStats> deleteList = new ArrayList<>();
-            for (ImsRegistrationServiceDescStats proto : mImsRegistrationServiceDescStatsList) {
-                if (proto.carrierId == carrierId) {
-                    proto.publishedMillis = getWallTimeMillis() - proto.publishedMillis;
-                    mAtomsStorage.addImsRegistrationServiceDescStats(proto);
-                    deleteList.add(proto);
-                }
-            }
-            for (ImsRegistrationServiceDescStats proto : deleteList) {
-                mImsRegistrationServiceDescStatsList.remove(proto);
-            }
-        }
-    }
-
-    /** Create a new atom when GBA Success Event changed. */
-    public synchronized void onGbaSuccessEvent(int subId) {
-        int carrierId = getCarrierId(subId);
-        if (!isValidCarrierId(carrierId)) {
-            return;
-        }
-
-        GbaEvent proto = new GbaEvent();
-        proto.carrierId = carrierId;
-        proto.slotId = getSlotId(subId);
-        proto.successful = true;
-        proto.failedReason = -1;
-        proto.count = 1;
-        mAtomsStorage.addGbaEvent(proto);
-    }
-
-    /** Create a new atom when GBA Failure Event changed. */
-    public synchronized void onGbaFailureEvent(int subId, int reason) {
-        int carrierId = getCarrierId(subId);
-        if (!isValidCarrierId(carrierId)) {
-            return;
-        }
-
-        GbaEvent proto = new GbaEvent();
-        proto.carrierId = carrierId;
-        proto.slotId = getSlotId(subId);
-        proto.successful = false;
-        proto.failedReason = reason;
-        proto.count = 1;
-        mAtomsStorage.addGbaEvent(proto);
-    }
-
-    /** Create or return exist RcsProvisioningCallback based on subId. */
-    public synchronized RcsProvisioningCallback getRcsProvisioningCallback(int subId,
-            boolean enableSingleRegistration) {
-        // find exist obj in Map
-        RcsProvisioningCallback rcsProvisioningCallback = mRcsProvisioningCallbackMap.get(subId);
-        if (rcsProvisioningCallback != null) {
-            return rcsProvisioningCallback;
-        }
-
-        // create new, add Map and return
-        rcsProvisioningCallback = new RcsProvisioningCallback(this, subId,
-                enableSingleRegistration);
-        mRcsProvisioningCallbackMap.put(subId, rcsProvisioningCallback);
-        return rcsProvisioningCallback;
-    }
-
-    /** Set whether single registration is supported. */
-    public synchronized void setEnableSingleRegistration(int subId,
-            boolean enableSingleRegistration) {
-        // find exist obj and set
-        RcsProvisioningCallback callbackBinder = mRcsProvisioningCallbackMap.get(subId);
-        if (callbackBinder != null) {
-            callbackBinder.setEnableSingleRegistration(enableSingleRegistration);
-        }
-    }
-
-    private synchronized void removeRcsProvisioningCallback(int subId) {
-        // remove obj from Map based on subId
-        mRcsProvisioningCallbackMap.remove(subId);
-    }
-
-    private ImsRegistrationFeatureTagStats copyImsRegistrationFeatureTagStats(
-            ImsRegistrationFeatureTagStats proto) {
-        ImsRegistrationFeatureTagStats newProto = new ImsRegistrationFeatureTagStats();
-        newProto.carrierId = proto.carrierId;
-        newProto.slotId = proto.slotId;
-        newProto.featureTagName = proto.featureTagName;
-        newProto.registrationTech = proto.registrationTech;
-        newProto.registeredMillis = proto.registeredMillis;
-
-        return newProto;
-    }
-
-    private RcsAcsProvisioningStats copyRcsAcsProvisioningStats(RcsAcsProvisioningStats proto) {
-        RcsAcsProvisioningStats newProto = new RcsAcsProvisioningStats();
-        newProto.carrierId = proto.carrierId;
-        newProto.slotId = proto.slotId;
-        newProto.responseCode = proto.responseCode;
-        newProto.responseType = proto.responseType;
-        newProto.isSingleRegistrationEnabled = proto.isSingleRegistrationEnabled;
-        newProto.count = proto.count;
-        newProto.stateTimerMillis = proto.stateTimerMillis;
-
-        return newProto;
-    }
-
-    private ImsRegistrationServiceDescStats copyImsRegistrationServiceDescStats(
-            ImsRegistrationServiceDescStats proto) {
-        ImsRegistrationServiceDescStats newProto = new ImsRegistrationServiceDescStats();
-        newProto.carrierId = proto.carrierId;
-        newProto.slotId = proto.slotId;
-        newProto.serviceIdName = proto.serviceIdName;
-        newProto.serviceIdVersion = proto.serviceIdVersion;
-        newProto.registrationTech = proto.registrationTech;
-        return newProto;
-    }
-
-    private void setImsRegistrationServiceDescStatsTime(int carrierId) {
-        synchronized (mImsRegistrationServiceDescStatsList) {
-            for (ImsRegistrationServiceDescStats descStats : mImsRegistrationServiceDescStatsList) {
-                if (descStats.carrierId == carrierId) {
-                    descStats.publishedMillis = getWallTimeMillis();
-                }
-            }
-        }
-    }
-
-    private void deleteImsRegistrationServiceDescStats(int carrierId) {
-        synchronized (mImsRegistrationServiceDescStatsList) {
-            List<ImsRegistrationServiceDescStats> deleteList = new ArrayList<>();
-            for (ImsRegistrationServiceDescStats proto : mImsRegistrationServiceDescStatsList) {
-                if (proto.carrierId == carrierId) {
-                    deleteList.add(proto);
-                }
-            }
-            for (ImsRegistrationServiceDescStats stats : deleteList) {
-                mImsRegistrationServiceDescStatsList.remove(stats);
-            }
-        }
-    }
-
-    private void handleImsRegistrationServiceDescStats() {
-        synchronized (mImsRegistrationServiceDescStatsList) {
-            List<ImsRegistrationServiceDescStats> deleteList = new ArrayList<>();
-            for (ImsRegistrationServiceDescStats proto : mImsRegistrationServiceDescStatsList) {
-                int subId = getSubId(proto.slotId);
-                int newCarrierId = getCarrierId(subId);
-                if (proto.carrierId != newCarrierId) {
-                    deleteList.add(proto);
-                    if (proto.publishedMillis != 0) {
-                        proto.publishedMillis = getWallTimeMillis() - proto.publishedMillis;
-                        mAtomsStorage.addImsRegistrationServiceDescStats(proto);
-                    }
-                }
-            }
-            for (ImsRegistrationServiceDescStats stats : deleteList) {
-                mImsRegistrationServiceDescStatsList.remove(stats);
-            }
-        }
-    }
-
-    private RcsAcsProvisioningStats getRcsAcsProvisioningStats(int subId) {
-        int carrierId = getCarrierId(subId);
-        int slotId = getSlotId(subId);
-
-        for (RcsAcsProvisioningStats stats : mRcsAcsProvisioningStatsList) {
-            if (stats == null) {
-                continue;
-            }
-            if (stats.carrierId == carrierId && stats.slotId == slotId) {
-                return stats;
-            }
-        }
-        return null;
-    }
-
-    private void flushRcsAcsProvisioningStatsInvalid() {
-        List<RcsAcsProvisioningStats> inValidList = new ArrayList<RcsAcsProvisioningStats>();
-
-        int subId;
-        int newCarrierId;
-
-        for (RcsAcsProvisioningStats stats : mRcsAcsProvisioningStatsList) {
-            subId = getSubId(stats.slotId);
-            newCarrierId = getCarrierId(subId);
-            if (stats.carrierId != newCarrierId) {
-                inValidList.add(stats);
-            }
-        }
-
-        for (RcsAcsProvisioningStats inValid : inValidList) {
-            inValid.stateTimerMillis = getWallTimeMillis() - inValid.stateTimerMillis;
-            mAtomsStorage.addRcsAcsProvisioningStats(inValid);
-            mRcsAcsProvisioningStatsList.remove(inValid);
-        }
-        inValidList.clear();
-    }
-
-    private void flushImsRegistrationFeatureTagStatsInvalid() {
-        List<ImsRegistrationFeatureTagStats> inValidList =
-                new ArrayList<ImsRegistrationFeatureTagStats>();
-
-        int subId;
-        int newCarrierId;
-
-        for (ImsRegistrationFeatureTagStats stats : mImsRegistrationFeatureTagStatsList) {
-            subId = getSubId(stats.slotId);
-            newCarrierId = getCarrierId(subId);
-            if (stats.carrierId != newCarrierId) {
-                inValidList.add(stats);
-            }
-        }
-
-        for (ImsRegistrationFeatureTagStats inValid : inValidList) {
-            inValid.registeredMillis = getWallTimeMillis() - inValid.registeredMillis;
-            mAtomsStorage.addImsRegistrationFeatureTagStats(inValid);
-            mImsRegistrationFeatureTagStatsList.remove(inValid);
-        }
-        inValidList.clear();
-    }
-
-    private LastSipDelegateStat getLastSipDelegateStat(int subId, Set<String> supportedTags) {
-        LastSipDelegateStat stat = null;
-        for (LastSipDelegateStat lastStat : mLastSipDelegateStatList) {
-            if (lastStat.compare(subId, supportedTags)) {
-                stat = lastStat;
-                break;
-            }
-        }
-
-        if (stat == null) {
-            stat = new LastSipDelegateStat(subId, supportedTags);
-            mLastSipDelegateStatList.add(stat);
-        }
-
-        return stat;
-    }
-
-    private void concludeSipDelegateStat() {
-        if (mLastSipDelegateStatList.isEmpty()) {
-            return;
-        }
-        long now = getWallTimeMillis();
-        List<LastSipDelegateStat> sipDelegateStatsCopy = new ArrayList<>(mLastSipDelegateStatList);
-        for (LastSipDelegateStat stat : sipDelegateStatsCopy) {
-            if (stat.isDestroyed()) {
-                stat.conclude(now);
-                mLastSipDelegateStatList.remove(stat);
-            }
-        }
-    }
-
-    private SipTransportFeatureTags getLastFeatureTags(int subId) {
-        SipTransportFeatureTags sipTransportFeatureTags;
-        if (mLastFeatureTagStatMap.containsKey(subId)) {
-            sipTransportFeatureTags = mLastFeatureTagStatMap.get(subId);
-        } else {
-            sipTransportFeatureTags = new SipTransportFeatureTags(subId);
-            mLastFeatureTagStatMap.put(subId, sipTransportFeatureTags);
-        }
-        return sipTransportFeatureTags;
-    }
-    @VisibleForTesting
-    protected boolean isValidCarrierId(int carrierId) {
-        return carrierId > TelephonyManager.UNKNOWN_CARRIER_ID;
-    }
-
-    @VisibleForTesting
-    protected int getSlotId(int subId) {
-        return SubscriptionManager.getPhoneId(subId);
-    }
-
-    @VisibleForTesting
-    protected int getCarrierId(int subId) {
-        int phoneId = SubscriptionManager.getPhoneId(subId);
-        Phone phone = PhoneFactory.getPhone(phoneId);
-        return phone != null ? phone.getCarrierId() : TelephonyManager.UNKNOWN_CARRIER_ID;
-    }
-
-    @VisibleForTesting
-    protected long getWallTimeMillis() {
-        //time in UTC, preserved across reboots, but can be adjusted e.g. by the user or NTP
-        return System.currentTimeMillis();
-    }
-
-    @VisibleForTesting
-    protected void logd(String msg) {
-        Rlog.d(TAG, msg);
-    }
-
-    @VisibleForTesting
-    protected int getSubId(int slotId) {
-        final int[] subIds = SubscriptionManager.getSubId(slotId);
-        int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-        if (subIds != null && subIds.length >= 1) {
-            subId = subIds[0];
-        }
-        return subId;
-    }
-
-    /** Get a enum value from pre-defined feature tag name list */
-    @VisibleForTesting
-    public int convertTagNameToValue(@NonNull String tagName) {
-        return FEATURE_TAGS.getOrDefault(tagName.trim().toLowerCase(),
-                TelephonyProtoEnums.IMS_FEATURE_TAG_CUSTOM);
-    }
-
-    /** Get a enum value from pre-defined service id list */
-    @VisibleForTesting
-    public int convertServiceIdToValue(@NonNull String serviceId) {
-        return SERVICE_IDS.getOrDefault(serviceId.trim().toLowerCase(),
-                IMS_REGISTRATION_SERVICE_DESC_STATS__SERVICE_ID_NAME__SERVICE_ID_CUSTOM);
-    }
-
-    /** Get a enum value from pre-defined message type list */
-    @VisibleForTesting
-    public int convertMessageTypeToValue(@NonNull String messageType) {
-        return MESSAGE_TYPE.getOrDefault(messageType.trim().toLowerCase(),
-                TelephonyProtoEnums.SIP_REQUEST_CUSTOM);
-    }
-
-    /** Get a enum value from pre-defined reason list */
-    @VisibleForTesting
-    public int convertPresenceNotifyReason(@NonNull String reason) {
-        return NOTIFY_REASONS.getOrDefault(reason.trim().toLowerCase(),
-                PRESENCE_NOTIFY_EVENT__REASON__REASON_CUSTOM);
-    }
-
-    /**
-     * Print all metrics data for debugging purposes
-     *
-     * @param rawWriter Print writer
-     */
-    public synchronized void printAllMetrics(PrintWriter rawWriter) {
-        if (mAtomsStorage == null || mAtomsStorage.mAtoms == null) {
-            return;
-        }
-
-        final IndentingPrintWriter pw = new IndentingPrintWriter(rawWriter, "  ");
-        PersistAtomsProto.PersistAtoms metricAtoms = mAtomsStorage.mAtoms;
-
-        pw.println("RcsStats Metrics Proto: ");
-        pw.println("------------------------------------------");
-        pw.println("ImsRegistrationFeatureTagStats:");
-        pw.increaseIndent();
-        for (ImsRegistrationFeatureTagStats stat : metricAtoms.imsRegistrationFeatureTagStats) {
-            pw.println("[" + stat.carrierId + "]"
-                    + " [" + stat.slotId + "]"
-                    + " Feature Tag Name = " + stat.featureTagName
-                    + ", Registration Tech = " + stat.registrationTech
-                    + ", Registered Duration (ms) = " + stat.registeredMillis);
-        }
-        pw.decreaseIndent();
-
-        pw.println("RcsClientProvisioningStats:");
-        pw.increaseIndent();
-        for (RcsClientProvisioningStats stat : metricAtoms.rcsClientProvisioningStats) {
-            pw.println("[" + stat.carrierId + "]"
-                    + " [" + stat.slotId + "]"
-                    + " Event = " + stat.event
-                    + ", Count = " + stat.count);
-        }
-        pw.decreaseIndent();
-
-        pw.println("RcsAcsProvisioningStats:");
-        pw.increaseIndent();
-        for (RcsAcsProvisioningStats stat : metricAtoms.rcsAcsProvisioningStats) {
-            pw.println("[" + stat.carrierId + "]"
-                    + " [" + stat.slotId + "]"
-                    + " Response Code = " + stat.responseCode
-                    + ", Response Type = " + stat.responseType
-                    + ", Single Registration Enabled = " + stat.isSingleRegistrationEnabled
-                    + ", Count = " + stat.count
-                    + ", State Timer (ms) = " + stat.stateTimerMillis);
-        }
-        pw.decreaseIndent();
-
-        pw.println("SipDelegateStats:");
-        pw.increaseIndent();
-        for (SipDelegateStats stat : metricAtoms.sipDelegateStats) {
-            pw.println("[" + stat.carrierId + "]"
-                    + " [" + stat.slotId + "]"
-                    + " [" + stat.dimension + "]"
-                    + " Destroy Reason = " + stat.destroyReason
-                    + ", Uptime (ms) = " + stat.uptimeMillis);
-        }
-        pw.decreaseIndent();
-
-        pw.println("SipTransportFeatureTagStats:");
-        pw.increaseIndent();
-        for (SipTransportFeatureTagStats stat : metricAtoms.sipTransportFeatureTagStats) {
-            pw.println("[" + stat.carrierId + "]"
-                    + " [" + stat.slotId + "]"
-                    + " Feature Tag Name = " + stat.featureTagName
-                    + ", Denied Reason = " + stat.sipTransportDeniedReason
-                    + ", Deregistered Reason = " + stat.sipTransportDeregisteredReason
-                    + ", Associated Time (ms) = " + stat.associatedMillis);
-        }
-        pw.decreaseIndent();
-
-        pw.println("SipMessageResponse:");
-        pw.increaseIndent();
-        for (SipMessageResponse stat : metricAtoms.sipMessageResponse) {
-            pw.println("[" + stat.carrierId + "]"
-                    + " [" + stat.slotId + "]"
-                    + " Message Method = " + stat.sipMessageMethod
-                    + ", Response = " + stat.sipMessageResponse
-                    + ", Direction = " + stat.sipMessageDirection
-                    + ", Error = " + stat.messageError
-                    + ", Count = " + stat.count);
-        }
-        pw.decreaseIndent();
-
-        pw.println("SipTransportSession:");
-        pw.increaseIndent();
-        for (SipTransportSession stat : metricAtoms.sipTransportSession) {
-            pw.println("[" + stat.carrierId + "]"
-                    + " [" + stat.slotId + "]"
-                    + " Session Method = " + stat.sessionMethod
-                    + ", Direction = " + stat.sipMessageDirection
-                    + ", Response = " + stat.sipResponse
-                    + ", Count = " + stat.sessionCount
-                    + ", GraceFully Count = " + stat.endedGracefullyCount);
-        }
-        pw.decreaseIndent();
-
-        pw.println("ImsDedicatedBearerListenerEvent:");
-        pw.increaseIndent();
-        for (ImsDedicatedBearerListenerEvent stat : metricAtoms.imsDedicatedBearerListenerEvent) {
-            pw.println("[" + stat.carrierId + "]"
-                    + " [" + stat.slotId + "]"
-                    + " RAT = " + stat.ratAtEnd
-                    + ", QCI = " + stat.qci
-                    + ", Dedicated Bearer Established = " + stat.dedicatedBearerEstablished
-                    + ", Count = " + stat.eventCount);
-        }
-        pw.decreaseIndent();
-
-        pw.println("ImsDedicatedBearerEvent:");
-        pw.increaseIndent();
-        for (ImsDedicatedBearerEvent stat : metricAtoms.imsDedicatedBearerEvent) {
-            pw.println("[" + stat.carrierId + "]"
-                    + " [" + stat.slotId + "]"
-                    + " RAT = " + stat.ratAtEnd
-                    + ", QCI = " + stat.qci
-                    + ", Bearer State = " + stat.bearerState
-                    + ", Local Connection Info = " + stat.localConnectionInfoReceived
-                    + ", Remote Connection Info = " + stat.remoteConnectionInfoReceived
-                    + ", Listener Existence = " + stat.hasListeners
-                    + ", Count = " + stat.count);
-        }
-        pw.decreaseIndent();
-
-        pw.println("ImsRegistrationServiceDescStats:");
-        pw.increaseIndent();
-        for (ImsRegistrationServiceDescStats stat : metricAtoms.imsRegistrationServiceDescStats) {
-            pw.println("[" + stat.carrierId + "]"
-                    + " [" + stat.slotId + "]"
-                    + " Name = " + stat.serviceIdName
-                    + ", Version = " + stat.serviceIdVersion
-                    + ", Registration Tech = " + stat.registrationTech
-                    + ", Published Time (ms) = " + stat.publishedMillis);
-        }
-        pw.decreaseIndent();
-
-        pw.println("UceEventStats:");
-        pw.increaseIndent();
-        for (UceEventStats stat : metricAtoms.uceEventStats) {
-            pw.println("[" + stat.carrierId + "]"
-                    + " [" + stat.slotId + "]"
-                    + " Type = " + stat.type
-                    + ", Successful = " + stat.successful
-                    + ", Code = " + stat.commandCode
-                    + ", Response = " + stat.networkResponse
-                    + ", Count = " + stat.count);
-        }
-        pw.decreaseIndent();
-
-        pw.println("PresenceNotifyEvent:");
-        pw.increaseIndent();
-        for (PresenceNotifyEvent stat : metricAtoms.presenceNotifyEvent) {
-            pw.println("[" + stat.carrierId + "]"
-                    + " [" + stat.slotId + "]"
-                    + " Reason = " + stat.reason
-                    + ", Body = " + stat.contentBodyReceived
-                    + ", RCS Count = " + stat.rcsCapsCount
-                    + ", MMTEL Count = " + stat.mmtelCapsCount
-                    + ", NoCaps Count = " + stat.noCapsCount
-                    + ", Count = " + stat.count);
-        }
-        pw.decreaseIndent();
-
-        pw.println("GbaEvent:");
-        pw.increaseIndent();
-        for (GbaEvent stat : metricAtoms.gbaEvent) {
-            pw.println("[" + stat.carrierId + "]"
-                    + " [" + stat.slotId + "]"
-                    + " Successful = "  + stat.successful
-                    + ", Fail Reason = " + stat.failedReason
-                    + ", Count = " + stat.count);
-        }
-        pw.decreaseIndent();
-    }
-
-    /**
-     * Reset all events
-     */
-    public synchronized void reset() {
-        if (mAtomsStorage == null || mAtomsStorage.mAtoms == null) {
-            return;
-        }
-
-        PersistAtomsProto.PersistAtoms metricAtoms = mAtomsStorage.mAtoms;
-
-        metricAtoms.imsRegistrationFeatureTagStats =
-                PersistAtomsProto.ImsRegistrationFeatureTagStats.emptyArray();
-        metricAtoms.rcsClientProvisioningStats =
-                PersistAtomsProto.RcsClientProvisioningStats.emptyArray();
-        metricAtoms.rcsAcsProvisioningStats =
-                PersistAtomsProto.RcsAcsProvisioningStats.emptyArray();
-        metricAtoms.sipDelegateStats = PersistAtomsProto.SipDelegateStats.emptyArray();
-        metricAtoms.sipTransportFeatureTagStats =
-                PersistAtomsProto.SipTransportFeatureTagStats.emptyArray();
-        metricAtoms.sipMessageResponse = PersistAtomsProto.SipMessageResponse.emptyArray();
-        metricAtoms.sipTransportSession = PersistAtomsProto.SipTransportSession.emptyArray();
-        metricAtoms.imsDedicatedBearerListenerEvent =
-                PersistAtomsProto.ImsDedicatedBearerListenerEvent.emptyArray();
-        metricAtoms.imsDedicatedBearerEvent =
-                PersistAtomsProto.ImsDedicatedBearerEvent.emptyArray();
-        metricAtoms.imsRegistrationServiceDescStats =
-                PersistAtomsProto.ImsRegistrationServiceDescStats.emptyArray();
-        metricAtoms.uceEventStats = PersistAtomsProto.UceEventStats.emptyArray();
-        metricAtoms.presenceNotifyEvent = PersistAtomsProto.PresenceNotifyEvent.emptyArray();
-        metricAtoms.gbaEvent = PersistAtomsProto.GbaEvent.emptyArray();
-    }
-
-    /**
-     * Convert the PersistAtomsProto into Base-64 encoded string
-     *
-     * @return Encoded string
-     */
-    public String buildLog() {
-        PersistAtomsProto.PersistAtoms log = buildProto();
-        return Base64.encodeToString(
-                PersistAtomsProto.PersistAtoms.toByteArray(log), Base64.DEFAULT);
-    }
-
-    /**
-     * Build the PersistAtomsProto
-     *
-     * @return PersistAtomsProto.PersistAtoms
-     */
-    public PersistAtomsProto.PersistAtoms buildProto() {
-        PersistAtomsProto.PersistAtoms log = new PersistAtomsProto.PersistAtoms();
-
-        PersistAtomsProto.PersistAtoms atoms = mAtomsStorage.mAtoms;
-        log.imsRegistrationFeatureTagStats = Arrays.copyOf(atoms.imsRegistrationFeatureTagStats,
-                atoms.imsRegistrationFeatureTagStats.length);
-        log.rcsClientProvisioningStats = Arrays.copyOf(atoms.rcsClientProvisioningStats,
-                atoms.rcsClientProvisioningStats.length);
-        log.rcsAcsProvisioningStats = Arrays.copyOf(atoms.rcsAcsProvisioningStats,
-                atoms.rcsAcsProvisioningStats.length);
-        log.sipDelegateStats = Arrays.copyOf(atoms.sipDelegateStats, atoms.sipDelegateStats.length);
-        log.sipTransportFeatureTagStats = Arrays.copyOf(atoms.sipTransportFeatureTagStats,
-                atoms.sipTransportFeatureTagStats.length);
-        log.sipMessageResponse = Arrays.copyOf(atoms.sipMessageResponse,
-                atoms.sipMessageResponse.length);
-        log.sipTransportSession = Arrays.copyOf(atoms.sipTransportSession,
-                atoms.sipTransportSession.length);
-        log.imsDedicatedBearerListenerEvent = Arrays.copyOf(atoms.imsDedicatedBearerListenerEvent,
-                atoms.imsDedicatedBearerListenerEvent.length);
-        log.imsDedicatedBearerEvent = Arrays.copyOf(atoms.imsDedicatedBearerEvent,
-                atoms.imsDedicatedBearerEvent.length);
-        log.imsRegistrationServiceDescStats = Arrays.copyOf(atoms.imsRegistrationServiceDescStats,
-                atoms.imsRegistrationServiceDescStats.length);
-        log.uceEventStats = Arrays.copyOf(atoms.uceEventStats, atoms.uceEventStats.length);
-        log.presenceNotifyEvent = Arrays.copyOf(atoms.presenceNotifyEvent,
-                atoms.presenceNotifyEvent.length);
-        log.gbaEvent = Arrays.copyOf(atoms.gbaEvent, atoms.gbaEvent.length);
-
-        return log;
-    }
-
-}
diff --git a/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java b/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java
index df4db73..a45e43f 100644
--- a/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java
+++ b/src/java/com/android/internal/telephony/metrics/ServiceStateStats.java
@@ -29,7 +29,6 @@
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.ServiceStateTracker;
-import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.nano.PersistAtomsProto.CellularDataServiceSwitch;
 import com.android.internal.telephony.nano.PersistAtomsProto.CellularServiceState;
 import com.android.telephony.Rlog;
@@ -59,23 +58,6 @@
         addServiceState(lastState, now);
     }
 
-    /** Updates service state when IMS voice registration changes. */
-    public void onImsVoiceRegistrationChanged() {
-        final long now = getTimeMillis();
-        TimestampedServiceState lastState =
-                mLastState.getAndUpdate(
-                        state -> {
-                            if (state.mServiceState == null) {
-                                return new TimestampedServiceState(null, now);
-                            }
-                            CellularServiceState newServiceState = copyOf(state.mServiceState);
-                            newServiceState.voiceRat =
-                                    getVoiceRat(mPhone, getServiceStateForPhone(mPhone));
-                            return new TimestampedServiceState(newServiceState, now);
-                        });
-        addServiceState(lastState, now);
-    }
-
     /** Updates the current service state. */
     public void onServiceStateChanged(ServiceState serviceState) {
         final long now = getTimeMillis();
@@ -92,7 +74,6 @@
             newState.simSlotIndex = mPhone.getPhoneId();
             newState.isMultiSim = SimSlotState.isMultiSim();
             newState.carrierId = mPhone.getCarrierId();
-            newState.isEmergencyOnly = isEmergencyOnly(serviceState);
 
             TimestampedServiceState prevState =
                     mLastState.getAndSet(new TimestampedServiceState(newState, now));
@@ -151,26 +132,24 @@
     }
 
     /**
-     * Returns the band used from the given phone, or {@code 0} if it is invalid or cannot be
-     * determined.
+     * Returns the band used from the given phone and RAT, or {@code 0} if it is invalid or cannot
+     * be determined.
      */
-    static int getBand(Phone phone) {
+    static int getBand(Phone phone, @NetworkType int rat) {
         ServiceState serviceState = getServiceStateForPhone(phone);
-        return getBand(serviceState);
+        return getBand(serviceState, rat);
     }
 
     /**
-     * Returns the band used from the given service state, or {@code 0} if it is invalid or cannot
-     * be determined.
+     * Returns the band used from the given service state and RAT, or {@code 0} if it is invalid or
+     * cannot be determined.
      */
-    static int getBand(@Nullable ServiceState serviceState) {
+    static int getBand(@Nullable ServiceState serviceState, @NetworkType int rat) {
         if (serviceState == null) {
-            Rlog.w(TAG, "getBand: serviceState=null");
             return 0; // Band unknown
         }
         int chNumber = serviceState.getChannelNumber();
         int band;
-        @NetworkType int rat = getRat(serviceState);
         switch (rat) {
             case TelephonyManager.NETWORK_TYPE_GSM:
             case TelephonyManager.NETWORK_TYPE_GPRS:
@@ -189,16 +168,10 @@
                 band = AccessNetworkUtils.getOperatingBandForEarfcn(chNumber);
                 break;
             default:
-                Rlog.w(TAG, "getBand: unknown WWAN RAT " + rat);
                 band = 0;
                 break;
         }
-        if (band == AccessNetworkUtils.INVALID_BAND) {
-            Rlog.w(TAG, "getBand: band invalid for rat=" + rat + " ch=" + chNumber);
-            return 0;
-        } else {
-            return band;
-        }
+        return band == AccessNetworkUtils.INVALID_BAND ? 0 : band;
     }
 
     private static CellularServiceState copyOf(CellularServiceState state) {
@@ -213,7 +186,6 @@
         copy.isMultiSim = state.isMultiSim;
         copy.carrierId = state.carrierId;
         copy.totalTimeMillis = state.totalTimeMillis;
-        copy.isEmergencyOnly = state.isEmergencyOnly;
         return copy;
     }
 
@@ -228,68 +200,24 @@
         return state.getVoiceRegState() == ServiceState.STATE_POWER_OFF;
     }
 
-    /**
-     * Returns the current voice RAT from IMS registration if present, otherwise from the service
-     * state.
-     */
-    static @NetworkType int getVoiceRat(Phone phone, @Nullable ServiceState state) {
-        if (state == null) {
-            return TelephonyManager.NETWORK_TYPE_UNKNOWN;
-        }
-        ImsPhone imsPhone = (ImsPhone) phone.getImsPhone();
-        if (imsPhone != null) {
-            @NetworkType int imsVoiceRat = imsPhone.getImsStats().getImsVoiceRadioTech();
-            if (imsVoiceRat != TelephonyManager.NETWORK_TYPE_UNKNOWN) {
-                // If IMS is over WWAN but WWAN PS is not in-service, then IMS RAT is invalid
-                boolean isImsVoiceRatValid =
-                        (imsVoiceRat == TelephonyManager.NETWORK_TYPE_IWLAN
-                                || getDataRat(state) != TelephonyManager.NETWORK_TYPE_UNKNOWN);
-                return isImsVoiceRatValid ? imsVoiceRat : TelephonyManager.NETWORK_TYPE_UNKNOWN;
-            }
-        }
-
-        // If WWAN CS is not in-service, we should return NETWORK_TYPE_UNKNOWN
-        final NetworkRegistrationInfo wwanRegInfo =
-                state.getNetworkRegistrationInfo(
-                        NetworkRegistrationInfo.DOMAIN_CS,
-                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        return wwanRegInfo != null && wwanRegInfo.isInService()
-                ? wwanRegInfo.getAccessNetworkTechnology()
-                : TelephonyManager.NETWORK_TYPE_UNKNOWN;
+    private static @NetworkType int getVoiceRat(Phone phone, ServiceState state) {
+        boolean isWifiCall =
+                phone.getImsPhone() != null
+                        && phone.getImsPhone().isWifiCallingEnabled()
+                        && state.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_IWLAN;
+        return isWifiCall ? TelephonyManager.NETWORK_TYPE_IWLAN : state.getVoiceNetworkType();
     }
 
-    /**
-     * Returns RAT used by WWAN.
-     *
-     * <p>Returns PS WWAN RAT, or CS WWAN RAT if PS WWAN RAT is unavailable.
-     */
-    private static @NetworkType int getRat(ServiceState state) {
-        @NetworkType int rat = getDataRat(state);
-        if (rat == TelephonyManager.NETWORK_TYPE_UNKNOWN) {
-            rat = state.getVoiceNetworkType();
-        }
-        return rat;
-    }
-
-    /** Returns PS (data) RAT used by WWAN. */
-    static @NetworkType int getDataRat(ServiceState state) {
+    private static @NetworkType int getDataRat(ServiceState state) {
         final NetworkRegistrationInfo wwanRegInfo =
                 state.getNetworkRegistrationInfo(
                         NetworkRegistrationInfo.DOMAIN_PS,
                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        return wwanRegInfo != null && wwanRegInfo.isInService()
+        return wwanRegInfo != null
                 ? wwanRegInfo.getAccessNetworkTechnology()
                 : TelephonyManager.NETWORK_TYPE_UNKNOWN;
     }
 
-    private static boolean isEmergencyOnly(ServiceState state) {
-        NetworkRegistrationInfo regInfo =
-                state.getNetworkRegistrationInfo(
-                        NetworkRegistrationInfo.DOMAIN_CS,
-                        AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        return regInfo != null && !regInfo.isInService() && regInfo.isEmergencyEnabled();
-    }
-
     private static boolean isEndc(ServiceState state) {
         if (getDataRat(state) != TelephonyManager.NETWORK_TYPE_LTE) {
             return false;
diff --git a/src/java/com/android/internal/telephony/metrics/SimSlotState.java b/src/java/com/android/internal/telephony/metrics/SimSlotState.java
index f840894..95fa042 100644
--- a/src/java/com/android/internal/telephony/metrics/SimSlotState.java
+++ b/src/java/com/android/internal/telephony/metrics/SimSlotState.java
@@ -19,7 +19,6 @@
 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
 import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UiccSlot;
 import com.android.telephony.Rlog;
 
@@ -47,15 +46,9 @@
                     if (slot.isEuicc()) {
                         // need to check active profiles besides the presence of eSIM cards
                         UiccCard card = slot.getUiccCard();
-                        if (card != null) {
-                            // Check each port on the EuiccCard
-                            UiccPort[] uiccPorts = card.getUiccPortList();
-                            for (UiccPort port : uiccPorts) {
-                                if (port != null && port.getNumApplications() > 0) {
-                                    numActiveSims++;
-                                    numActiveEsims++;
-                                }
-                            }
+                        if (card != null && card.getNumApplications() > 0) {
+                            numActiveSims++;
+                            numActiveEsims++;
                         }
                     } else {
                         // physical SIMs do not always have non-null card
diff --git a/src/java/com/android/internal/telephony/metrics/SmsStats.java b/src/java/com/android/internal/telephony/metrics/SmsStats.java
index af7e23e..5268aba 100644
--- a/src/java/com/android/internal/telephony/metrics/SmsStats.java
+++ b/src/java/com/android/internal/telephony/metrics/SmsStats.java
@@ -154,19 +154,17 @@
 
     /** Create a new atom when an outgoing SMS is sent. */
     public void onOutgoingSms(boolean isOverIms, boolean is3gpp2, boolean fallbackToCs,
-            @SmsManager.Result int errorCode, long messageId, boolean isFromDefaultApp,
-            long intervalMillis) {
+            @SmsManager.Result int errorCode, long messageId, boolean isFromDefaultApp) {
         onOutgoingSms(isOverIms, is3gpp2, fallbackToCs, errorCode, NO_ERROR_CODE,
-                messageId, isFromDefaultApp, intervalMillis);
+                messageId, isFromDefaultApp);
     }
 
     /** Create a new atom when an outgoing SMS is sent. */
     public void onOutgoingSms(boolean isOverIms, boolean is3gpp2, boolean fallbackToCs,
             @SmsManager.Result int errorCode, int radioSpecificErrorCode, long messageId,
-            boolean isFromDefaultApp, long intervalMillis) {
+            boolean isFromDefaultApp) {
         OutgoingSms proto =
-                getOutgoingDefaultProto(is3gpp2, isOverIms, messageId, isFromDefaultApp,
-                        intervalMillis);
+                getOutgoingDefaultProto(is3gpp2, isOverIms, messageId, isFromDefaultApp);
 
         if (isOverIms) {
             // Populate error code and result for IMS case
@@ -219,7 +217,7 @@
 
     /** Create a proto for a normal {@code OutgoingSms} with default values. */
     private OutgoingSms getOutgoingDefaultProto(boolean is3gpp2, boolean isOverIms,
-            long messageId, boolean isFromDefaultApp, long intervalMillis) {
+            long messageId, boolean isFromDefaultApp) {
         OutgoingSms proto = new OutgoingSms();
         proto.smsFormat = getSmsFormat(is3gpp2);
         proto.smsTech = getSmsTech(isOverIms, is3gpp2);
@@ -237,7 +235,6 @@
         // Setting the retry ID to zero. If needed, it will be incremented when the atom is added
         // in the persistent storage.
         proto.retryId = 0;
-        proto.intervalMillis = intervalMillis;
         return proto;
     }
 
diff --git a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
index 5b47ae5..5e43876 100644
--- a/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
+++ b/src/java/com/android/internal/telephony/metrics/TelephonyMetrics.java
@@ -31,7 +31,7 @@
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SEND_SMS;
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SEND_SMS_EXPECT_MORE;
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SETUP_DATA_CALL;
-import static com.android.internal.telephony.data.LinkBandwidthEstimator.NUM_SIGNAL_LEVEL;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.NUM_SIGNAL_LEVEL;
 import static com.android.internal.telephony.nano.TelephonyProto.PdpType.PDP_TYPE_IP;
 import static com.android.internal.telephony.nano.TelephonyProto.PdpType.PDP_TYPE_IPV4V6;
 import static com.android.internal.telephony.nano.TelephonyProto.PdpType.PDP_TYPE_IPV6;
@@ -85,7 +85,7 @@
 import com.android.internal.telephony.SmsController;
 import com.android.internal.telephony.SmsResponse;
 import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.data.LinkBandwidthEstimator;
+import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.imsphone.ImsPhoneCall;
 import com.android.internal.telephony.nano.TelephonyProto;
@@ -290,14 +290,12 @@
                     break;
                 case "--metricsproto":
                     pw.println(convertProtoToBase64String(buildProto()));
-                    pw.println(RcsStats.getInstance().buildLog());
                     if (reset) {
                         reset();
                     }
                     break;
                 case "--metricsprototext":
                     pw.println(buildProto().toString());
-                    pw.println(RcsStats.getInstance().buildProto().toString());
                     break;
             }
         }
@@ -646,8 +644,6 @@
         for (BwEstimationStats stats : mBwEstStatsMapList.get(1).values()) {
             pw.println(stats.toString());
         }
-
-        RcsStats.getInstance().printAllMetrics(rawWriter);
     }
 
     /**
@@ -749,8 +745,6 @@
                     .setRadioState(mLastRadioState.get(key)).build();
             addTelephonyEvent(event);
         }
-
-        RcsStats.getInstance().reset();
     }
 
     /**
@@ -2198,13 +2192,6 @@
             cq.rtpInactivityDetected = callQuality.isRtpInactivityDetected();
             cq.rxSilenceDetected = callQuality.isIncomingSilenceDetectedAtCallSetup();
             cq.txSilenceDetected = callQuality.isOutgoingSilenceDetectedAtCallSetup();
-            cq.voiceFrames = callQuality.getNumVoiceFrames();
-            cq.noDataFrames = callQuality.getNumNoDataFrames();
-            cq.rtpDroppedPackets = callQuality.getNumDroppedRtpPackets();
-            cq.minPlayoutDelayMillis = callQuality.getMinPlayoutDelayMillis();
-            cq.maxPlayoutDelayMillis = callQuality.getMaxPlayoutDelayMillis();
-            cq.rxRtpSidPackets = callQuality.getNumRtpSidPacketsReceived();
-            cq.rtpDuplicatePackets = callQuality.getNumRtpDuplicatePackets();
         }
         return cq;
     }
diff --git a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
index 5f9f275..9b988ad 100644
--- a/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
+++ b/src/java/com/android/internal/telephony/metrics/VoiceCallSessionStats.java
@@ -19,13 +19,6 @@
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_UNKNOWN;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_FIVE_MINUTES;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_HOUR;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_MINUTE;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_TEN_MINUTES;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_THIRTY_MINUTES;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_MORE_THAN_ONE_HOUR;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_FULLBAND;
@@ -89,7 +82,7 @@
 public class VoiceCallSessionStats {
     private static final String TAG = VoiceCallSessionStats.class.getSimpleName();
 
-    // Upper bounds of each call setup duration category in milliseconds.
+    /** Upper bounds of each call setup duration category in milliseconds. */
     private static final int CALL_SETUP_DURATION_UNKNOWN = 0;
     private static final int CALL_SETUP_DURATION_EXTREMELY_FAST = 400;
     private static final int CALL_SETUP_DURATION_ULTRA_FAST = 700;
@@ -101,21 +94,14 @@
     private static final int CALL_SETUP_DURATION_ULTRA_SLOW = 10000;
     // CALL_SETUP_DURATION_EXTREMELY_SLOW has no upper bound (it includes everything above 10000)
 
-    // Upper bounds of each call duration category in milliseconds.
-    private static final int CALL_DURATION_ONE_MINUTE = 60000;
-    private static final int CALL_DURATION_FIVE_MINUTES = 300000;
-    private static final int CALL_DURATION_TEN_MINUTES = 600000;
-    private static final int CALL_DURATION_THIRTY_MINUTES = 1800000;
-    private static final int CALL_DURATION_ONE_HOUR = 3600000;
-
     /** Number of buckets for codec quality, from UNKNOWN to FULLBAND. */
     private static final int CODEC_QUALITY_COUNT = 5;
 
     /**
      * Threshold to calculate the main audio codec quality of the call.
      *
-     * <p>The audio codec quality was equal to or greater than the main audio codec quality for at
-     * least 70% of the call.
+     * The audio codec quality was equal to or greater than the main audio codec quality for
+     * at least 70% of the call.
      */
     private static final int MAIN_CODEC_QUALITY_THRESHOLD = 70;
 
@@ -128,9 +114,6 @@
     /** Holds setup duration buckets with values as their upper bounds in milliseconds. */
     private static final SparseIntArray CALL_SETUP_DURATION_MAP = buildCallSetupDurationMap();
 
-    /** Holds call duration buckets with values as their upper bounds in milliseconds. */
-    private static final SparseIntArray CALL_DURATION_MAP = buildCallDurationMap();
-
     /**
      * Tracks statistics for each call connection, indexed with ID returned by {@link
      * #getConnectionId}.
@@ -138,10 +121,9 @@
     private final SparseArray<VoiceCallSession> mCallProtos = new SparseArray<>();
 
     /**
-     * Tracks usage of codecs for each call.
-     *
-     * <p>The outer array is used to map each connection id to the corresponding codec usage. The
-     * inner array is used to map timestamp (key) with the codec in use (value).
+     * Tracks usage of codecs for each call. The outer array is used to map each connection id to
+     * the corresponding codec usage. The inner array is used to map timestamp (key) with the
+     * codec in use (value).
      */
     private final SparseArray<LongSparseArray<Integer>> mCodecUsage = new SparseArray<>();
 
@@ -170,7 +152,7 @@
     /** Updates internal states when previous CS calls are accepted to track MT call setup time. */
     public synchronized void onRilAcceptCall(List<Connection> connections) {
         for (Connection conn : connections) {
-            acceptCall(conn);
+            addCall(conn);
         }
     }
 
@@ -191,10 +173,7 @@
                     addCall(conn);
                     checkCallSetup(conn, mCallProtos.get(id));
                 } else {
-                    logd(
-                            "onRilCallListChanged: skip adding disconnected connection,"
-                                    + " connectionId=%d",
-                            id);
+                    logd("onRilCallListChanged: skip adding disconnected connection");
                 }
             } else {
                 VoiceCallSession proto = mCallProtos.get(id);
@@ -206,7 +185,6 @@
                     proto.disconnectReasonCode = conn.getDisconnectCause();
                     proto.disconnectExtraCode = conn.getPreciseDisconnectCause();
                     proto.disconnectExtraMessage = conn.getVendorDisconnectCause();
-                    proto.callDuration = classifyCallDuration(conn.getDurationMillis());
                     finishCall(id);
                 }
             }
@@ -236,7 +214,7 @@
     /** Updates internal states when previous IMS calls are accepted to track MT call setup time. */
     public synchronized void onImsAcceptCall(List<Connection> connections) {
         for (Connection conn : connections) {
-            acceptCall(conn);
+            addCall(conn);
         }
     }
 
@@ -247,19 +225,19 @@
             List<Integer> imsConnIds = getImsConnectionIds();
             if (imsConnIds.size() == 1) {
                 loge("onImsCallTerminated: ending IMS call w/ conn=null");
-                finishImsCall(imsConnIds.get(0), reasonInfo, 0);
+                finishImsCall(imsConnIds.get(0), reasonInfo);
             } else {
                 loge("onImsCallTerminated: %d IMS calls w/ conn=null", imsConnIds.size());
             }
         } else {
             int id = getConnectionId(conn);
             if (mCallProtos.contains(id)) {
-                finishImsCall(id, reasonInfo, conn.getDurationMillis());
+                finishImsCall(id, reasonInfo);
             } else {
-                loge("onImsCallTerminated: untracked connection, connectionId=%d", id);
+                loge("onImsCallTerminated: untracked connection");
                 // fake a call so at least some info can be tracked
                 addCall(conn);
-                finishImsCall(id, reasonInfo, conn.getDurationMillis());
+                finishImsCall(id, reasonInfo);
             }
         }
     }
@@ -276,7 +254,7 @@
         int id = getConnectionId(conn);
         VoiceCallSession proto = mCallProtos.get(id);
         if (proto == null) {
-            loge("onAudioCodecChanged: untracked connection, connectionId=%d", id);
+            loge("onAudioCodecChanged: untracked connection");
             return;
         }
         int codec = audioQualityToCodec(proto.bearerAtEnd, audioQuality);
@@ -297,10 +275,10 @@
         int id = getConnectionId(conn);
         VoiceCallSession proto = mCallProtos.get(id);
         if (proto == null) {
-            loge("onVideoStateChange: untracked connection, connectionId=%d", id);
+            loge("onVideoStateChange: untracked connection");
             return;
         }
-        logd("onVideoStateChange: video state=%d, connectionId=%d", videoState, id);
+        logd("Video state = " + videoState);
         if (videoState != VideoProfile.STATE_AUDIO_ONLY) {
             proto.videoEnabled = true;
         }
@@ -311,10 +289,10 @@
         int id = getConnectionId(conn);
         VoiceCallSession proto = mCallProtos.get(id);
         if (proto == null) {
-            loge("onMultipartyChange: untracked connection, connectionId=%d", id);
+            loge("onMultipartyChange: untracked connection");
             return;
         }
-        logd("onMultipartyChange: isMultiparty=%b, connectionId=%d", isMultiParty, id);
+        logd("Multiparty = " + isMultiParty);
         if (isMultiParty) {
             proto.isMultiparty = true;
         }
@@ -328,12 +306,11 @@
      */
     public synchronized void onCallStateChanged(Call call) {
         for (Connection conn : call.getConnections()) {
-            int id = getConnectionId(conn);
-            VoiceCallSession proto = mCallProtos.get(id);
+            VoiceCallSession proto = mCallProtos.get(getConnectionId(conn));
             if (proto != null) {
                 checkCallSetup(conn, proto);
             } else {
-                loge("onCallStateChanged: untracked connection, connectionId=%d", id);
+                loge("onCallStateChanged: untracked connection");
             }
         }
     }
@@ -388,19 +365,6 @@
 
     /* internal */
 
-    /** Handles ringing MT call getting accepted. */
-    private void acceptCall(Connection conn) {
-        int id = getConnectionId(conn);
-        if (mCallProtos.contains(id)) {
-            logd("acceptCall: resetting setup info, connectionId=%d", id);
-            VoiceCallSession proto = mCallProtos.get(id);
-            proto.setupBeginMillis = getTimeMillis();
-            proto.setupDuration = VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
-        } else {
-            loge("acceptCall: untracked connection, connectionId=%d", id);
-        }
-    }
-
     /**
      * Adds a call connection.
      *
@@ -410,63 +374,59 @@
     private void addCall(Connection conn) {
         int id = getConnectionId(conn);
         if (mCallProtos.contains(id)) {
-            loge(
-                    "addCall: already tracked connection, connectionId=%d, connectionInfo=%s",
-                    id, conn);
-            return;
+            // mostly handles ringing MT call getting accepted (MT call setup begins)
+            logd("addCall: resetting setup info");
+            VoiceCallSession proto = mCallProtos.get(id);
+            proto.setupBeginMillis = getTimeMillis();
+            proto.setupDuration = VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
+        } else {
+            int bearer = getBearer(conn);
+            ServiceState serviceState = getServiceState();
+            @NetworkType int rat = getRat(serviceState);
+
+            VoiceCallSession proto = new VoiceCallSession();
+
+            proto.bearerAtStart = bearer;
+            proto.bearerAtEnd = bearer;
+            proto.direction = getDirection(conn);
+            proto.setupDuration = VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
+            proto.setupFailed = true;
+            proto.disconnectReasonCode = conn.getDisconnectCause();
+            proto.disconnectExtraCode = conn.getPreciseDisconnectCause();
+            proto.disconnectExtraMessage = conn.getVendorDisconnectCause();
+            proto.ratAtStart = rat;
+            proto.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
+            proto.ratAtEnd = rat;
+            proto.ratSwitchCount = 0L;
+            proto.codecBitmask = 0L;
+            proto.simSlotIndex = mPhoneId;
+            proto.isMultiSim = SimSlotState.isMultiSim();
+            proto.isEsim = SimSlotState.isEsim(mPhoneId);
+            proto.carrierId = mPhone.getCarrierId();
+            proto.srvccCompleted = false;
+            proto.srvccFailureCount = 0L;
+            proto.srvccCancellationCount = 0L;
+            proto.rttEnabled = false;
+            proto.isEmergency = conn.isEmergencyCall();
+            proto.isRoaming = serviceState != null ? serviceState.getVoiceRoaming() : false;
+            proto.isMultiparty = conn.isMultiparty();
+
+            // internal fields for tracking
+            proto.setupBeginMillis = getTimeMillis();
+
+            proto.concurrentCallCountAtStart = mCallProtos.size();
+            mCallProtos.put(id, proto);
+
+            // RAT call count needs to be updated
+            updateRatTracker(serviceState);
         }
-        int bearer = getBearer(conn);
-        ServiceState serviceState = getServiceState();
-        @NetworkType int rat = ServiceStateStats.getVoiceRat(mPhone, serviceState);
-
-        VoiceCallSession proto = new VoiceCallSession();
-
-        proto.bearerAtStart = bearer;
-        proto.bearerAtEnd = bearer;
-        proto.direction = getDirection(conn);
-        proto.setupDuration = VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_UNKNOWN;
-        proto.setupFailed = true;
-        proto.disconnectReasonCode = conn.getDisconnectCause();
-        proto.disconnectExtraCode = conn.getPreciseDisconnectCause();
-        proto.disconnectExtraMessage = conn.getVendorDisconnectCause();
-        proto.ratAtStart = rat;
-        proto.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-        proto.ratAtEnd = rat;
-        proto.ratSwitchCount = 0L;
-        proto.codecBitmask = 0L;
-        proto.simSlotIndex = mPhoneId;
-        proto.isMultiSim = SimSlotState.isMultiSim();
-        proto.isEsim = SimSlotState.isEsim(mPhoneId);
-        proto.carrierId = mPhone.getCarrierId();
-        proto.srvccCompleted = false;
-        proto.srvccFailureCount = 0L;
-        proto.srvccCancellationCount = 0L;
-        proto.rttEnabled = false;
-        proto.isEmergency = conn.isEmergencyCall();
-        proto.isRoaming = serviceState != null ? serviceState.getVoiceRoaming() : false;
-        proto.isMultiparty = conn.isMultiparty();
-
-        // internal fields for tracking
-        proto.setupBeginMillis = getTimeMillis();
-
-        // audio codec might have already been set
-        int codec = audioQualityToCodec(bearer, conn.getAudioCodec());
-        if (codec != AudioCodec.AUDIO_CODEC_UNKNOWN) {
-            proto.codecBitmask = (1L << codec);
-        }
-
-        proto.concurrentCallCountAtStart = mCallProtos.size();
-        mCallProtos.put(id, proto);
-
-        // RAT call count needs to be updated
-        updateRatTracker(serviceState);
     }
 
     /** Sends the call metrics to persist storage when it is finished. */
     private void finishCall(int connectionId) {
         VoiceCallSession proto = mCallProtos.get(connectionId);
         if (proto == null) {
-            loge("finishCall: could not find call to be removed, connectionId=%d", connectionId);
+            loge("finishCall: could not find call to be removed");
             return;
         }
         mCallProtos.delete(connectionId);
@@ -502,15 +462,14 @@
     }
 
     private void setRttStarted(ImsPhoneConnection conn) {
-        int id = getConnectionId(conn);
-        VoiceCallSession proto = mCallProtos.get(id);
+        VoiceCallSession proto = mCallProtos.get(getConnectionId(conn));
         if (proto == null) {
-            loge("onRttStarted: untracked connection, connectionId=%d", id);
+            loge("onRttStarted: untracked connection");
             return;
         }
         // should be IMS w/o SRVCC
         if (proto.bearerAtStart != getBearer(conn) || proto.bearerAtEnd != getBearer(conn)) {
-            loge("onRttStarted: connection bearer mismatch but proceeding, connectionId=%d", id);
+            loge("onRttStarted: connection bearer mismatch but proceeding");
         }
         proto.rttEnabled = true;
     }
@@ -551,7 +510,7 @@
             proto.setupFailed = false;
             // Track RAT when voice call is connected.
             ServiceState serviceState = getServiceState();
-            proto.ratAtConnected = ServiceStateStats.getVoiceRat(mPhone, serviceState);
+            proto.ratAtConnected = getRat(serviceState);
             // Reset list of codecs with the last codec at the present time. In this way, we
             // track codec quality only after call is connected and not while ringing.
             resetCodecList(conn);
@@ -559,9 +518,8 @@
     }
 
     private void updateRatTracker(ServiceState state) {
-        @NetworkType int rat = ServiceStateStats.getVoiceRat(mPhone, state);
-        int band =
-                (rat == TelephonyManager.NETWORK_TYPE_IWLAN) ? 0 : ServiceStateStats.getBand(state);
+        @NetworkType int rat = getRat(state);
+        int band = ServiceStateStats.getBand(state, rat);
 
         mRatUsage.add(mPhone.getCarrierId(), rat, getTimeMillis(), getConnectionIds());
         for (int i = 0; i < mCallProtos.size(); i++) {
@@ -575,13 +533,12 @@
         }
     }
 
-    private void finishImsCall(int id, ImsReasonInfo reasonInfo, long durationMillis) {
+    private void finishImsCall(int id, ImsReasonInfo reasonInfo) {
         VoiceCallSession proto = mCallProtos.get(id);
         proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
         proto.disconnectReasonCode = reasonInfo.mCode;
         proto.disconnectExtraCode = reasonInfo.mExtraCode;
         proto.disconnectExtraMessage = ImsStats.filterExtraMessage(reasonInfo.mExtraMessage);
-        proto.callDuration = classifyCallDuration(durationMillis);
         finishCall(id);
     }
 
@@ -610,6 +567,17 @@
         }
     }
 
+    private @NetworkType int getRat(@Nullable ServiceState state) {
+        if (state == null) {
+            return TelephonyManager.NETWORK_TYPE_UNKNOWN;
+        }
+        boolean isWifiCall =
+                mPhone.getImsPhone() != null
+                        && mPhone.getImsPhone().isWifiCallingEnabled()
+                        && state.getDataNetworkType() == TelephonyManager.NETWORK_TYPE_IWLAN;
+        return isWifiCall ? TelephonyManager.NETWORK_TYPE_IWLAN : state.getVoiceNetworkType();
+    }
+
     /** Returns the signal strength. */
     private int getSignalStrength(@NetworkType int rat) {
         if (rat == TelephonyManager.NETWORK_TYPE_IWLAN) {
@@ -629,8 +597,8 @@
             int level = wifiManager.calculateSignalLevel(wifiInfo.getRssi());
             int max = wifiManager.getMaxSignalLevel();
             // Scale result into 0 to 4 range.
-            result =
-                    VOICE_CALL_SESSION__SIGNAL_STRENGTH_AT_END__SIGNAL_STRENGTH_GREAT * level / max;
+            result = VOICE_CALL_SESSION__SIGNAL_STRENGTH_AT_END__SIGNAL_STRENGTH_GREAT
+                    * level / max;
             logd("WiFi level: " + result + " (" + level + "/" + max + ")");
         }
         return result;
@@ -691,7 +659,7 @@
     }
 
     private int getCodecQuality(int codec) {
-        switch (codec) {
+        switch(codec) {
             case AudioCodec.AUDIO_CODEC_AMR:
             case AudioCodec.AUDIO_CODEC_QCELP13K:
             case AudioCodec.AUDIO_CODEC_EVRC:
@@ -756,19 +724,6 @@
         return VOICE_CALL_SESSION__SETUP_DURATION__CALL_SETUP_DURATION_EXTREMELY_SLOW;
     }
 
-    private static int classifyCallDuration(long durationMillis) {
-        if (durationMillis == 0L) {
-            return VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
-        }
-        // keys in CALL_SETUP_DURATION_MAP are upper bounds in ascending order
-        for (int i = 0; i < CALL_DURATION_MAP.size(); i++) {
-            if (durationMillis < CALL_DURATION_MAP.keyAt(i)) {
-                return CALL_DURATION_MAP.valueAt(i);
-            }
-        }
-        return VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_MORE_THAN_ONE_HOUR;
-    }
-
     /**
      * Generates an ID for each connection, which should be the same for IMS and CS connections
      * involved in the same SRVCC.
@@ -868,27 +823,4 @@
 
         return map;
     }
-
-    private static SparseIntArray buildCallDurationMap() {
-        SparseIntArray map = new SparseIntArray();
-
-        map.put(
-                CALL_DURATION_ONE_MINUTE,
-                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_MINUTE);
-        map.put(
-                CALL_DURATION_FIVE_MINUTES,
-                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_FIVE_MINUTES);
-        map.put(
-                CALL_DURATION_TEN_MINUTES,
-                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_TEN_MINUTES);
-        map.put(
-                CALL_DURATION_THIRTY_MINUTES,
-                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_THIRTY_MINUTES);
-        map.put(
-                CALL_DURATION_ONE_HOUR,
-                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_HOUR);
-        // anything above would be MORE_THAN_ONE_HOUR
-
-        return map;
-    }
 }
diff --git a/src/java/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactory.java b/src/java/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactory.java
index 5cb7cf3..aa72722 100644
--- a/src/java/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactory.java
+++ b/src/java/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactory.java
@@ -21,10 +21,10 @@
 import android.content.Context;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
+import android.os.TimestampedValue;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.NitzData;
-import com.android.internal.telephony.NitzSignal;
 import com.android.internal.telephony.NitzStateMachine.DeviceState;
 import com.android.internal.telephony.nitz.NitzStateMachineImpl.NitzSignalInputFilterPredicate;
 import com.android.telephony.Rlog;
@@ -84,8 +84,8 @@
          */
         @Nullable
         Boolean mustProcessNitzSignal(
-                @Nullable NitzSignal previousSignal,
-                @NonNull NitzSignal newSignal);
+                @Nullable TimestampedValue<NitzData> previousSignal,
+                @NonNull TimestampedValue<NitzData> newSignal);
     }
 
     /**
@@ -132,9 +132,8 @@
                 // Acquire the wake lock as we are reading the elapsed realtime clock below.
                 wakeLock.acquire();
 
-                long elapsedRealtime = deviceState.elapsedRealtimeMillis();
-                long millisSinceNitzReceived =
-                        elapsedRealtime - newSignal.getReceiptElapsedRealtimeMillis();
+                long elapsedRealtime = deviceState.elapsedRealtime();
+                long millisSinceNitzReceived = elapsedRealtime - newSignal.getReferenceTimeMillis();
                 if (millisSinceNitzReceived < 0 || millisSinceNitzReceived > Integer.MAX_VALUE) {
                     if (DBG) {
                         Rlog.d(LOG_TAG, "mustProcessNitzSignal: Not processing NITZ signal"
@@ -179,15 +178,15 @@
             @Override
             @NonNull
             public Boolean mustProcessNitzSignal(
-                    @NonNull NitzSignal previousSignal,
-                    @NonNull NitzSignal newSignal) {
+                    @NonNull TimestampedValue<NitzData> previousSignal,
+                    @NonNull TimestampedValue<NitzData> newSignal) {
                 Objects.requireNonNull(newSignal);
-                Objects.requireNonNull(newSignal.getNitzData());
+                Objects.requireNonNull(newSignal.getValue());
                 Objects.requireNonNull(previousSignal);
-                Objects.requireNonNull(previousSignal.getNitzData());
+                Objects.requireNonNull(previousSignal.getValue());
 
-                NitzData newNitzData = newSignal.getNitzData();
-                NitzData previousNitzData = previousSignal.getNitzData();
+                NitzData newNitzData = newSignal.getValue();
+                NitzData previousNitzData = previousSignal.getValue();
 
                 // Compare the discrete NitzData fields associated with local time offset. Any
                 // difference and we should process the signal regardless of how recent the last one
@@ -196,36 +195,26 @@
                     return true;
                 }
 
-                // Check the time-related NitzData fields to see if they are sufficiently different.
-
-                // See if the NITZ signals have been received sufficiently far apart. If yes, we
-                // want to process the new one.
+                // Now check the continuous NitzData field (time) to see if it is sufficiently
+                // different.
                 int nitzUpdateSpacing = deviceState.getNitzUpdateSpacingMillis();
-                long elapsedRealtimeSinceLastSaved = newSignal.getReceiptElapsedRealtimeMillis()
-                        - previousSignal.getReceiptElapsedRealtimeMillis();
-                if (elapsedRealtimeSinceLastSaved > nitzUpdateSpacing) {
-                    return true;
-                }
-
-                // See if the NITZ signals have sufficiently different encoded Unix epoch times. If
-                // yes, then we want to process the new one.
                 int nitzUpdateDiff = deviceState.getNitzUpdateDiffMillis();
 
-                // Calculate the Unix epoch difference between the time the two signals hold,
-                // accounting for any difference in receipt time and age.
-                long unixEpochTimeDifferenceMillis = newNitzData.getCurrentTimeInMillis()
-                        - previousNitzData.getCurrentTimeInMillis();
-                long ageAdjustedElapsedRealtimeDifferenceMillis =
-                        newSignal.getAgeAdjustedElapsedRealtimeMillis()
-                                - previousSignal.getAgeAdjustedElapsedRealtimeMillis();
+                // Calculate the elapsed time between the new signal and the last signal.
+                long elapsedRealtimeSinceLastSaved = newSignal.getReferenceTimeMillis()
+                        - previousSignal.getReferenceTimeMillis();
 
-                // In ideal conditions, the difference between
-                // ageAdjustedElapsedRealtimeSinceLastSaved and unixEpochTimeDifferenceMillis will
-                // be zero if two NITZ signals are consistent and if the elapsed realtime clock is
-                // ticking at the correct rate.
-                long millisGainedOrLost = Math.abs(
-                        unixEpochTimeDifferenceMillis - ageAdjustedElapsedRealtimeDifferenceMillis);
-                if (millisGainedOrLost > nitzUpdateDiff) {
+                // Calculate the UTC difference between the time the two signals hold.
+                long utcTimeDifferenceMillis = newNitzData.getCurrentTimeInMillis()
+                        - previousNitzData.getCurrentTimeInMillis();
+
+                // Ideally the difference between elapsedRealtimeSinceLastSaved and
+                // utcTimeDifferenceMillis would be zero.
+                long millisGainedOrLost = Math
+                        .abs(utcTimeDifferenceMillis - elapsedRealtimeSinceLastSaved);
+
+                if (elapsedRealtimeSinceLastSaved > nitzUpdateSpacing
+                        || millisGainedOrLost > nitzUpdateDiff) {
                     return true;
                 }
 
@@ -267,8 +256,8 @@
         }
 
         @Override
-        public boolean mustProcessNitzSignal(@Nullable NitzSignal oldSignal,
-                @NonNull NitzSignal newSignal) {
+        public boolean mustProcessNitzSignal(@Nullable TimestampedValue<NitzData> oldSignal,
+                @NonNull TimestampedValue<NitzData> newSignal) {
             Objects.requireNonNull(newSignal);
 
             for (TrivalentPredicate component : mComponents) {
diff --git a/src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java b/src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java
index 0190776..a36eb4f 100644
--- a/src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java
+++ b/src/java/com/android/internal/telephony/nitz/NitzStateMachineImpl.java
@@ -25,7 +25,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.NitzData;
-import com.android.internal.telephony.NitzSignal;
 import com.android.internal.telephony.NitzStateMachine;
 import com.android.internal.telephony.Phone;
 import com.android.internal.util.IndentingPrintWriter;
@@ -69,8 +68,8 @@
          * See {@link NitzSignalInputFilterPredicate}.
          */
         boolean mustProcessNitzSignal(
-                @Nullable NitzSignal oldSignal,
-                @NonNull NitzSignal newSignal);
+                @Nullable TimestampedValue<NitzData> oldSignal,
+                @NonNull TimestampedValue<NitzData> newSignal);
     }
 
     /**
@@ -90,41 +89,32 @@
         @NonNull
         TelephonyTimeZoneSuggestion getTimeZoneSuggestion(
                 int slotIndex, @Nullable String countryIsoCode,
-                @Nullable NitzSignal nitzSignal);
+                @Nullable TimestampedValue<NitzData> nitzSignal);
     }
 
-    static final String LOG_TAG = "NitzStateMachineImpl";
+    static final String LOG_TAG = "NewNitzStateMachineImpl";
     static final boolean DBG = true;
 
     // Miscellaneous dependencies and helpers not related to detection state.
     private final int mSlotIndex;
-    @NonNull private final DeviceState mDeviceState;
     /** Applied to NITZ signals during input filtering. */
-    @NonNull private final NitzSignalInputFilterPredicate mNitzSignalInputFilter;
+    private final NitzSignalInputFilterPredicate mNitzSignalInputFilter;
     /**
      * Creates a {@link TelephonyTimeZoneSuggestion} for passing to the time zone detection service.
      */
-    @NonNull private final TimeZoneSuggester mTimeZoneSuggester;
+    private final TimeZoneSuggester mTimeZoneSuggester;
     /** A facade to the time / time zone detection services. */
-    @NonNull private final TimeServiceHelper mTimeServiceHelper;
+    private final TimeServiceHelper mTimeServiceHelper;
 
     // Shared detection state.
 
     /**
-     * The latest active NITZ signal <em>processed</em> (i.e. after input filtering). It is used for
+     * The last / latest NITZ signal <em>processed</em> (i.e. after input filtering). It is used for
      * input filtering (e.g. rate limiting) and provides the NITZ information when time / time zone
      * needs to be recalculated when something else has changed.
      */
-    @Nullable private NitzSignal mLatestNitzSignal;
-
-    /**
-     * The last NITZ received, which has been cleared from {@link #mLatestNitzSignal} because of a
-     * loss of connectivity. The TimestampedValue reference time is the time according to the
-     * elapsed realtime clock when {@link #mLatestNitzSignal} was cleared. This field is used to
-     * hold the NITZ for later restoration after transient network disconnections. This can be null,
-     * but the NitzSignal referenced by the TimestampedValue will never be.
-     */
-    @Nullable private TimestampedValue<NitzSignal> mLastNitzSignalCleared;
+    @Nullable
+    private TimestampedValue<NitzData> mLatestNitzSignal;
 
     // Time Zone detection state.
 
@@ -133,7 +123,7 @@
      * (lower case), empty (test network) or null (no country detected). A country code is required
      * to determine time zone except when on a test network.
      */
-    @Nullable private String mCountryIsoCode;
+    private String mCountryIsoCode;
 
     /**
      * Creates an instance for the supplied {@link Phone}.
@@ -150,7 +140,7 @@
         NitzSignalInputFilterPredicate nitzSignalFilter =
                 NitzSignalInputFilterPredicateFactory.create(phone.getContext(), deviceState);
         return new NitzStateMachineImpl(
-                slotIndex, deviceState, nitzSignalFilter, timeZoneSuggester, newTimeServiceHelper);
+                slotIndex, nitzSignalFilter, timeZoneSuggester, newTimeServiceHelper);
     }
 
     /**
@@ -159,12 +149,10 @@
      */
     @VisibleForTesting
     public NitzStateMachineImpl(int slotIndex,
-            @NonNull DeviceState deviceState,
             @NonNull NitzSignalInputFilterPredicate nitzSignalInputFilter,
             @NonNull TimeZoneSuggester timeZoneSuggester,
             @NonNull TimeServiceHelper newTimeServiceHelper) {
         mSlotIndex = slotIndex;
-        mDeviceState = Objects.requireNonNull(deviceState);
         mTimeZoneSuggester = Objects.requireNonNull(timeZoneSuggester);
         mTimeServiceHelper = Objects.requireNonNull(newTimeServiceHelper);
         mNitzSignalInputFilter = Objects.requireNonNull(nitzSignalInputFilter);
@@ -172,14 +160,41 @@
 
     @Override
     public void handleNetworkAvailable() {
-        String reason = "handleNetworkAvailable";
-        restoreNetworkStateAndRerunDetection(reason);
+        // We no longer do any useful work here: we assume handleNetworkUnavailable() is reliable.
+        // TODO: Remove this method when all implementations do nothing.
     }
 
     @Override
     public void handleNetworkUnavailable() {
-        String reason = "handleNetworkUnavailable";
-        clearNetworkStateAndRerunDetection(reason, false /* fullyClearNitz */);
+        String reason = "handleNetworkUnavailable()";
+        clearNetworkStateAndRerunDetection(reason);
+    }
+
+    private void clearNetworkStateAndRerunDetection(String reason) {
+        if (mLatestNitzSignal == null) {
+            // The network state is already empty so there's no need to do anything.
+            if (DBG) {
+                Rlog.d(LOG_TAG, reason + ": mLatestNitzSignal was already null. Nothing to do.");
+            }
+            return;
+        }
+
+        // The previous NITZ signal received is now invalid so clear it.
+        mLatestNitzSignal = null;
+
+        // countryIsoCode can be assigned null here, in which case the doTimeZoneDetection() call
+        // below will do nothing, which is ok as nothing will have changed.
+        String countryIsoCode = mCountryIsoCode;
+        if (DBG) {
+            Rlog.d(LOG_TAG, reason + ": countryIsoCode=" + countryIsoCode);
+        }
+
+        // Generate a new time zone suggestion (which could be an empty suggestion) and update the
+        // service as needed.
+        doTimeZoneDetection(countryIsoCode, null /* nitzSignal */, reason);
+
+        // Generate a new time suggestion and update the service as needed.
+        doTimeDetection(null /* nitzSignal */, reason);
     }
 
     @Override
@@ -208,31 +223,33 @@
 
         // Generate a new time zone suggestion and update the service as needed.
         doTimeZoneDetection(null /* countryIsoCode */, mLatestNitzSignal,
-                "handleCountryUnavailable");
+                "handleCountryUnavailable()");
     }
 
     @Override
-    public void handleNitzReceived(@NonNull NitzSignal nitzSignal) {
+    public void handleNitzReceived(@NonNull TimestampedValue<NitzData> nitzSignal) {
+        if (DBG) {
+            Rlog.d(LOG_TAG, "handleNitzReceived: nitzSignal=" + nitzSignal);
+        }
         Objects.requireNonNull(nitzSignal);
 
         // Perform input filtering to filter bad data and avoid processing signals too often.
-        NitzSignal previousNitzSignal = mLatestNitzSignal;
+        TimestampedValue<NitzData> previousNitzSignal = mLatestNitzSignal;
         if (!mNitzSignalInputFilter.mustProcessNitzSignal(previousNitzSignal, nitzSignal)) {
-            if (DBG) {
-                Rlog.d(LOG_TAG, "handleNitzReceived: previousNitzSignal=" + previousNitzSignal
-                        + ", nitzSignal=" + nitzSignal + ": NITZ filtered");
-            }
             return;
         }
 
         // Always store the latest valid NITZ signal to be processed.
         mLatestNitzSignal = nitzSignal;
 
-        // Clear any retained NITZ signal: The value now in mLatestNitzSignal means it isn't needed.
-        mLastNitzSignalCleared = null;
-
         String reason = "handleNitzReceived(" + nitzSignal + ")";
-        runDetection(reason);
+
+        // Generate a new time zone suggestion and update the service as needed.
+        String countryIsoCode = mCountryIsoCode;
+        doTimeZoneDetection(countryIsoCode, nitzSignal, reason);
+
+        // Generate a new time suggestion and update the service as needed.
+        doTimeDetection(nitzSignal, reason);
     }
 
     @Override
@@ -254,89 +271,14 @@
         mCountryIsoCode = null;
 
         String reason = "handleAirplaneModeChanged(" + on + ")";
-        clearNetworkStateAndRerunDetection(reason, true /* fullyClearNitz */);
-    }
-
-    private void restoreNetworkStateAndRerunDetection(String reason) {
-        // Restore the last NITZ signal if the network has been unavailable for only a short period.
-        if (mLastNitzSignalCleared == null) {
-            if (DBG) {
-                Rlog.d(LOG_TAG, reason + ": mLastNitzSignalCleared is null.");
-            }
-            // Nothing has changed. No work to do.
-            return;
-        }
-
-        long timeSinceNitzClearedMillis = mDeviceState.elapsedRealtimeMillis()
-                - mLastNitzSignalCleared.getReferenceTimeMillis();
-        boolean canRestoreNitz = timeSinceNitzClearedMillis
-                < mDeviceState.getNitzNetworkDisconnectRetentionMillis();
-        if (canRestoreNitz) {
-            reason = reason + ", mLatestNitzSignal restored from mLastNitzSignalCleared="
-                    + mLastNitzSignalCleared.getValue();
-            mLatestNitzSignal = mLastNitzSignalCleared.getValue();
-
-            // NITZ was restored, so we do not need the retained value anymore.
-            mLastNitzSignalCleared = null;
-
-            runDetection(reason);
-        } else {
-            if (DBG) {
-                Rlog.d(LOG_TAG, reason + ": mLastNitzSignalCleared is too old.");
-            }
-            // The retained NITZ is judged too old, so it could be cleared here, but it's kept for
-            // debugging and in case mDeviceState.getNitzNetworkDisconnectRetentionMillis() changes.
-        }
-    }
-
-    private void clearNetworkStateAndRerunDetection(String reason, boolean fullyClearNitz) {
-        if (mLatestNitzSignal == null) {
-            if (fullyClearNitz) {
-                mLastNitzSignalCleared = null;
-            }
-
-            // The network state is already empty so there's no need to do anything.
-            if (DBG) {
-                Rlog.d(LOG_TAG, reason + ": mLatestNitzSignal was already null. Nothing to do.");
-            }
-            return;
-        }
-
-        if (fullyClearNitz) {
-            mLastNitzSignalCleared = null;
-        } else {
-            mLastNitzSignalCleared = new TimestampedValue<>(
-                    mDeviceState.elapsedRealtimeMillis(), mLatestNitzSignal);
-        }
-        mLatestNitzSignal = null;
-
-        runDetection(reason);
-    }
-
-    private void runDetection(String reason) {
-        // countryIsoCode can be assigned null here, in which case the doTimeZoneDetection() call
-        // below will do nothing.
-        String countryIsoCode = mCountryIsoCode;
-
-        NitzSignal nitzSignal = mLatestNitzSignal;
-        if (DBG) {
-            Rlog.d(LOG_TAG, "runDetection: reason=" + reason + ", countryIsoCode=" + countryIsoCode
-                    + ", nitzSignal=" + nitzSignal);
-        }
-
-        // Generate a new time zone suggestion (which could be an empty suggestion) and update the
-        // service as needed.
-        doTimeZoneDetection(countryIsoCode, nitzSignal, reason);
-
-        // Generate a new time suggestion and update the service as needed.
-        doTimeDetection(nitzSignal, reason);
+        clearNetworkStateAndRerunDetection(reason);
     }
 
     /**
      * Perform a round of time zone detection and notify the time zone detection service as needed.
      */
     private void doTimeZoneDetection(
-            @Nullable String countryIsoCode, @Nullable NitzSignal nitzSignal,
+            @Nullable String countryIsoCode, @Nullable TimestampedValue<NitzData> nitzSignal,
             @NonNull String reason) {
         try {
             Objects.requireNonNull(reason);
@@ -364,7 +306,7 @@
     /**
      * Perform a round of time detection and notify the time detection service as needed.
      */
-    private void doTimeDetection(@Nullable NitzSignal nitzSignal,
+    private void doTimeDetection(@Nullable TimestampedValue<NitzData> nitzSignal,
             @NonNull String reason) {
         try {
             Objects.requireNonNull(reason);
@@ -375,8 +317,10 @@
                 builder.addDebugInfo("Clearing time suggestion"
                         + " reason=" + reason);
             } else {
-                TimestampedValue<Long> newNitzTime = nitzSignal.createTimeSignal();
-                builder.setUnixEpochTime(newNitzTime);
+                TimestampedValue<Long> newNitzTime = new TimestampedValue<>(
+                        nitzSignal.getReferenceTimeMillis(),
+                        nitzSignal.getValue().getCurrentTimeInMillis());
+                builder.setUtcTime(newNitzTime);
                 builder.addDebugInfo("Sending new time suggestion"
                         + " nitzSignal=" + nitzSignal
                         + ", reason=" + reason);
@@ -404,16 +348,8 @@
         mTimeServiceHelper.dumpLogs(ipw);
     }
 
-    @VisibleForTesting
     @Nullable
-    public NitzData getLatestNitzData() {
-        return mLatestNitzSignal != null ? mLatestNitzSignal.getNitzData() : null;
-    }
-
-    @VisibleForTesting
-    @Nullable
-    public NitzData getLastNitzDataCleared() {
-        return mLastNitzSignalCleared != null
-                ? mLastNitzSignalCleared.getValue().getNitzData() : null;
+    public NitzData getCachedNitzData() {
+        return mLatestNitzSignal != null ? mLatestNitzSignal.getValue() : null;
     }
 }
diff --git a/src/java/com/android/internal/telephony/nitz/TimeServiceHelperImpl.java b/src/java/com/android/internal/telephony/nitz/TimeServiceHelperImpl.java
index 9c7aac9..7f85786 100644
--- a/src/java/com/android/internal/telephony/nitz/TimeServiceHelperImpl.java
+++ b/src/java/com/android/internal/telephony/nitz/TimeServiceHelperImpl.java
@@ -43,8 +43,8 @@
     private final TimeDetector mTimeDetector;
     private final TimeZoneDetector mTimeZoneDetector;
 
-    private final LocalLog mTimeZoneLog = new LocalLog(32, false /* mUseLocalTimestamps */);
-    private final LocalLog mTimeLog = new LocalLog(32, false /* mUseLocalTimestamps */);
+    private final LocalLog mTimeZoneLog = new LocalLog(30, false /* mUseLocalTimestamps */);
+    private final LocalLog mTimeLog = new LocalLog(30, false /* mUseLocalTimestamps */);
 
     /**
      * Records the last time zone suggestion made. Used to avoid sending duplicate suggestions to
@@ -68,9 +68,9 @@
 
         Objects.requireNonNull(timeSuggestion);
 
-        if (timeSuggestion.getUnixEpochTime() != null) {
-            TimestampedValue<Long> unixEpochTime = timeSuggestion.getUnixEpochTime();
-            TelephonyMetrics.getInstance().writeNITZEvent(mSlotIndex, unixEpochTime.getValue());
+        if (timeSuggestion.getUtcTime() != null) {
+            TimestampedValue<Long> utcTime = timeSuggestion.getUtcTime();
+            TelephonyMetrics.getInstance().writeNITZEvent(mSlotIndex, utcTime.getValue());
         }
         mTimeDetector.suggestTelephonyTime(timeSuggestion);
     }
diff --git a/src/java/com/android/internal/telephony/nitz/TimeZoneSuggesterImpl.java b/src/java/com/android/internal/telephony/nitz/TimeZoneSuggesterImpl.java
index 342705b..48491df 100644
--- a/src/java/com/android/internal/telephony/nitz/TimeZoneSuggesterImpl.java
+++ b/src/java/com/android/internal/telephony/nitz/TimeZoneSuggesterImpl.java
@@ -21,12 +21,12 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
+import android.os.TimestampedValue;
 import android.text.TextUtils;
 import android.timezone.CountryTimeZones.OffsetResult;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.NitzData;
-import com.android.internal.telephony.NitzSignal;
 import com.android.internal.telephony.NitzStateMachine.DeviceState;
 import com.android.internal.telephony.nitz.NitzStateMachineImpl.TimeZoneSuggester;
 import com.android.internal.telephony.nitz.TimeZoneLookupHelper.CountryResult;
@@ -55,12 +55,12 @@
     @Override
     @NonNull
     public TelephonyTimeZoneSuggestion getTimeZoneSuggestion(int slotIndex,
-            @Nullable String countryIsoCode, @Nullable NitzSignal nitzSignal) {
+            @Nullable String countryIsoCode, @Nullable TimestampedValue<NitzData> nitzSignal) {
         try {
             // Check for overriding NITZ-based signals from Android running in an emulator.
             TelephonyTimeZoneSuggestion overridingSuggestion = null;
             if (nitzSignal != null) {
-                NitzData nitzData = nitzSignal.getNitzData();
+                NitzData nitzData = nitzSignal.getValue();
                 if (nitzData.getEmulatorHostTimeZone() != null) {
                     TelephonyTimeZoneSuggestion.Builder builder =
                             new TelephonyTimeZoneSuggestion.Builder(slotIndex)
@@ -135,9 +135,9 @@
      */
     @NonNull
     private TelephonyTimeZoneSuggestion findTimeZoneForTestNetwork(
-            int slotIndex, @NonNull NitzSignal nitzSignal) {
+            int slotIndex, @NonNull TimestampedValue<NitzData> nitzSignal) {
         Objects.requireNonNull(nitzSignal);
-        NitzData nitzData = Objects.requireNonNull(nitzSignal.getNitzData());
+        NitzData nitzData = Objects.requireNonNull(nitzSignal.getValue());
 
         TelephonyTimeZoneSuggestion.Builder suggestionBuilder =
                 new TelephonyTimeZoneSuggestion.Builder(slotIndex);
@@ -166,7 +166,7 @@
     @NonNull
     private TelephonyTimeZoneSuggestion findTimeZoneFromCountryAndNitz(
             int slotIndex, @NonNull String countryIsoCode,
-            @NonNull NitzSignal nitzSignal) {
+            @NonNull TimestampedValue<NitzData> nitzSignal) {
         Objects.requireNonNull(countryIsoCode);
         Objects.requireNonNull(nitzSignal);
 
@@ -175,7 +175,7 @@
         suggestionBuilder.addDebugInfo("findTimeZoneFromCountryAndNitz:"
                 + " countryIsoCode=" + countryIsoCode
                 + ", nitzSignal=" + nitzSignal);
-        NitzData nitzData = Objects.requireNonNull(nitzSignal.getNitzData());
+        NitzData nitzData = Objects.requireNonNull(nitzSignal.getValue());
         if (isNitzSignalOffsetInfoBogus(countryIsoCode, nitzData)) {
             suggestionBuilder.addDebugInfo(
                     "findTimeZoneFromCountryAndNitz: NITZ signal looks bogus");
diff --git a/src/java/com/android/internal/telephony/sip/SipCallBase.java b/src/java/com/android/internal/telephony/sip/SipCallBase.java
new file mode 100644
index 0000000..a7396cc
--- /dev/null
+++ b/src/java/com/android/internal/telephony/sip/SipCallBase.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2010 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.sip;
+
+import com.android.internal.telephony.Call;
+
+abstract class SipCallBase extends Call {
+
+    @Override
+    public boolean isMultiparty() {
+        return getConnectionsCount() > 1;
+    }
+
+    @Override
+    public String toString() {
+        return mState.toString() + ":" + super.toString();
+    }
+}
diff --git a/src/java/com/android/internal/telephony/sip/SipCommandInterface.java b/src/java/com/android/internal/telephony/sip/SipCommandInterface.java
new file mode 100644
index 0000000..f3c1839
--- /dev/null
+++ b/src/java/com/android/internal/telephony/sip/SipCommandInterface.java
@@ -0,0 +1,695 @@
+/*
+ * Copyright (C) 2010 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.sip;
+
+import android.content.Context;
+import android.net.KeepalivePacketData;
+import android.net.LinkProperties;
+import android.os.Handler;
+import android.os.Message;
+import android.telephony.ImsiEncryptionInfo;
+import android.telephony.NetworkScanRequest;
+import android.telephony.SignalThresholdInfo;
+import android.telephony.TelephonyManager;
+import android.telephony.data.DataProfile;
+import android.telephony.data.NetworkSliceInfo;
+import android.telephony.data.TrafficDescriptor;
+import android.telephony.emergency.EmergencyNumber;
+
+import com.android.internal.telephony.BaseCommands;
+import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.UUSInfo;
+import com.android.internal.telephony.cdma.CdmaSmsBroadcastConfigInfo;
+import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
+
+/**
+ * SIP doesn't need CommandsInterface. The class does nothing but made to work
+ * with Phone's constructor.
+ */
+class SipCommandInterface extends BaseCommands implements CommandsInterface {
+    SipCommandInterface(Context context) {
+        super(context);
+    }
+
+    @Override public void setOnNITZTime(Handler h, int what, Object obj) {
+    }
+
+    @Override
+    public void getIccCardStatus(Message result) {
+    }
+
+    @Override
+    public void getIccSlotsStatus(Message result) {
+    }
+
+    @Override
+    public void setLogicalToPhysicalSlotMapping(int[] physicalSlots, Message result) {
+    }
+
+    @Override
+    public void supplyIccPin(String pin, Message result) {
+    }
+
+    @Override
+    public void supplyIccPuk(String puk, String newPin, Message result) {
+    }
+
+    @Override
+    public void supplyIccPin2(String pin, Message result) {
+    }
+
+    @Override
+    public void supplyIccPuk2(String puk, String newPin2, Message result) {
+    }
+
+    @Override
+    public void changeIccPin(String oldPin, String newPin, Message result) {
+    }
+
+    @Override
+    public void changeIccPin2(String oldPin2, String newPin2, Message result) {
+    }
+
+    @Override
+    public void changeBarringPassword(String facility, String oldPwd,
+            String newPwd, Message result) {
+    }
+
+    @Override
+    public void supplyNetworkDepersonalization(String netpin, Message result) {
+    }
+
+    @Override
+    public void supplySimDepersonalization(PersoSubState persoType,
+            String controlKey, Message result) {
+    }
+
+    @Override
+    public void getCurrentCalls(Message result) {
+    }
+
+    @Override
+    @Deprecated public void getPDPContextList(Message result) {
+    }
+
+    @Override
+    public void getDataCallList(Message result) {
+    }
+
+    @Override
+    public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
+                     boolean hasKnownUserIntentEmergency, int clirMode, Message result) {
+    }
+
+    @Override
+    public void dial(String address, boolean isEmergencyCall, EmergencyNumber emergencyNumberInfo,
+                     boolean hasKnownUserIntentEmergency, int clirMode, UUSInfo uusInfo,
+                     Message result) {
+    }
+
+    @Override
+    public void getIMSI(Message result) {
+    }
+
+    @Override
+    public void getIMSIForApp(String aid, Message result) {
+    }
+
+    @Override
+    public void getIMEI(Message result) {
+    }
+
+    @Override
+    public void getIMEISV(Message result) {
+    }
+
+
+    @Override
+    public void hangupConnection (int gsmIndex, Message result) {
+    }
+
+    @Override
+    public void hangupWaitingOrBackground (Message result) {
+    }
+
+    @Override
+    public void hangupForegroundResumeBackground (Message result) {
+    }
+
+    @Override
+    public void switchWaitingOrHoldingAndActive (Message result) {
+    }
+
+    @Override
+    public void conference (Message result) {
+    }
+
+
+    @Override
+    public void setPreferredVoicePrivacy(boolean enable, Message result) {
+    }
+
+    @Override
+    public void getPreferredVoicePrivacy(Message result) {
+    }
+
+    @Override
+    public void separateConnection (int gsmIndex, Message result) {
+    }
+
+    @Override
+    public void acceptCall (Message result) {
+    }
+
+    @Override
+    public void rejectCall (Message result) {
+    }
+
+    @Override
+    public void explicitCallTransfer (Message result) {
+    }
+
+    @Override
+    public void getLastCallFailCause (Message result) {
+    }
+
+    @Deprecated
+    @Override
+    public void getLastPdpFailCause (Message result) {
+    }
+
+    @Override
+    public void getLastDataCallFailCause (Message result) {
+    }
+
+    @Override
+    public void setMute (boolean enableMute, Message response) {
+    }
+
+    @Override
+    public void getMute (Message response) {
+    }
+
+    @Override
+    public void getSignalStrength (Message result) {
+    }
+
+    @Override
+    public void getVoiceRegistrationState (Message result) {
+    }
+
+    @Override
+    public void getDataRegistrationState (Message result) {
+    }
+
+    @Override
+    public void getOperator(Message result) {
+    }
+
+    @Override
+    public void sendDtmf(char c, Message result) {
+    }
+
+    @Override
+    public void startDtmf(char c, Message result) {
+    }
+
+    @Override
+    public void stopDtmf(Message result) {
+    }
+
+    @Override
+    public void sendBurstDtmf(String dtmfString, int on, int off,
+            Message result) {
+    }
+
+    @Override
+    public void sendSMS (String smscPDU, String pdu, Message result) {
+    }
+
+    @Override
+    public void sendSMSExpectMore (String smscPDU, String pdu, Message result) {
+    }
+
+    @Override
+    public void sendCdmaSms(byte[] pdu, Message result) {
+    }
+
+    @Override
+    public void sendCdmaSMSExpectMore(byte[] pdu, Message result) {
+    }
+
+    @Override
+    public void sendImsGsmSms (String smscPDU, String pdu,
+            int retry, int messageRef, Message response) {
+    }
+
+    @Override
+    public void sendImsCdmaSms(byte[] pdu, int retry, int messageRef,
+            Message response) {
+    }
+
+    @Override
+    public void getImsRegistrationState (Message result) {
+    }
+
+    @Override
+    public void deleteSmsOnSim(int index, Message response) {
+    }
+
+    @Override
+    public void deleteSmsOnRuim(int index, Message response) {
+    }
+
+    @Override
+    public void writeSmsToSim(int status, String smsc, String pdu, Message response) {
+    }
+
+    @Override
+    public void writeSmsToRuim(int status, byte[] pdu, Message response) {
+    }
+
+    @Override
+    public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming,
+            boolean allowRoaming, int reason, LinkProperties linkProperties, int pduSessionId,
+            NetworkSliceInfo sliceInfo, TrafficDescriptor trafficDescriptor,
+            boolean matchAllRuleAllowed, Message result) {
+    }
+
+    @Override
+    public void deactivateDataCall(int cid, int reason, Message result) {
+    }
+
+    @Override
+    public void setRadioPower(boolean on, Message result) {
+    }
+
+    @Override
+    public void setSuppServiceNotifications(boolean enable, Message result) {
+    }
+
+    @Override
+    public void acknowledgeLastIncomingGsmSms(boolean success, int cause,
+            Message result) {
+    }
+
+    @Override
+    public void acknowledgeLastIncomingCdmaSms(boolean success, int cause,
+            Message result) {
+    }
+
+    @Override
+    public void acknowledgeIncomingGsmSmsWithPdu(boolean success, String ackPdu,
+            Message result) {
+    }
+
+    @Override
+    public void iccIO (int command, int fileid, String path, int p1, int p2,
+            int p3, String data, String pin2, Message result) {
+    }
+    @Override
+    public void iccIOForApp (int command, int fileid, String path, int p1, int p2,
+            int p3, String data, String pin2, String aid, Message result) {
+    }
+
+    @Override
+    public void getCLIR(Message result) {
+    }
+
+    @Override
+    public void setCLIR(int clirMode, Message result) {
+    }
+
+    @Override
+    public void queryCallWaiting(int serviceClass, Message response) {
+    }
+
+    @Override
+    public void setCallWaiting(boolean enable, int serviceClass,
+            Message response) {
+    }
+
+    @Override
+    public void setNetworkSelectionModeAutomatic(Message response) {
+    }
+
+    @Override
+    public void setNetworkSelectionModeManual(String operatorNumeric, int ran, Message response) {
+    }
+
+    @Override
+    public void getNetworkSelectionMode(Message response) {
+    }
+
+    @Override
+    public void getAvailableNetworks(Message response) {
+    }
+
+    @Override
+    public void startNetworkScan(NetworkScanRequest nsr, Message response) {
+    }
+
+    @Override
+    public void stopNetworkScan(Message response) {
+    }
+
+    @Override
+    public void setCallForward(int action, int cfReason, int serviceClass,
+                String number, int timeSeconds, Message response) {
+    }
+
+    @Override
+    public void queryCallForwardStatus(int cfReason, int serviceClass,
+            String number, Message response) {
+    }
+
+    @Override
+    public void queryCLIP(Message response) {
+    }
+
+    @Override
+    public void getBasebandVersion (Message response) {
+    }
+
+    @Override
+    public void queryFacilityLock(String facility, String password,
+            int serviceClass, Message response) {
+    }
+
+    @Override
+    public void queryFacilityLockForApp(String facility, String password,
+            int serviceClass, String appId, Message response) {
+    }
+
+    @Override
+    public void setFacilityLock(String facility, boolean lockState,
+            String password, int serviceClass, Message response) {
+    }
+
+    @Override
+    public void setFacilityLockForApp(String facility, boolean lockState,
+            String password, int serviceClass, String appId, Message response) {
+    }
+
+    @Override
+    public void sendUSSD (String ussdString, Message response) {
+    }
+
+    @Override
+    public void cancelPendingUssd (Message response) {
+    }
+
+    @Override
+    public void resetRadio(Message result) {
+    }
+
+    @Override
+    public void invokeOemRilRequestRaw(byte[] data, Message response) {
+    }
+
+    @Override
+    public void invokeOemRilRequestStrings(String[] strings, Message response) {
+    }
+
+    @Override
+    public void setBandMode (int bandMode, Message response) {
+    }
+
+    @Override
+    public void queryAvailableBandMode (Message response) {
+    }
+
+    @Override
+    public void sendTerminalResponse(String contents, Message response) {
+    }
+
+    @Override
+    public void sendEnvelope(String contents, Message response) {
+    }
+
+    @Override
+    public void sendEnvelopeWithStatus(String contents, Message response) {
+    }
+
+    @Override
+    public void handleCallSetupRequestFromSim(
+            boolean accept, Message response) {
+    }
+
+    @Override
+    public void setPreferredNetworkType(int networkType , Message response) {
+    }
+
+    @Override
+    public void getPreferredNetworkType(Message response) {
+    }
+
+    @Override
+    public void setAllowedNetworkTypesBitmap(
+            @TelephonyManager.NetworkTypeBitMask int networkTypeBitmask, Message response) {
+    }
+
+    @Override
+    public void getAllowedNetworkTypesBitmap(Message response) {
+    }
+
+    @Override
+    public void setLocationUpdates(boolean enable, Message response) {
+    }
+
+    @Override
+    public void getSmscAddress(Message result) {
+    }
+
+    @Override
+    public void setSmscAddress(String address, Message result) {
+    }
+
+    @Override
+    public void reportSmsMemoryStatus(boolean available, Message result) {
+    }
+
+    @Override
+    public void reportStkServiceIsRunning(Message result) {
+    }
+
+    @Override
+    public void getCdmaSubscriptionSource(Message response) {
+    }
+
+    @Override
+    public void getGsmBroadcastConfig(Message response) {
+    }
+
+    @Override
+    public void setGsmBroadcastConfig(SmsBroadcastConfigInfo[] config, Message response) {
+    }
+
+    @Override
+    public void setGsmBroadcastActivation(boolean activate, Message response) {
+    }
+
+    // ***** Methods for CDMA support
+    @Override
+    public void getDeviceIdentity(Message response) {
+    }
+
+    @Override
+    public void getCDMASubscription(Message response) {
+    }
+
+    @Override
+    public void setPhoneType(int phoneType) { //Set by GsmCdmaPhone
+    }
+
+    @Override
+    public void queryCdmaRoamingPreference(Message response) {
+    }
+
+    @Override
+    public void setCdmaRoamingPreference(int cdmaRoamingType, Message response) {
+    }
+
+    @Override
+    public void setCdmaSubscriptionSource(int cdmaSubscription , Message response) {
+    }
+
+    @Override
+    public void queryTTYMode(Message response) {
+    }
+
+    @Override
+    public void setTTYMode(int ttyMode, Message response) {
+    }
+
+    @Override
+    public void sendCDMAFeatureCode(String FeatureCode, Message response) {
+    }
+
+    @Override
+    public void getCdmaBroadcastConfig(Message response) {
+    }
+
+    @Override
+    public void setCdmaBroadcastConfig(CdmaSmsBroadcastConfigInfo[] configs, Message response) {
+    }
+
+    @Override
+    public void setCdmaBroadcastActivation(boolean activate, Message response) {
+    }
+
+    @Override
+    public void exitEmergencyCallbackMode(Message response) {
+    }
+
+    @Override
+    public void supplyIccPinForApp(String pin, String aid, Message response) {
+    }
+
+    @Override
+    public void supplyIccPukForApp(String puk, String newPin, String aid, Message response) {
+    }
+
+    @Override
+    public void supplyIccPin2ForApp(String pin2, String aid, Message response) {
+    }
+
+    @Override
+    public void supplyIccPuk2ForApp(String puk2, String newPin2, String aid, Message response) {
+    }
+
+    @Override
+    public void changeIccPinForApp(String oldPin, String newPin, String aidPtr, Message response) {
+    }
+
+    @Override
+    public void changeIccPin2ForApp(String oldPin2, String newPin2, String aidPtr,
+            Message response) {
+    }
+
+    @Override
+    public void requestIccSimAuthentication(int authContext, String data, String aid, Message response) {
+    }
+
+    @Override
+    public void getVoiceRadioTechnology(Message result) {
+    }
+
+    @Override
+    public void setInitialAttachApn(DataProfile dataProfile, boolean isRoaming, Message result) {
+    }
+
+    @Override
+    public void setDataProfile(DataProfile[] dps, boolean isRoaming, Message result) {
+    }
+
+    @Override
+    public void iccOpenLogicalChannel(String AID, int p2, Message response) {
+    }
+
+    @Override
+    public void iccCloseLogicalChannel(int channel, Message response) {
+    }
+
+    @Override
+    public void iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
+            int p1, int p2, int p3, String data, Message response) {
+    }
+
+    @Override
+    public void iccTransmitApduBasicChannel(int cla, int instruction, int p1, int p2,
+            int p3, String data, Message response) {
+    }
+
+    @Override
+    public void nvWriteCdmaPrl(byte[] preferredRoamingList, Message response) {
+    }
+
+    @Override
+    public void nvResetConfig(int resetType, Message response) {
+    }
+
+    @Override
+    public void getHardwareConfig(Message result) {
+    }
+
+    @Override
+    public void requestShutdown(Message result) {
+    }
+
+    @Override
+    public void startLceService(int reportIntervalMs, boolean pullMode, Message result) {
+    }
+
+    @Override
+    public void stopLceService(Message result) {
+    }
+
+    @Override
+    public void pullLceData(Message result) {
+    }
+
+    @Override
+    public void setCarrierInfoForImsiEncryption(ImsiEncryptionInfo imsiEncryptionInfo,
+                                                Message result) {
+    }
+
+    @Override
+    public void sendDeviceState(int stateType, boolean state, Message result) {
+    }
+
+    @Override
+    public void setUnsolResponseFilter(int filter, Message result){
+    }
+
+    @Override
+    public void setSignalStrengthReportingCriteria(
+            SignalThresholdInfo signalThresholdInfo, int ran, Message result) {
+    }
+
+    @Override
+    public void setLinkCapacityReportingCriteria(int hysteresisMs, int hysteresisDlKbps,
+            int hysteresisUlKbps, int[] thresholdsDlKbps, int[] thresholdsUlKbps, int ran,
+            Message result) {
+    }
+
+    @Override
+    public void startNattKeepalive(
+            int contextId, KeepalivePacketData packetData, int intervalMillis, Message result) {
+    }
+
+    @Override
+    public void stopNattKeepalive(int sessionHandle, Message result) {
+    }
+
+    @Override
+    public void allocatePduSessionId(Message result) {
+    }
+
+    @Override
+    public void releasePduSessionId(Message result, int pduSessionId) {
+    }
+
+    @Override
+    public void startHandover(Message result, int callId) {
+    }
+
+    @Override
+    public void cancelHandover(Message result, int callId) {
+    }
+}
diff --git a/src/java/com/android/internal/telephony/sip/SipConnectionBase.java b/src/java/com/android/internal/telephony/sip/SipConnectionBase.java
new file mode 100644
index 0000000..40e5203
--- /dev/null
+++ b/src/java/com/android/internal/telephony/sip/SipConnectionBase.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2010 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.sip;
+
+import android.os.SystemClock;
+import android.telephony.PhoneNumberUtils;
+
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.UUSInfo;
+import com.android.telephony.Rlog;
+
+abstract class SipConnectionBase extends Connection {
+    private static final String LOG_TAG = "SipConnBase";
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false; // STOPSHIP if true
+
+    /*
+     * These time/timespan values are based on System.currentTimeMillis(),
+     * i.e., "wall clock" time.
+     */
+    private long mCreateTime;
+    private long mConnectTime;
+    private long mDisconnectTime;
+
+    /*
+     * These time/timespan values are based on SystemClock.elapsedRealTime(),
+     * i.e., time since boot.  They are appropriate for comparison and
+     * calculating deltas.
+     */
+    private long mConnectTimeReal;
+    private long mDuration = -1L;
+    private long mHoldingStartTime;  // The time when the Connection last transitioned
+                            // into HOLDING
+
+    SipConnectionBase(String dialString) {
+        super(PhoneConstants.PHONE_TYPE_SIP);
+        if (DBG) log("SipConnectionBase: ctor dialString=" + SipPhone.hidePii(dialString));
+        mPostDialString = PhoneNumberUtils.extractPostDialPortion(dialString);
+
+        mCreateTime = System.currentTimeMillis();
+    }
+
+    protected void setState(Call.State state) {
+        if (DBG) log("setState: state=" + state);
+        switch (state) {
+            case ACTIVE:
+                if (mConnectTime == 0) {
+                    mConnectTimeReal = SystemClock.elapsedRealtime();
+                    mConnectTime = System.currentTimeMillis();
+                }
+                break;
+            case DISCONNECTED:
+                mDuration = getDurationMillis();
+                mDisconnectTime = System.currentTimeMillis();
+                break;
+            case HOLDING:
+                mHoldingStartTime = SystemClock.elapsedRealtime();
+                break;
+            default:
+                // Ignore
+                break;
+        }
+    }
+
+    @Override
+    public long getCreateTime() {
+        if (VDBG) log("getCreateTime: ret=" + mCreateTime);
+        return mCreateTime;
+    }
+
+    @Override
+    public long getConnectTime() {
+        if (VDBG) log("getConnectTime: ret=" + mConnectTime);
+        return mConnectTime;
+    }
+
+    @Override
+    public long getDisconnectTime() {
+        if (VDBG) log("getDisconnectTime: ret=" + mDisconnectTime);
+        return mDisconnectTime;
+    }
+
+    @Override
+    public long getDurationMillis() {
+        long dur;
+        if (mConnectTimeReal == 0) {
+            dur = 0;
+        } else if (mDuration < 0) {
+            dur = SystemClock.elapsedRealtime() - mConnectTimeReal;
+        } else {
+            dur = mDuration;
+        }
+        if (VDBG) log("getDurationMillis: ret=" + dur);
+        return dur;
+    }
+
+    @Override
+    public long getHoldDurationMillis() {
+        long dur;
+        if (getState() != Call.State.HOLDING) {
+            // If not holding, return 0
+            dur = 0;
+        } else {
+            dur = SystemClock.elapsedRealtime() - mHoldingStartTime;
+        }
+        if (VDBG) log("getHoldDurationMillis: ret=" + dur);
+        return dur;
+    }
+
+    void setDisconnectCause(int cause) {
+        if (DBG) log("setDisconnectCause: prev=" + mCause + " new=" + cause);
+        mCause = cause;
+    }
+
+    @Override
+    public String getVendorDisconnectCause() {
+      return null;
+    }
+
+    @Override
+    public void proceedAfterWaitChar() {
+        if (DBG) log("proceedAfterWaitChar: ignore");
+    }
+
+    @Override
+    public void proceedAfterWildChar(String str) {
+        if (DBG) log("proceedAfterWildChar: ignore");
+    }
+
+    @Override
+    public void cancelPostDial() {
+        if (DBG) log("cancelPostDial: ignore");
+    }
+
+    protected abstract Phone getPhone();
+
+    private void log(String msg) {
+        Rlog.d(LOG_TAG, msg);
+    }
+
+    @Override
+    public int getNumberPresentation() {
+        // TODO: add PRESENTATION_URL
+        if (VDBG) log("getNumberPresentation: ret=PRESENTATION_ALLOWED");
+        return PhoneConstants.PRESENTATION_ALLOWED;
+    }
+
+    @Override
+    public UUSInfo getUUSInfo() {
+        // FIXME: what's this for SIP?
+        if (VDBG) log("getUUSInfo: ? ret=null");
+        return null;
+    }
+
+    @Override
+    public int getPreciseDisconnectCause() {
+        return 0;
+    }
+
+    @Override
+    public long getHoldingStartTime() {
+        return mHoldingStartTime;
+    }
+
+    @Override
+    public long getConnectTimeReal() {
+        return mConnectTimeReal;
+    }
+
+    @Override
+    public Connection getOrigConnection() {
+        return null;
+    }
+
+    @Override
+    public boolean isMultiparty() {
+        return false;
+    }
+}
diff --git a/src/java/com/android/internal/telephony/sip/SipPhone.java b/src/java/com/android/internal/telephony/sip/SipPhone.java
new file mode 100755
index 0000000..4ac1ddf
--- /dev/null
+++ b/src/java/com/android/internal/telephony/sip/SipPhone.java
@@ -0,0 +1,1121 @@
+/*
+ * Copyright (C) 2010 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.sip;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.media.AudioManager;
+import android.net.rtp.AudioGroup;
+import android.net.sip.SipAudioCall;
+import android.net.sip.SipErrorCode;
+import android.net.sip.SipException;
+import android.net.sip.SipManager;
+import android.net.sip.SipProfile;
+import android.net.sip.SipSession;
+import android.os.AsyncResult;
+import android.os.Build;
+import android.os.Message;
+import android.telephony.DisconnectCause;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.ServiceState;
+import android.text.TextUtils;
+
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.CallStateException;
+import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneNotifier;
+import com.android.telephony.Rlog;
+
+import java.text.ParseException;
+import java.util.function.Consumer;
+import java.util.regex.Pattern;
+
+/**
+ * {@hide}
+ */
+public class SipPhone extends SipPhoneBase {
+    private static final String LOG_TAG = "SipPhone";
+    private static final boolean DBG = true;
+    private static final boolean VDBG = false; // STOPSHIP if true
+    private static final int TIMEOUT_MAKE_CALL = 15; // in seconds
+    private static final int TIMEOUT_ANSWER_CALL = 8; // in seconds
+    private static final int TIMEOUT_HOLD_CALL = 15; // in seconds
+    // Minimum time needed between hold/unhold requests.
+    private static final long TIMEOUT_HOLD_PROCESSING = 1000; // ms
+
+    // A call that is ringing or (call) waiting
+    private SipCall mRingingCall = new SipCall();
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private SipCall mForegroundCall = new SipCall();
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private SipCall mBackgroundCall = new SipCall();
+
+    private SipManager mSipManager;
+    private SipProfile mProfile;
+
+    private long mTimeOfLastValidHoldRequest = System.currentTimeMillis();
+
+    SipPhone (Context context, PhoneNotifier notifier, SipProfile profile) {
+        super("SIP:" + profile.getUriString(), context, notifier);
+
+        if (DBG) log("new SipPhone: " + hidePii(profile.getUriString()));
+        mRingingCall = new SipCall();
+        mForegroundCall = new SipCall();
+        mBackgroundCall = new SipCall();
+        mProfile = profile;
+        mSipManager = SipManager.newInstance(context);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) return true;
+        if (!(o instanceof SipPhone)) return false;
+        SipPhone that = (SipPhone) o;
+        return mProfile.getUriString().equals(that.mProfile.getUriString());
+    }
+
+    public String getSipUri() {
+        return mProfile.getUriString();
+    }
+
+    public boolean equals(SipPhone phone) {
+        return getSipUri().equals(phone.getSipUri());
+    }
+
+    public Connection takeIncomingCall(Object incomingCall) {
+        // FIXME: Is synchronizing on the class necessary, should we use a mLockObj?
+        // Also there are many things not synchronized, of course
+        // this may be true of GsmCdmaPhone too!!!
+        synchronized (SipPhone.class) {
+            if (!(incomingCall instanceof SipAudioCall)) {
+                if (DBG) log("takeIncomingCall: ret=null, not a SipAudioCall");
+                return null;
+            }
+            if (mRingingCall.getState().isAlive()) {
+                if (DBG) log("takeIncomingCall: ret=null, ringingCall not alive");
+                return null;
+            }
+
+            // FIXME: is it true that we cannot take any incoming call if
+            // both foreground and background are active
+            if (mForegroundCall.getState().isAlive()
+                    && mBackgroundCall.getState().isAlive()) {
+                if (DBG) {
+                    log("takeIncomingCall: ret=null," + " foreground and background both alive");
+                }
+                return null;
+            }
+
+            try {
+                SipAudioCall sipAudioCall = (SipAudioCall) incomingCall;
+                if (DBG) log("takeIncomingCall: taking call from: "
+                        + hidePii(sipAudioCall.getPeerProfile().getUriString()));
+                String localUri = sipAudioCall.getLocalProfile().getUriString();
+                if (localUri.equals(mProfile.getUriString())) {
+                    boolean makeCallWait = mForegroundCall.getState().isAlive();
+                    SipConnection connection = mRingingCall.initIncomingCall(sipAudioCall,
+                            makeCallWait);
+                    if (sipAudioCall.getState() != SipSession.State.INCOMING_CALL) {
+                        // Peer cancelled the call!
+                        if (DBG) log("    takeIncomingCall: call cancelled !!");
+                        mRingingCall.reset();
+                        connection = null;
+                    }
+                    return connection;
+                }
+            } catch (Exception e) {
+                // Peer may cancel the call at any time during the time we hook
+                // up ringingCall with sipAudioCall. Clean up ringingCall when
+                // that happens.
+                if (DBG) log("    takeIncomingCall: exception e=" + e);
+                mRingingCall.reset();
+            }
+            if (DBG) log("takeIncomingCall: NOT taking !!");
+            return null;
+        }
+    }
+
+    @Override
+    public void acceptCall(int videoState) throws CallStateException {
+        synchronized (SipPhone.class) {
+            if ((mRingingCall.getState() == Call.State.INCOMING) ||
+                    (mRingingCall.getState() == Call.State.WAITING)) {
+                if (DBG) log("acceptCall: accepting");
+                // Always unmute when answering a new call
+                mRingingCall.setMute(false);
+                mRingingCall.acceptCall();
+            } else {
+                if (DBG) {
+                    log("acceptCall:" +
+                        " throw CallStateException(\"phone not ringing\")");
+                }
+                throw new CallStateException("phone not ringing");
+            }
+        }
+    }
+
+    @Override
+    public void rejectCall() throws CallStateException {
+        synchronized (SipPhone.class) {
+            if (mRingingCall.getState().isRinging()) {
+                if (DBG) log("rejectCall: rejecting");
+                mRingingCall.rejectCall();
+            } else {
+                if (DBG) {
+                    log("rejectCall:" +
+                        " throw CallStateException(\"phone not ringing\")");
+                }
+                throw new CallStateException("phone not ringing");
+            }
+        }
+    }
+
+    @Override
+    public Connection startConference(String[] participantsToDial, DialArgs dialArgs)
+            throws CallStateException {
+        throw new CallStateException("startConference: not supported");
+    }
+
+    @Override
+    public Connection dial(String dialString, DialArgs dialArgs,
+            Consumer<Phone> chosenPhoneConsumer) throws CallStateException {
+        chosenPhoneConsumer.accept(this);
+        synchronized (SipPhone.class) {
+            return dialInternal(dialString, dialArgs.videoState);
+        }
+    }
+
+    private Connection dialInternal(String dialString, int videoState)
+            throws CallStateException {
+        if (DBG) log("dialInternal: dialString=" + hidePii(dialString));
+        clearDisconnected();
+
+        if (!canDial()) {
+            throw new CallStateException("dialInternal: cannot dial in current state");
+        }
+        if (mForegroundCall.getState() == SipCall.State.ACTIVE) {
+            switchHoldingAndActive();
+        }
+        if (mForegroundCall.getState() != SipCall.State.IDLE) {
+            //we should have failed in !canDial() above before we get here
+            throw new CallStateException("cannot dial in current state");
+        }
+
+        mForegroundCall.setMute(false);
+        try {
+            Connection c = mForegroundCall.dial(dialString);
+            return c;
+        } catch (SipException e) {
+            loge("dialInternal: ", e);
+            throw new CallStateException("dial error: " + e);
+        }
+    }
+
+    @Override
+    public void switchHoldingAndActive() throws CallStateException {
+        // Wait for at least TIMEOUT_HOLD_PROCESSING ms to occur before sending hold/unhold requests
+        // to prevent spamming the SipAudioCall state machine and putting it into an invalid state.
+        if (!isHoldTimeoutExpired()) {
+            if (DBG) log("switchHoldingAndActive: Disregarded! Under " + TIMEOUT_HOLD_PROCESSING +
+                    " ms...");
+            return;
+        }
+        if (DBG) log("switchHoldingAndActive: switch fg and bg");
+        synchronized (SipPhone.class) {
+            mForegroundCall.switchWith(mBackgroundCall);
+            if (mBackgroundCall.getState().isAlive()) mBackgroundCall.hold();
+            if (mForegroundCall.getState().isAlive()) mForegroundCall.unhold();
+        }
+    }
+
+    @Override
+    public boolean canConference() {
+        if (DBG) log("canConference: ret=true");
+        return true;
+    }
+
+    @Override
+    public void conference() throws CallStateException {
+        synchronized (SipPhone.class) {
+            if ((mForegroundCall.getState() != SipCall.State.ACTIVE)
+                    || (mForegroundCall.getState() != SipCall.State.ACTIVE)) {
+                throw new CallStateException("wrong state to merge calls: fg="
+                        + mForegroundCall.getState() + ", bg="
+                        + mBackgroundCall.getState());
+            }
+            if (DBG) log("conference: merge fg & bg");
+            mForegroundCall.merge(mBackgroundCall);
+        }
+    }
+
+    public void conference(Call that) throws CallStateException {
+        synchronized (SipPhone.class) {
+            if (!(that instanceof SipCall)) {
+                throw new CallStateException("expect " + SipCall.class
+                        + ", cannot merge with " + that.getClass());
+            }
+            mForegroundCall.merge((SipCall) that);
+        }
+    }
+
+    @Override
+    public boolean canTransfer() {
+        return false;
+    }
+
+    @Override
+    public void explicitCallTransfer() {
+        //mCT.explicitCallTransfer();
+    }
+
+    @Override
+    public void clearDisconnected() {
+        synchronized (SipPhone.class) {
+            mRingingCall.clearDisconnected();
+            mForegroundCall.clearDisconnected();
+            mBackgroundCall.clearDisconnected();
+
+            updatePhoneState();
+            notifyPreciseCallStateChanged();
+        }
+    }
+
+    @Override
+    public void sendDtmf(char c) {
+        if (!PhoneNumberUtils.is12Key(c)) {
+            loge("sendDtmf called with invalid character '" + c + "'");
+        } else if (mForegroundCall.getState().isAlive()) {
+            synchronized (SipPhone.class) {
+                mForegroundCall.sendDtmf(c);
+            }
+        }
+    }
+
+    @Override
+    public void startDtmf(char c) {
+        if (!PhoneNumberUtils.is12Key(c)) {
+            loge("startDtmf called with invalid character '" + c + "'");
+        } else {
+            sendDtmf(c);
+        }
+    }
+
+    @Override
+    public void stopDtmf() {
+        // no op
+    }
+
+    public void sendBurstDtmf(String dtmfString) {
+        loge("sendBurstDtmf() is a CDMA method");
+    }
+
+    @Override
+    public void getOutgoingCallerIdDisplay(Message onComplete) {
+        // FIXME: what to reply?
+        AsyncResult.forMessage(onComplete, null, null);
+        onComplete.sendToTarget();
+    }
+
+    @Override
+    public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
+                                           Message onComplete) {
+        // FIXME: what's this for SIP?
+        AsyncResult.forMessage(onComplete, null, null);
+        onComplete.sendToTarget();
+    }
+
+    @Override
+    public void getCallWaiting(Message onComplete) {
+        // FIXME: what to reply?
+        AsyncResult.forMessage(onComplete, null, null);
+        onComplete.sendToTarget();
+    }
+
+    @Override
+    public void setCallWaiting(boolean enable, Message onComplete) {
+        // FIXME: what to reply?
+        loge("call waiting not supported");
+    }
+
+    @Override
+    public void setEchoSuppressionEnabled() {
+        // Echo suppression may not be available on every device. So, check
+        // whether it is supported
+        synchronized (SipPhone.class) {
+            AudioManager audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+            String echoSuppression = audioManager.getParameters("ec_supported");
+            if (echoSuppression.contains("off")) {
+                mForegroundCall.setAudioGroupMode();
+            }
+        }
+    }
+
+    @Override
+    public void setMute(boolean muted) {
+        synchronized (SipPhone.class) {
+            mForegroundCall.setMute(muted);
+        }
+    }
+
+    @Override
+    public boolean getMute() {
+        return (mForegroundCall.getState().isAlive()
+                ? mForegroundCall.getMute()
+                : mBackgroundCall.getMute());
+    }
+
+    @Override
+    public Call getForegroundCall() {
+        return mForegroundCall;
+    }
+
+    @Override
+    public Call getBackgroundCall() {
+        return mBackgroundCall;
+    }
+
+    @Override
+    public Call getRingingCall() {
+        return mRingingCall;
+    }
+
+    @Override
+    public ServiceState getServiceState() {
+        // FIXME: we may need to provide this when data connectivity is lost
+        // or when server is down
+        return super.getServiceState();
+    }
+
+    private String getUriString(SipProfile p) {
+        // SipProfile.getUriString() may contain "SIP:" and port
+        return p.getUserName() + "@" + getSipDomain(p);
+    }
+
+    private String getSipDomain(SipProfile p) {
+        String domain = p.getSipDomain();
+        // TODO: move this to SipProfile
+        if (domain.endsWith(":5060")) {
+            return domain.substring(0, domain.length() - 5);
+        } else {
+            return domain;
+        }
+    }
+
+    private static Call.State getCallStateFrom(SipAudioCall sipAudioCall) {
+        if (sipAudioCall.isOnHold()) return Call.State.HOLDING;
+        int sessionState = sipAudioCall.getState();
+        switch (sessionState) {
+            case SipSession.State.READY_TO_CALL:            return Call.State.IDLE;
+            case SipSession.State.INCOMING_CALL:
+            case SipSession.State.INCOMING_CALL_ANSWERING:  return Call.State.INCOMING;
+            case SipSession.State.OUTGOING_CALL:            return Call.State.DIALING;
+            case SipSession.State.OUTGOING_CALL_RING_BACK:  return Call.State.ALERTING;
+            case SipSession.State.OUTGOING_CALL_CANCELING:  return Call.State.DISCONNECTING;
+            case SipSession.State.IN_CALL:                  return Call.State.ACTIVE;
+            default:
+                slog("illegal connection state: " + sessionState);
+                return Call.State.DISCONNECTED;
+        }
+    }
+
+    private synchronized boolean isHoldTimeoutExpired() {
+        long currTime = System.currentTimeMillis();
+        if ((currTime - mTimeOfLastValidHoldRequest) > TIMEOUT_HOLD_PROCESSING) {
+            mTimeOfLastValidHoldRequest = currTime;
+            return true;
+        }
+        return false;
+    }
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private void log(String s) {
+        Rlog.d(LOG_TAG, s);
+    }
+
+    private static void slog(String s) {
+        Rlog.d(LOG_TAG, s);
+    }
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private void loge(String s) {
+        Rlog.e(LOG_TAG, s);
+    }
+
+    private void loge(String s, Exception e) {
+        Rlog.e(LOG_TAG, s, e);
+    }
+
+    private class SipCall extends SipCallBase {
+        private static final String SC_TAG = "SipCall";
+        private static final boolean SC_DBG = true;
+        private static final boolean SC_VDBG = false; // STOPSHIP if true
+
+        void reset() {
+            if (SC_DBG) log("reset");
+            clearConnections();
+            setState(Call.State.IDLE);
+        }
+
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        void switchWith(SipCall that) {
+            if (SC_DBG) log("switchWith");
+            synchronized (SipPhone.class) {
+                SipCall tmp = new SipCall();
+                tmp.takeOver(this);
+                this.takeOver(that);
+                that.takeOver(tmp);
+            }
+        }
+
+        private void takeOver(SipCall that) {
+            if (SC_DBG) log("takeOver");
+            copyConnectionFrom(that);
+            mState = that.mState;
+            for (Connection c : getConnections()) {
+                ((SipConnection) c).changeOwner(this);
+            }
+        }
+
+        @Override
+        public Phone getPhone() {
+            return SipPhone.this;
+        }
+
+        Connection dial(String originalNumber) throws SipException {
+            if (SC_DBG) log("dial: num=" + (SC_VDBG ? originalNumber : "xxx"));
+            // TODO: Should this be synchronized?
+            String calleeSipUri = originalNumber;
+            if (!calleeSipUri.contains("@")) {
+                String replaceStr = Pattern.quote(mProfile.getUserName() + "@");
+                calleeSipUri = mProfile.getUriString().replaceFirst(replaceStr,
+                        calleeSipUri + "@");
+            }
+            try {
+                SipProfile callee =
+                        new SipProfile.Builder(calleeSipUri).build();
+                SipConnection c = new SipConnection(this, callee,
+                        originalNumber);
+                c.dial();
+                addConnection(c);
+                setState(Call.State.DIALING);
+                return c;
+            } catch (ParseException e) {
+                throw new SipException("dial", e);
+            }
+        }
+
+        @Override
+        public void hangup() throws CallStateException {
+            synchronized (SipPhone.class) {
+                if (mState.isAlive()) {
+                    if (SC_DBG) log("hangup: call " + getState()
+                            + ": " + this + " on phone " + getPhone());
+                    setState(State.DISCONNECTING);
+                    CallStateException excp = null;
+                    for (Connection c : getConnections()) {
+                        try {
+                            c.hangup();
+                        } catch (CallStateException e) {
+                            excp = e;
+                        }
+                    }
+                    if (excp != null) throw excp;
+                } else {
+                    if (SC_DBG) log("hangup: dead call " + getState()
+                            + ": " + this + " on phone " + getPhone());
+                }
+            }
+        }
+
+        /**
+         * Hangup the ringing call with a specified reason; reason is not supported on SIP.
+         * @param rejectReason
+         */
+        @Override
+        public void hangup(@android.telecom.Call.RejectReason int rejectReason)
+                throws CallStateException  {
+            hangup();
+        }
+
+        SipConnection initIncomingCall(SipAudioCall sipAudioCall, boolean makeCallWait) {
+            SipProfile callee = sipAudioCall.getPeerProfile();
+            SipConnection c = new SipConnection(this, callee);
+            addConnection(c);
+
+            Call.State newState = makeCallWait ? State.WAITING : State.INCOMING;
+            c.initIncomingCall(sipAudioCall, newState);
+
+            setState(newState);
+            notifyNewRingingConnectionP(c);
+            return c;
+        }
+
+        void rejectCall() throws CallStateException {
+            if (SC_DBG) log("rejectCall:");
+            hangup();
+        }
+
+        void acceptCall() throws CallStateException {
+            if (SC_DBG) log("acceptCall: accepting");
+            if (this != mRingingCall) {
+                throw new CallStateException("acceptCall() in a non-ringing call");
+            }
+            if (getConnectionsCount() != 1) {
+                throw new CallStateException("acceptCall() in a conf call");
+            }
+            ((SipConnection) getConnections().get(0)).acceptCall();
+        }
+
+        private boolean isSpeakerOn() {
+            Boolean ret = ((AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE))
+                    .isSpeakerphoneOn();
+            if (SC_VDBG) log("isSpeakerOn: ret=" + ret);
+            return ret;
+        }
+
+        void setAudioGroupMode() {
+            AudioGroup audioGroup = getAudioGroup();
+            if (audioGroup == null) {
+                if (SC_DBG) log("setAudioGroupMode: audioGroup == null ignore");
+                return;
+            }
+            int mode = audioGroup.getMode();
+            if (mState == State.HOLDING) {
+                audioGroup.setMode(AudioGroup.MODE_ON_HOLD);
+            } else if (getMute()) {
+                audioGroup.setMode(AudioGroup.MODE_MUTED);
+            } else if (isSpeakerOn()) {
+                audioGroup.setMode(AudioGroup.MODE_ECHO_SUPPRESSION);
+            } else {
+                audioGroup.setMode(AudioGroup.MODE_NORMAL);
+            }
+            if (SC_DBG) log(String.format(
+                    "setAudioGroupMode change: %d --> %d", mode,
+                    audioGroup.getMode()));
+        }
+
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        void hold() throws CallStateException {
+            if (SC_DBG) log("hold:");
+            setState(State.HOLDING);
+            for (Connection c : getConnections()) ((SipConnection) c).hold();
+            setAudioGroupMode();
+        }
+
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        void unhold() throws CallStateException {
+            if (SC_DBG) log("unhold:");
+            setState(State.ACTIVE);
+            AudioGroup audioGroup = new AudioGroup(mContext);
+            for (Connection c : getConnections()) {
+                ((SipConnection) c).unhold(audioGroup);
+            }
+            setAudioGroupMode();
+        }
+
+        void setMute(boolean muted) {
+            if (SC_DBG) log("setMute: muted=" + muted);
+            for (Connection c : getConnections()) {
+                ((SipConnection) c).setMute(muted);
+            }
+        }
+
+        boolean getMute() {
+            boolean ret = getConnections().isEmpty()
+                    ? false
+                    : ((SipConnection) getConnections().get(0)).getMute();
+            if (SC_DBG) log("getMute: ret=" + ret);
+            return ret;
+        }
+
+        void merge(SipCall that) throws CallStateException {
+            if (SC_DBG) log("merge:");
+            AudioGroup audioGroup = getAudioGroup();
+
+            // copy to an array to avoid concurrent modification as connections
+            // in that.connections will be removed in add(SipConnection).
+            Connection[] cc = that.getConnections().toArray(
+                    new Connection[that.getConnectionsCount()]);
+            for (Connection c : cc) {
+                SipConnection conn = (SipConnection) c;
+                add(conn);
+                if (conn.getState() == Call.State.HOLDING) {
+                    conn.unhold(audioGroup);
+                }
+            }
+            that.setState(Call.State.IDLE);
+        }
+
+        private void add(SipConnection conn) {
+            if (SC_DBG) log("add:");
+            SipCall call = conn.getCall();
+            if (call == this) return;
+            if (call != null) call.removeConnection(conn);
+
+            addConnection(conn);
+            conn.changeOwner(this);
+        }
+
+        void sendDtmf(char c) {
+            if (SC_DBG) log("sendDtmf: c=" + c);
+            AudioGroup audioGroup = getAudioGroup();
+            if (audioGroup == null) {
+                if (SC_DBG) log("sendDtmf: audioGroup == null, ignore c=" + c);
+                return;
+            }
+            audioGroup.sendDtmf(convertDtmf(c));
+        }
+
+        private int convertDtmf(char c) {
+            int code = c - '0';
+            if ((code < 0) || (code > 9)) {
+                switch (c) {
+                    case '*': return 10;
+                    case '#': return 11;
+                    case 'A': return 12;
+                    case 'B': return 13;
+                    case 'C': return 14;
+                    case 'D': return 15;
+                    default:
+                        throw new IllegalArgumentException(
+                                "invalid DTMF char: " + (int) c);
+                }
+            }
+            return code;
+        }
+
+        @Override
+        protected void setState(State newState) {
+            if (mState != newState) {
+                if (SC_DBG) log("setState: cur state" + mState
+                        + " --> " + newState + ": " + this + ": on phone "
+                        + getPhone() + " " + getConnectionsCount());
+
+                if (newState == Call.State.ALERTING) {
+                    mState = newState; // need in ALERTING to enable ringback
+                    startRingbackTone();
+                } else if (mState == Call.State.ALERTING) {
+                    stopRingbackTone();
+                }
+                mState = newState;
+                updatePhoneState();
+                notifyPreciseCallStateChanged();
+            }
+        }
+
+        void onConnectionStateChanged(SipConnection conn) {
+            // this can be called back when a conf call is formed
+            if (SC_DBG) log("onConnectionStateChanged: conn=" + conn);
+            if (mState != State.ACTIVE) {
+                setState(conn.getState());
+            }
+        }
+
+        void onConnectionEnded(SipConnection conn) {
+            // set state to DISCONNECTED only when all conns are disconnected
+            if (SC_DBG) log("onConnectionEnded: conn=" + conn);
+            if (mState != State.DISCONNECTED) {
+                boolean allConnectionsDisconnected = true;
+                if (SC_DBG) log("---check connections: "
+                        + getConnectionsCount());
+                for (Connection c : getConnections()) {
+                    if (SC_DBG) log("   state=" + c.getState() + ": "
+                            + c);
+                    if (c.getState() != State.DISCONNECTED) {
+                        allConnectionsDisconnected = false;
+                        break;
+                    }
+                }
+                if (allConnectionsDisconnected) setState(State.DISCONNECTED);
+            }
+            notifyDisconnectP(conn);
+        }
+
+        private AudioGroup getAudioGroup() {
+            if (getConnections().isEmpty()) return null;
+            return ((SipConnection) getConnections().get(0)).getAudioGroup();
+        }
+
+        private void log(String s) {
+            Rlog.d(SC_TAG, s);
+        }
+    }
+
+    private class SipConnection extends SipConnectionBase {
+        private static final String SCN_TAG = "SipConnection";
+        private static final boolean SCN_DBG = true;
+
+        private SipCall mOwner;
+        private SipAudioCall mSipAudioCall;
+        private Call.State mState = Call.State.IDLE;
+        private SipProfile mPeer;
+        private boolean mIncoming = false;
+        private String mOriginalNumber; // may be a PSTN number
+
+        private SipAudioCallAdapter mAdapter = new SipAudioCallAdapter() {
+            @Override
+            protected void onCallEnded(int cause) {
+                if (getDisconnectCause() != DisconnectCause.LOCAL) {
+                    setDisconnectCause(cause);
+                }
+                synchronized (SipPhone.class) {
+                    setState(Call.State.DISCONNECTED);
+                    SipAudioCall sipAudioCall = mSipAudioCall;
+                    // FIXME: This goes null and is synchronized, but many uses aren't sync'd
+                    mSipAudioCall = null;
+                    String sessionState = (sipAudioCall == null)
+                            ? ""
+                            : (sipAudioCall.getState() + ", ");
+                    if (SCN_DBG) log("[SipAudioCallAdapter] onCallEnded: "
+                            + hidePii(mPeer.getUriString()) + ": " + sessionState
+                            + "cause: " + getDisconnectCause() + ", on phone "
+                            + getPhone());
+                    if (sipAudioCall != null) {
+                        sipAudioCall.setListener(null);
+                        sipAudioCall.close();
+                    }
+                    mOwner.onConnectionEnded(SipConnection.this);
+                }
+            }
+
+            @Override
+            public void onCallEstablished(SipAudioCall call) {
+                onChanged(call);
+                // Race onChanged synchronized this isn't
+                if (mState == Call.State.ACTIVE) call.startAudio();
+            }
+
+            @Override
+            public void onCallHeld(SipAudioCall call) {
+                onChanged(call);
+                // Race onChanged synchronized this isn't
+                if (mState == Call.State.HOLDING) call.startAudio();
+            }
+
+            @Override
+            public void onChanged(SipAudioCall call) {
+                synchronized (SipPhone.class) {
+                    Call.State newState = getCallStateFrom(call);
+                    if (mState == newState) return;
+                    if (newState == Call.State.INCOMING) {
+                        setState(mOwner.getState()); // INCOMING or WAITING
+                    } else {
+                        if (mOwner == mRingingCall) {
+                            if (mRingingCall.getState() == Call.State.WAITING) {
+                                try {
+                                    switchHoldingAndActive();
+                                } catch (CallStateException e) {
+                                    // disconnect the call.
+                                    onCallEnded(DisconnectCause.LOCAL);
+                                    return;
+                                }
+                            }
+                            mForegroundCall.switchWith(mRingingCall);
+                        }
+                        setState(newState);
+                    }
+                    mOwner.onConnectionStateChanged(SipConnection.this);
+                    if (SCN_DBG) {
+                        log("onChanged: " + hidePii(mPeer.getUriString()) + ": " + mState
+                                + " on phone " + getPhone());
+                    }
+                }
+            }
+
+            @Override
+            protected void onError(int cause) {
+                if (SCN_DBG) log("onError: " + cause);
+                onCallEnded(cause);
+            }
+        };
+
+        public SipConnection(SipCall owner, SipProfile callee,
+                String originalNumber) {
+            super(originalNumber);
+            mOwner = owner;
+            mPeer = callee;
+            mOriginalNumber = originalNumber;
+        }
+
+        public SipConnection(SipCall owner, SipProfile callee) {
+            this(owner, callee, getUriString(callee));
+        }
+
+        @Override
+        public String getCnapName() {
+            String displayName = mPeer.getDisplayName();
+            return TextUtils.isEmpty(displayName) ? null
+                                                  : displayName;
+        }
+
+        @Override
+        public int getNumberPresentation() {
+            return PhoneConstants.PRESENTATION_ALLOWED;
+        }
+
+        void initIncomingCall(SipAudioCall sipAudioCall, Call.State newState) {
+            setState(newState);
+            mSipAudioCall = sipAudioCall;
+            sipAudioCall.setListener(mAdapter); // call back to set state
+            mIncoming = true;
+        }
+
+        void acceptCall() throws CallStateException {
+            try {
+                mSipAudioCall.answerCall(TIMEOUT_ANSWER_CALL);
+            } catch (SipException e) {
+                throw new CallStateException("acceptCall(): " + e);
+            }
+        }
+
+        void changeOwner(SipCall owner) {
+            mOwner = owner;
+        }
+
+        AudioGroup getAudioGroup() {
+            if (mSipAudioCall == null) return null;
+            return mSipAudioCall.getAudioGroup();
+        }
+
+        void dial() throws SipException {
+            setState(Call.State.DIALING);
+            mSipAudioCall = mSipManager.makeAudioCall(mProfile, mPeer, null,
+                    TIMEOUT_MAKE_CALL);
+            mSipAudioCall.setListener(mAdapter);
+        }
+
+        void hold() throws CallStateException {
+            setState(Call.State.HOLDING);
+            try {
+                mSipAudioCall.holdCall(TIMEOUT_HOLD_CALL);
+            } catch (SipException e) {
+                throw new CallStateException("hold(): " + e);
+            }
+        }
+
+        void unhold(AudioGroup audioGroup) throws CallStateException {
+            mSipAudioCall.setAudioGroup(audioGroup);
+            setState(Call.State.ACTIVE);
+            try {
+                mSipAudioCall.continueCall(TIMEOUT_HOLD_CALL);
+            } catch (SipException e) {
+                throw new CallStateException("unhold(): " + e);
+            }
+        }
+
+        void setMute(boolean muted) {
+            if ((mSipAudioCall != null) && (muted != mSipAudioCall.isMuted())) {
+                if (SCN_DBG) log("setState: prev muted=" + !muted + " new muted=" + muted);
+                mSipAudioCall.toggleMute();
+            }
+        }
+
+        boolean getMute() {
+            return (mSipAudioCall == null) ? false
+                                           : mSipAudioCall.isMuted();
+        }
+
+        @Override
+        protected void setState(Call.State state) {
+            if (state == mState) return;
+            super.setState(state);
+            mState = state;
+        }
+
+        @Override
+        public Call.State getState() {
+            return mState;
+        }
+
+        @Override
+        public boolean isIncoming() {
+            return mIncoming;
+        }
+
+        @Override
+        public String getAddress() {
+            // Phone app uses this to query caller ID. Return the original dial
+            // number (which may be a PSTN number) instead of the peer's SIP
+            // URI.
+            return mOriginalNumber;
+        }
+
+        @Override
+        public SipCall getCall() {
+            return mOwner;
+        }
+
+        @Override
+        protected Phone getPhone() {
+            return mOwner.getPhone();
+        }
+
+        @Override
+        public void hangup() throws CallStateException {
+            synchronized (SipPhone.class) {
+                if (SCN_DBG) {
+                    log("hangup: conn=" + hidePii(mPeer.getUriString())
+                            + ": " + mState + ": on phone "
+                            + getPhone().getPhoneName());
+                }
+                if (!mState.isAlive()) return;
+                try {
+                    SipAudioCall sipAudioCall = mSipAudioCall;
+                    if (sipAudioCall != null) {
+                        sipAudioCall.setListener(null);
+                        sipAudioCall.endCall();
+                    }
+                } catch (SipException e) {
+                    throw new CallStateException("hangup(): " + e);
+                } finally {
+                    mAdapter.onCallEnded(((mState == Call.State.INCOMING)
+                            || (mState == Call.State.WAITING))
+                            ? DisconnectCause.INCOMING_REJECTED
+                            : DisconnectCause.LOCAL);
+                }
+            }
+        }
+
+        @Override
+        public void separate() throws CallStateException {
+            synchronized (SipPhone.class) {
+                SipCall call = (getPhone() == SipPhone.this)
+                        ? (SipCall) getBackgroundCall()
+                        : (SipCall) getForegroundCall();
+                if (call.getState() != Call.State.IDLE) {
+                    throw new CallStateException(
+                            "cannot put conn back to a call in non-idle state: "
+                            + call.getState());
+                }
+                if (SCN_DBG) log("separate: conn="
+                        + mPeer.getUriString() + " from " + mOwner + " back to "
+                        + call);
+
+                // separate the AudioGroup and connection from the original call
+                Phone originalPhone = getPhone();
+                AudioGroup audioGroup = call.getAudioGroup(); // may be null
+                call.add(this);
+                mSipAudioCall.setAudioGroup(audioGroup);
+
+                // put the original call to bg; and the separated call becomes
+                // fg if it was in bg
+                originalPhone.switchHoldingAndActive();
+
+                // start audio and notify the phone app of the state change
+                call = (SipCall) getForegroundCall();
+                mSipAudioCall.startAudio();
+                call.onConnectionStateChanged(this);
+            }
+        }
+
+        @Override
+        public void deflect(String number) throws CallStateException {
+            //Deflect is not supported.
+            throw new CallStateException ("deflect is not supported for SipPhone");
+        }
+
+        @Override
+        public void transfer(String number, boolean isConfirmationRequired)
+                throws CallStateException {
+            //Transfer is not supported.
+            throw new CallStateException("transfer is not supported for SipPhone");
+        }
+
+        @Override
+        public void consultativeTransfer(Connection other) throws CallStateException {
+            //Transfer is not supported.
+            throw new CallStateException("transfer is not supported for SipPhone");
+        }
+
+        private void log(String s) {
+            Rlog.d(SCN_TAG, s);
+        }
+    }
+
+    private abstract class SipAudioCallAdapter extends SipAudioCall.Listener {
+        private static final String SACA_TAG = "SipAudioCallAdapter";
+        private static final boolean SACA_DBG = true;
+        /** Call ended with cause defined in {@link DisconnectCause}. */
+        protected abstract void onCallEnded(int cause);
+        /** Call failed with cause defined in {@link DisconnectCause}. */
+        protected abstract void onError(int cause);
+
+        @Override
+        public void onCallEnded(SipAudioCall call) {
+            if (SACA_DBG) log("onCallEnded: call=" + call);
+            onCallEnded(call.isInCall()
+                    ? DisconnectCause.NORMAL
+                    : DisconnectCause.INCOMING_MISSED);
+        }
+
+        @Override
+        public void onCallBusy(SipAudioCall call) {
+            if (SACA_DBG) log("onCallBusy: call=" + call);
+            onCallEnded(DisconnectCause.BUSY);
+        }
+
+        @Override
+        public void onError(SipAudioCall call, int errorCode,
+                String errorMessage) {
+            if (SACA_DBG) {
+                log("onError: call=" + call + " code="+ SipErrorCode.toString(errorCode)
+                    + ": " + errorMessage);
+            }
+            switch (errorCode) {
+                case SipErrorCode.SERVER_UNREACHABLE:
+                    onError(DisconnectCause.SERVER_UNREACHABLE);
+                    break;
+                case SipErrorCode.PEER_NOT_REACHABLE:
+                    onError(DisconnectCause.NUMBER_UNREACHABLE);
+                    break;
+                case SipErrorCode.INVALID_REMOTE_URI:
+                    onError(DisconnectCause.INVALID_NUMBER);
+                    break;
+                case SipErrorCode.TIME_OUT:
+                case SipErrorCode.TRANSACTION_TERMINTED:
+                    onError(DisconnectCause.TIMED_OUT);
+                    break;
+                case SipErrorCode.DATA_CONNECTION_LOST:
+                    onError(DisconnectCause.LOST_SIGNAL);
+                    break;
+                case SipErrorCode.INVALID_CREDENTIALS:
+                    onError(DisconnectCause.INVALID_CREDENTIALS);
+                    break;
+                case SipErrorCode.CROSS_DOMAIN_AUTHENTICATION:
+                    onError(DisconnectCause.OUT_OF_NETWORK);
+                    break;
+                case SipErrorCode.SERVER_ERROR:
+                    onError(DisconnectCause.SERVER_ERROR);
+                    break;
+                case SipErrorCode.SOCKET_ERROR:
+                case SipErrorCode.CLIENT_ERROR:
+                default:
+                    onError(DisconnectCause.ERROR_UNSPECIFIED);
+            }
+        }
+
+        private void log(String s) {
+            Rlog.d(SACA_TAG, s);
+        }
+    }
+
+    public static String hidePii(String s) {
+        return VDBG ? Rlog.pii(LOG_TAG, s) : "xxxxx";
+    }
+}
diff --git a/src/java/com/android/internal/telephony/sip/SipPhoneBase.java b/src/java/com/android/internal/telephony/sip/SipPhoneBase.java
new file mode 100755
index 0000000..dea124b
--- /dev/null
+++ b/src/java/com/android/internal/telephony/sip/SipPhoneBase.java
@@ -0,0 +1,534 @@
+/*
+ * Copyright (C) 2010 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.sip;
+
+import android.content.Context;
+import android.net.LinkProperties;
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RegistrantList;
+import android.os.ResultReceiver;
+import android.sysprop.TelephonyProperties;
+import android.telephony.NetworkScanRequest;
+import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
+
+import com.android.internal.telephony.Call;
+import com.android.internal.telephony.Connection;
+import com.android.internal.telephony.IccCard;
+import com.android.internal.telephony.IccPhoneBookInterfaceManager;
+import com.android.internal.telephony.MmiCode;
+import com.android.internal.telephony.OperatorInfo;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.PhoneNotifier;
+import com.android.internal.telephony.uicc.IccFileHandler;
+import com.android.telephony.Rlog;
+
+import java.util.ArrayList;
+import java.util.List;
+
+abstract class SipPhoneBase extends Phone {
+    private static final String LOG_TAG = "SipPhoneBase";
+
+    private RegistrantList mRingbackRegistrants = new RegistrantList();
+    private PhoneConstants.State mState = PhoneConstants.State.IDLE;
+
+    public SipPhoneBase(String name, Context context, PhoneNotifier notifier) {
+        super(name, notifier, context, new SipCommandInterface(context), false);
+    }
+
+    @Override
+    public abstract Call getForegroundCall();
+
+    @Override
+    public abstract Call getBackgroundCall();
+
+    @Override
+    public abstract Call getRingingCall();
+
+    void migrateFrom(SipPhoneBase from) {
+        super.migrateFrom(from);
+        migrate(mRingbackRegistrants, from.mRingbackRegistrants);
+    }
+
+    @Override
+    public void registerForRingbackTone(Handler h, int what, Object obj) {
+        mRingbackRegistrants.addUnique(h, what, obj);
+    }
+
+    @Override
+    public void unregisterForRingbackTone(Handler h) {
+        mRingbackRegistrants.remove(h);
+    }
+
+    @Override
+    public void startRingbackTone() {
+        AsyncResult result = new AsyncResult(null, Boolean.TRUE, null);
+        mRingbackRegistrants.notifyRegistrants(result);
+    }
+
+    @Override
+    public void stopRingbackTone() {
+        AsyncResult result = new AsyncResult(null, Boolean.FALSE, null);
+        mRingbackRegistrants.notifyRegistrants(result);
+    }
+
+    @Override
+    public ServiceState getServiceState() {
+        // FIXME: we may need to provide this when data connectivity is lost
+        // or when server is down
+        ServiceState s = new ServiceState();
+        s.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
+        return s;
+    }
+
+    @Override
+    public PhoneConstants.State getState() {
+        return mState;
+    }
+
+    @Override
+    public int getPhoneType() {
+        return PhoneConstants.PHONE_TYPE_SIP;
+    }
+
+    @Override
+    public SignalStrength getSignalStrength() {
+        return new SignalStrength();
+    }
+
+    @Override
+    public boolean getMessageWaitingIndicator() {
+        return false;
+    }
+
+    @Override
+    public boolean getCallForwardingIndicator() {
+        return false;
+    }
+
+    @Override
+    public List<? extends MmiCode> getPendingMmiCodes() {
+        return new ArrayList<MmiCode>(0);
+    }
+
+    @Override
+    public PhoneConstants.DataState getDataConnectionState() {
+        return PhoneConstants.DataState.DISCONNECTED;
+    }
+
+    @Override
+    public DataActivityState getDataActivityState() {
+        return DataActivityState.NONE;
+    }
+
+    /**
+     * SIP phones do not have a subscription id, so do not notify of specific phone state changes.
+     */
+    /* package */ void notifyPhoneStateChanged() {
+        // Do nothing.
+    }
+
+    /**
+     * Notify registrants of a change in the call state. This notifies changes in
+     * {@link com.android.internal.telephony.Call.State}. Use this when changes
+     * in the precise call state are needed, else use notifyPhoneStateChanged.
+     */
+    /* package */ void notifyPreciseCallStateChanged() {
+        /* we'd love it if this was package-scoped*/
+        super.notifyPreciseCallStateChangedP();
+    }
+
+    void notifyNewRingingConnection(Connection c) {
+        super.notifyNewRingingConnectionP(c);
+    }
+
+    void notifyDisconnect(Connection cn) {
+        mDisconnectRegistrants.notifyResult(cn);
+    }
+
+    void notifyUnknownConnection() {
+        mUnknownConnectionRegistrants.notifyResult(this);
+    }
+
+    void notifySuppServiceFailed(SuppService code) {
+        mSuppServiceFailedRegistrants.notifyResult(code);
+    }
+
+    void notifyServiceStateChanged(ServiceState ss) {
+        super.notifyServiceStateChangedP(ss);
+    }
+
+    @Override
+    public void notifyCallForwardingIndicator() {
+        mNotifier.notifyCallForwardingChanged(this);
+    }
+
+    public boolean canDial() {
+        int serviceState = getServiceState().getState();
+        Rlog.v(LOG_TAG, "canDial(): serviceState = " + serviceState);
+        if (serviceState == ServiceState.STATE_POWER_OFF) return false;
+
+        boolean disableCall = TelephonyProperties.disable_call().orElse(false);
+        Rlog.v(LOG_TAG, "canDial(): disableCall = " + disableCall);
+        if (disableCall) return false;
+
+        Rlog.v(LOG_TAG, "canDial(): ringingCall: " + getRingingCall().getState());
+        Rlog.v(LOG_TAG, "canDial(): foregndCall: " + getForegroundCall().getState());
+        Rlog.v(LOG_TAG, "canDial(): backgndCall: " + getBackgroundCall().getState());
+        return !getRingingCall().isRinging()
+                && (!getForegroundCall().getState().isAlive()
+                    || !getBackgroundCall().getState().isAlive());
+    }
+
+    @Override
+    public boolean handleInCallMmiCommands(String dialString) {
+        return false;
+    }
+
+    boolean isInCall() {
+        Call.State foregroundCallState = getForegroundCall().getState();
+        Call.State backgroundCallState = getBackgroundCall().getState();
+        Call.State ringingCallState = getRingingCall().getState();
+
+       return (foregroundCallState.isAlive() || backgroundCallState.isAlive()
+            || ringingCallState.isAlive());
+    }
+
+    @Override
+    public boolean handlePinMmi(String dialString) {
+        return false;
+    }
+
+    @Override
+    public boolean handleUssdRequest(String dialString, ResultReceiver wrappedCallback) {
+        return false;
+    }
+
+    @Override
+    public void sendUssdResponse(String ussdMessge) {
+    }
+
+    @Override
+    public void registerForSuppServiceNotification(
+            Handler h, int what, Object obj) {
+    }
+
+    @Override
+    public void unregisterForSuppServiceNotification(Handler h) {
+    }
+
+    @Override
+    public void setRadioPower(boolean power) {
+    }
+
+    @Override
+    public String getVoiceMailNumber() {
+        return null;
+    }
+
+    @Override
+    public String getVoiceMailAlphaTag() {
+        return null;
+    }
+
+    @Override
+    public String getDeviceId() {
+        return null;
+    }
+
+    @Override
+    public String getDeviceSvn() {
+        return null;
+    }
+
+    @Override
+    public String getImei() {
+        return null;
+    }
+
+    @Override
+    public String getEsn() {
+        Rlog.e(LOG_TAG, "[SipPhone] getEsn() is a CDMA method");
+        return "0";
+    }
+
+    @Override
+    public String getMeid() {
+        Rlog.e(LOG_TAG, "[SipPhone] getMeid() is a CDMA method");
+        return "0";
+    }
+
+    @Override
+    public String getSubscriberId() {
+        return null;
+    }
+
+    @Override
+    public String getGroupIdLevel1() {
+        return null;
+    }
+
+    @Override
+    public String getGroupIdLevel2() {
+        return null;
+    }
+
+    @Override
+    public String getIccSerialNumber() {
+        return null;
+    }
+
+    @Override
+    public String getLine1Number() {
+        return null;
+    }
+
+    @Override
+    public String getLine1AlphaTag() {
+        return null;
+    }
+
+    @Override
+    public boolean setLine1Number(String alphaTag, String number, Message onComplete) {
+        // FIXME: what to reply for SIP?
+        return false;
+    }
+
+    @Override
+    public void setVoiceMailNumber(String alphaTag, String voiceMailNumber,
+            Message onComplete) {
+        // FIXME: what to reply for SIP?
+        AsyncResult.forMessage(onComplete, null, null);
+        onComplete.sendToTarget();
+    }
+
+    @Override
+    public void getCallForwardingOption(int commandInterfaceCFReason, Message onComplete) {
+    }
+
+    @Override
+    public void getCallForwardingOption(int commandInterfaceCFReason, int serviceClass,
+            Message onComplete) {
+    }
+
+    @Override
+    public void setCallForwardingOption(int commandInterfaceCFAction,
+            int commandInterfaceCFReason, String dialingNumber,
+            int timerSeconds, Message onComplete) {
+    }
+
+    @Override
+    public void setCallForwardingOption(int commandInterfaceCFAction,
+            int commandInterfaceCFReason, String dialingNumber, int serviceClass,
+            int timerSeconds, Message onComplete) {
+    }
+
+    @Override
+    public void getOutgoingCallerIdDisplay(Message onComplete) {
+        // FIXME: what to reply?
+        AsyncResult.forMessage(onComplete, null, null);
+        onComplete.sendToTarget();
+    }
+
+    @Override
+    public void setOutgoingCallerIdDisplay(int commandInterfaceCLIRMode,
+                                           Message onComplete) {
+        // FIXME: what's this for SIP?
+        AsyncResult.forMessage(onComplete, null, null);
+        onComplete.sendToTarget();
+    }
+
+    @Override
+    public void getCallWaiting(Message onComplete) {
+        AsyncResult.forMessage(onComplete, null, null);
+        onComplete.sendToTarget();
+    }
+
+    @Override
+    public void setCallWaiting(boolean enable, Message onComplete) {
+        Rlog.e(LOG_TAG, "call waiting not supported");
+    }
+
+    @Override
+    public boolean getIccRecordsLoaded() {
+        return false;
+    }
+
+    @Override
+    public IccCard getIccCard() {
+        return null;
+    }
+
+    @Override
+    public void getAvailableNetworks(Message response) {
+    }
+
+    @Override
+    public void startNetworkScan(NetworkScanRequest nsr, Message response) {
+    }
+
+    @Override
+    public void stopNetworkScan(Message response) {
+    }
+
+    @Override
+    public void setNetworkSelectionModeAutomatic(Message response) {
+    }
+
+    @Override
+    public void selectNetworkManually(OperatorInfo network, boolean persistSelection,
+            Message response) {
+    }
+
+    @Override
+    public void setOnPostDialCharacter(Handler h, int what, Object obj) {
+    }
+
+    @Override
+    public void updateServiceLocation() {
+    }
+
+    @Override
+    public void enableLocationUpdates() {
+    }
+
+    @Override
+    public void disableLocationUpdates() {
+    }
+
+    @Override
+    public boolean getDataRoamingEnabled() {
+        return false;
+    }
+
+    @Override
+    public void setDataRoamingEnabled(boolean enable) {
+    }
+
+    @Override
+    public boolean isUserDataEnabled() {
+        return false;
+    }
+
+    public boolean enableDataConnectivity() {
+        return false;
+    }
+
+    public boolean disableDataConnectivity() {
+        return false;
+    }
+
+    @Override
+    public boolean isDataAllowed(int apnType) {
+        return false;
+    }
+
+    public void saveClirSetting(int commandInterfaceCLIRMode) {
+    }
+
+    @Override
+    public IccPhoneBookInterfaceManager getIccPhoneBookInterfaceManager(){
+        return null;
+    }
+
+    @Override
+    public IccFileHandler getIccFileHandler(){
+        return null;
+    }
+
+    @Override
+    public void activateCellBroadcastSms(int activate, Message response) {
+        Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP.");
+    }
+
+    @Override
+    public void getCellBroadcastSmsConfig(Message response) {
+        Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP.");
+    }
+
+    @Override
+    public void setCellBroadcastSmsConfig(int[] configValuesArray, Message response){
+        Rlog.e(LOG_TAG, "Error! This functionality is not implemented for SIP.");
+    }
+
+    //@Override
+    @Override
+    public boolean needsOtaServiceProvisioning() {
+        // FIXME: what's this for SIP?
+        return false;
+    }
+
+    //@Override
+    @Override
+    public LinkProperties getLinkProperties(String apnType) {
+        // FIXME: what's this for SIP?
+        return null;
+    }
+
+    /**
+     * Determines if video calling is enabled.  Always {@code false} for SIP.
+     *
+     * @return {@code false} since SIP does not support video calling.
+     */
+    @Override
+    public boolean isVideoEnabled() {
+        return false;
+    }
+
+    void updatePhoneState() {
+        PhoneConstants.State oldState = mState;
+
+        if (getRingingCall().isRinging()) {
+            mState = PhoneConstants.State.RINGING;
+        } else if (getForegroundCall().isIdle()
+                && getBackgroundCall().isIdle()) {
+            mState = PhoneConstants.State.IDLE;
+        } else {
+            mState = PhoneConstants.State.OFFHOOK;
+        }
+
+        if (mState != oldState) {
+            Rlog.d(LOG_TAG, " ^^^ new phone state: " + mState);
+            notifyPhoneStateChanged();
+        }
+    }
+
+    @Override
+    protected void onUpdateIccAvailability() {
+    }
+
+    @Override
+    public void sendEmergencyCallStateChange(boolean callActive) {
+    }
+
+    @Override
+    public void setBroadcastEmergencyCallStateChanges(boolean broadcast) {
+    }
+
+    @Override
+    public void getCallBarring(String facility, String password, Message onComplete,
+            int serviceClass) {
+    }
+
+    @Override
+    public void setCallBarring(String facility, boolean lockState, String password,
+            Message onComplete, int serviceClass) {
+    }
+}
diff --git a/src/java/com/android/internal/telephony/sip/SipPhoneFactory.java b/src/java/com/android/internal/telephony/sip/SipPhoneFactory.java
new file mode 100644
index 0000000..42b7be7
--- /dev/null
+++ b/src/java/com/android/internal/telephony/sip/SipPhoneFactory.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 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.sip;
+
+import android.content.Context;
+import android.net.sip.SipProfile;
+
+import com.android.internal.telephony.PhoneNotifier;
+import com.android.telephony.Rlog;
+
+import java.text.ParseException;
+
+/**
+ * {@hide}
+ */
+public class SipPhoneFactory {
+    /**
+     * Makes a {@link SipPhone} object.
+     * @param sipUri the local SIP URI the phone runs on
+     * @param context {@code Context} needed to create a Phone object
+     * @param phoneNotifier {@code PhoneNotifier} needed to create a Phone
+     *      object
+     * @return the {@code SipPhone} object or null if the SIP URI is not valid
+     */
+    public static SipPhone makePhone(String sipUri, Context context,
+            PhoneNotifier phoneNotifier) {
+        try {
+            SipProfile profile = new SipProfile.Builder(sipUri).build();
+            return new SipPhone(context, phoneNotifier, profile);
+        } catch (ParseException e) {
+            Rlog.w("SipPhoneFactory", "makePhone", e);
+            return null;
+        }
+    }
+}
diff --git a/src/java/com/android/internal/telephony/uicc/AdnCapacity.java b/src/java/com/android/internal/telephony/uicc/AdnCapacity.java
index 479786c..300759a 100644
--- a/src/java/com/android/internal/telephony/uicc/AdnCapacity.java
+++ b/src/java/com/android/internal/telephony/uicc/AdnCapacity.java
@@ -16,6 +16,7 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.hardware.radio.V1_6.PhonebookCapacity;
 import android.os.Parcel;
 import android.os.Parcelable;
 
@@ -54,8 +55,19 @@
         mMaxAnrLength = maxAnrLength;
     }
 
-    public AdnCapacity() {
-        this(0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
+    public AdnCapacity(PhonebookCapacity pbCap) {
+        if (pbCap != null) {
+            mMaxAdnCount = pbCap.maxAdnRecords;
+            mUsedAdnCount = pbCap.usedAdnRecords;
+            mMaxEmailCount = pbCap.maxEmailRecords;
+            mUsedEmailCount = pbCap.usedEmailRecords;
+            mMaxAnrCount = pbCap.maxAdditionalNumberRecords;
+            mUsedAnrCount = pbCap.usedAdditionalNumberRecords;
+            mMaxNameLength = pbCap.maxNameLen;
+            mMaxNumberLength = pbCap.maxNumberLen;
+            mMaxEmailLength = pbCap.maxEmailLen;
+            mMaxAnrLength = pbCap.maxAdditionalNumberLen;
+        }
     }
 
     public int getMaxAdnCount() {
@@ -102,14 +114,6 @@
         return mMaxAdnCount == mUsedAdnCount;
     }
 
-    public boolean isSimEmpty() {
-        return mUsedAdnCount == 0;
-    }
-
-    public boolean isSimValid() {
-        return mMaxAdnCount > 0;
-    }
-
     public static final Parcelable.Creator<AdnCapacity> CREATOR
             = new Parcelable.Creator<AdnCapacity>() {
         @Override
diff --git a/src/java/com/android/internal/telephony/uicc/AnswerToReset.java b/src/java/com/android/internal/telephony/uicc/AnswerToReset.java
index 8e4d217..9ded7d6 100644
--- a/src/java/com/android/internal/telephony/uicc/AnswerToReset.java
+++ b/src/java/com/android/internal/telephony/uicc/AnswerToReset.java
@@ -41,7 +41,6 @@
     private static final int B8_MASK = 0x80;
     private static final int B7_MASK = 0x40;
     private static final int B2_MASK = 0x02;
-    private static final int B1_MASK = 0x01;
 
     public static final byte DIRECT_CONVENTION = (byte) 0x3B;
     public static final byte INVERSE_CONVENTION = (byte) 0x3F;
@@ -56,7 +55,6 @@
     private boolean mIsDirectConvention;
     private boolean mOnlyTEqualsZero = true;
     private boolean mIsEuiccSupported;
-    private boolean mIsMultipleEnabledProfilesSupported = false;
     private byte mFormatByte;
     private ArrayList<InterfaceByte> mInterfaceBytes = new ArrayList<>();
     private HistoricalBytes mHistoricalBytes;
@@ -149,21 +147,15 @@
         return b == null ? null : IccUtils.byteToHex(b);
     }
 
-    private void checkEuiccSupportedCapabilities() {
+    private void checkIsEuiccSupported() {
         // eUICC is supported only if the b8 and b2 of the first tB after T=15 are set to 1.
-        // MEP is supported only if the b8 and b1 of the first tB after T=15 are set to 1.
         for (int i = 0; i < mInterfaceBytes.size() - 1; i++) {
             if (mInterfaceBytes.get(i).getTD() != null
                     && (mInterfaceBytes.get(i).getTD() & T_MASK) == T_VALUE_FOR_GLOBAL_INTERFACE
-                    && mInterfaceBytes.get(i + 1).getTB() != null) {
-                if ((mInterfaceBytes.get(i + 1).getTB() & B8_MASK) != 0
-                        && (mInterfaceBytes.get(i + 1).getTB() & B2_MASK) != 0) {
-                    mIsEuiccSupported = true;
-                }
-                if ((mInterfaceBytes.get(i + 1).getTB() & B8_MASK) != 0
-                        && (mInterfaceBytes.get(i + 1).getTB() & B1_MASK) != 0) {
-                    mIsMultipleEnabledProfilesSupported = true;
-                }
+                    && mInterfaceBytes.get(i + 1).getTB() != null
+                    && (mInterfaceBytes.get(i + 1).getTB() & B8_MASK) != 0
+                    && (mInterfaceBytes.get(i + 1).getTB() & B2_MASK) != 0) {
+                mIsEuiccSupported = true;
                 return;
             }
         }
@@ -338,7 +330,7 @@
             return false;
         }
         log("Successfully parsed the ATR string " + atr + " into " + toString());
-        checkEuiccSupportedCapabilities();
+        checkIsEuiccSupported();
         return true;
     }
 
@@ -485,10 +477,6 @@
         }
     }
 
-    public boolean isMultipleEnabledProfilesSupported() {
-        return mIsMultipleEnabledProfilesSupported;
-    }
-
     @Override
     public String toString() {
         StringBuffer sb = new StringBuffer();
diff --git a/src/java/com/android/internal/telephony/uicc/CarrierTestOverride.java b/src/java/com/android/internal/telephony/uicc/CarrierTestOverride.java
index 48077f8..da51848 100644
--- a/src/java/com/android/internal/telephony/uicc/CarrierTestOverride.java
+++ b/src/java/com/android/internal/telephony/uicc/CarrierTestOverride.java
@@ -53,7 +53,7 @@
        </carrierTestOverrides>
      */
     static final String DATA_CARRIER_TEST_OVERRIDE_PATH =
-            "/user_de/0/com.android.phone/files/carrier_test_conf_sim";
+            "/user_de/0/com.android.phone/files/carrier_test_conf.xml";
     static final String CARRIER_TEST_XML_HEADER = "carrierTestOverrides";
     static final String CARRIER_TEST_XML_SUBHEADER = "carrierTestOverride";
     static final String CARRIER_TEST_XML_ITEM_KEY = "key";
@@ -69,9 +69,9 @@
 
     private HashMap<String, String> mCarrierTestParamMap;
 
-    CarrierTestOverride(int phoneId) {
+    CarrierTestOverride() {
         mCarrierTestParamMap = new HashMap<String, String>();
-        loadCarrierTestOverrides(phoneId);
+        loadCarrierTestOverrides();
     }
 
     boolean isInTestMode() {
@@ -169,12 +169,12 @@
         mCarrierTestParamMap.put(CARRIER_TEST_XML_ITEM_KEY_STRING_SPN, spn);
     }
 
-    private void loadCarrierTestOverrides(int phoneId) {
+    private void loadCarrierTestOverrides() {
 
         FileReader carrierTestConfigReader;
-        String filePath = DATA_CARRIER_TEST_OVERRIDE_PATH + Integer.toString(phoneId) + ".xml";
-        Rlog.d(LOG_TAG, "File path : " + filePath);
-        File carrierTestConfigFile = new File(Environment.getDataDirectory(), filePath);
+
+        File carrierTestConfigFile = new File(Environment.getDataDirectory(),
+                DATA_CARRIER_TEST_OVERRIDE_PATH);
 
         try {
             carrierTestConfigReader = new FileReader(carrierTestConfigFile);
diff --git a/src/java/com/android/internal/telephony/uicc/IccCardApplicationStatus.java b/src/java/com/android/internal/telephony/uicc/IccCardApplicationStatus.java
index 840a6b3..fb8b111 100644
--- a/src/java/com/android/internal/telephony/uicc/IccCardApplicationStatus.java
+++ b/src/java/com/android/internal/telephony/uicc/IccCardApplicationStatus.java
@@ -155,7 +155,7 @@
     // null terminated string
     public String         app_label;
     // applicable to USIM and CSIM
-    public boolean        pin1_replaced;
+    public int            pin1_replaced;
     public PinState       pin1;
     public PinState       pin2;
 
diff --git a/src/java/com/android/internal/telephony/uicc/IccCardStatus.java b/src/java/com/android/internal/telephony/uicc/IccCardStatus.java
index ec07780..74f7a41 100644
--- a/src/java/com/android/internal/telephony/uicc/IccCardStatus.java
+++ b/src/java/com/android/internal/telephony/uicc/IccCardStatus.java
@@ -20,9 +20,6 @@
 import android.os.Build;
 import android.telephony.SubscriptionInfo;
 
-import com.android.internal.telephony.util.TelephonyUtils;
-import com.android.telephony.Rlog;
-
 /**
  * See also RIL_CardStatus in include/telephony/ril.h
  *
@@ -81,6 +78,7 @@
     public int        mCdmaSubscriptionAppIndex;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public int        mImsSubscriptionAppIndex;
+    public int        physicalSlotIndex = UiccController.INVALID_SLOT_ID;
     public String     atr;
     public String     iccid;
     public String     eid;
@@ -88,8 +86,6 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public IccCardApplicationStatus[] mApplications;
 
-    public IccSlotPortMapping mSlotPortMapping;
-
     public void setCardState(int state) {
         switch(state) {
         case 0:
@@ -171,10 +167,9 @@
             sb.append(app == null ? "null" : app);
         }
 
-        sb.append(",atr=").append(atr);
+        sb.append(",physical_slot_id=").append(physicalSlotIndex).append(",atr=").append(atr);
         sb.append(",iccid=").append(SubscriptionInfo.givePrintableIccid(iccid));
-        sb.append(",eid=").append(Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, eid));
-        sb.append(",SlotPortMapping=").append(mSlotPortMapping);
+        sb.append(",eid=").append(eid);
 
         sb.append("}");
         return sb.toString();
diff --git a/src/java/com/android/internal/telephony/uicc/IccRecords.java b/src/java/com/android/internal/telephony/uicc/IccRecords.java
index 3a7db7f..4eee4cf 100644
--- a/src/java/com/android/internal/telephony/uicc/IccRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/IccRecords.java
@@ -299,7 +299,7 @@
         mTelephonyManager = (TelephonyManager) mContext.getSystemService(
                 Context.TELEPHONY_SERVICE);
 
-        mCarrierTestOverride = new CarrierTestOverride(mParentApp.getPhoneId());
+        mCarrierTestOverride = new CarrierTestOverride();
         mCi.registerForIccRefresh(this, EVENT_REFRESH, null);
 
         mParentApp.registerForReady(this, EVENT_APP_READY, null);
diff --git a/src/java/com/android/internal/telephony/uicc/IccSimPortInfo.java b/src/java/com/android/internal/telephony/uicc/IccSimPortInfo.java
deleted file mode 100644
index 9a5e10d..0000000
--- a/src/java/com/android/internal/telephony/uicc/IccSimPortInfo.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.uicc;
-
-import android.telephony.SubscriptionInfo;
-import android.text.TextUtils;
-
-import java.util.Objects;
-
-public class IccSimPortInfo {
-
-    public String mIccId;      /* iccid of the currently enabled profile */
-    public int mLogicalSlotIndex; /* logical slotId of the active slot */
-    public boolean mPortActive;     /* port state in the slot */
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj) {
-            return true;
-        }
-        if (obj == null || getClass() != obj.getClass()) {
-            return false;
-        }
-
-        IccSimPortInfo that = (IccSimPortInfo) obj;
-        return (mPortActive == that.mPortActive)
-                && (mLogicalSlotIndex == that.mLogicalSlotIndex)
-                && (TextUtils.equals(mIccId, that.mIccId));
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(mPortActive,  mLogicalSlotIndex, mIccId);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("{").append("iccid=")
-                .append(SubscriptionInfo.givePrintableIccid(mIccId)).append(",")
-                .append("logicalSlotIndex=").append(mLogicalSlotIndex).append(",")
-                .append("portActive=").append(mPortActive)
-                .append("}");
-        return sb.toString();
-    }
-}
\ No newline at end of file
diff --git a/src/java/com/android/internal/telephony/uicc/IccSlotPortMapping.java b/src/java/com/android/internal/telephony/uicc/IccSlotPortMapping.java
deleted file mode 100644
index da837e3..0000000
--- a/src/java/com/android/internal/telephony/uicc/IccSlotPortMapping.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.uicc;
-
-import android.telephony.TelephonyManager;
-
-public class IccSlotPortMapping {
-
-    public int mPhysicalSlotIndex = UiccController.INVALID_SLOT_ID;
-    public int mPortIndex = TelephonyManager.DEFAULT_PORT_INDEX;
-
-    public IccSlotPortMapping() {
-    }
-
-    @Override
-    public String toString() {
-        return "{" + "physicalSlotIndex=" + mPhysicalSlotIndex + ", portIndex=" + mPortIndex + "}";
-    }
-}
diff --git a/src/java/com/android/internal/telephony/uicc/IccSlotStatus.java b/src/java/com/android/internal/telephony/uicc/IccSlotStatus.java
index 96a3a33..43f525e 100644
--- a/src/java/com/android/internal/telephony/uicc/IccSlotStatus.java
+++ b/src/java/com/android/internal/telephony/uicc/IccSlotStatus.java
@@ -16,26 +16,26 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.telephony.SubscriptionInfo;
 import android.text.TextUtils;
 
-import com.android.internal.telephony.util.TelephonyUtils;
-import com.android.telephony.Rlog;
-
-import java.util.Arrays;
-
 /**
  * This class represents the status of the physical UICC slots.
  */
 public class IccSlotStatus {
-    /* Added state active to check slotState in old HAL case.*/
-    public static final int STATE_ACTIVE = 1;
+
+    public enum SlotState {
+        SLOTSTATE_INACTIVE,
+        SLOTSTATE_ACTIVE;
+    }
 
     public IccCardStatus.CardState  cardState;
+    public SlotState  slotState;
+    public int        logicalSlotIndex;
     public String     atr;
+    public String     iccid;
     public String     eid;
 
-    public IccSimPortInfo[] mSimPortInfos;
-
     /**
      * Set the cardState according to the input state.
      */
@@ -58,20 +58,32 @@
         }
     }
 
+    /**
+     * Set the slotState according to the input state.
+     */
+    public void setSlotState(int state) {
+        switch(state) {
+            case 0:
+                slotState = SlotState.SLOTSTATE_INACTIVE;
+                break;
+            case 1:
+                slotState = SlotState.SLOTSTATE_ACTIVE;
+                break;
+            default:
+                throw new RuntimeException("Unrecognized RIL_SlotState: " + state);
+        }
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
         sb.append("IccSlotStatus {").append(cardState).append(",")
-                .append("atr=").append(atr).append(",")
-                .append("eid=").append(Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, eid)).append(",");
-        if (mSimPortInfos != null) {
-            sb.append("num_ports=").append(mSimPortInfos.length);
-            for (int i =0; i < mSimPortInfos.length; i++) {
-                sb.append(", IccSimPortInfo-" + i + mSimPortInfos[i]);
-            }
-        } else {
-            sb.append("num_ports=null");
-        }
+                .append(slotState).append(",")
+                .append("logicalSlotIndex=").append(logicalSlotIndex).append(",")
+                .append("atr=").append(atr).append(",iccid=")
+                .append(SubscriptionInfo.givePrintableIccid(iccid)).append(",")
+                .append("eid=").append(eid);
+
         sb.append("}");
         return sb.toString();
     }
@@ -87,9 +99,11 @@
 
         IccSlotStatus that = (IccSlotStatus) obj;
         return (cardState == that.cardState)
+                && (slotState == that.slotState)
+                && (logicalSlotIndex == that.logicalSlotIndex)
                 && (TextUtils.equals(atr, that.atr))
-                && (TextUtils.equals(eid, that.eid))
-                && Arrays.equals(mSimPortInfos, that.mSimPortInfos);
+                && (TextUtils.equals(iccid, that.iccid))
+                && (TextUtils.equals(eid, that.eid));
     }
 
 }
diff --git a/src/java/com/android/internal/telephony/uicc/PinStorage.java b/src/java/com/android/internal/telephony/uicc/PinStorage.java
index 1154e0f..2885124 100644
--- a/src/java/com/android/internal/telephony/uicc/PinStorage.java
+++ b/src/java/com/android/internal/telephony/uicc/PinStorage.java
@@ -47,7 +47,6 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.PersistableBundle;
-import android.os.WorkSource;
 import android.provider.Settings;
 import android.security.keystore.KeyGenParameterSpec;
 import android.telephony.CarrierConfigManager;
@@ -271,7 +270,7 @@
                 savePinInformation(slotId, null);
                 TelephonyStatsLog.write(PIN_STORAGE_EVENT,
                         PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_SKIPPED_SIM_CARD_MISMATCH,
-                        /* number_of_pins= */ 1, /* package_name= */ "");
+                        /* number_of_pins= */ 1);
             } else if (storedPin.status == PinStatus.VERIFICATION_READY) {
                 logd("getPin[%d] - Found PIN ready for verification", slotId);
                 // Move the state to AVAILABLE, so that it cannot be retrieved again.
@@ -292,7 +291,7 @@
      * @return The result of the reboot preparation.
      */
     @TelephonyManager.PrepareUnattendedRebootResult
-    public synchronized int prepareUnattendedReboot(WorkSource workSource) {
+    public synchronized int prepareUnattendedReboot() {
         // Unattended reboot should never occur before the device is unlocked.
         if (mIsDeviceLocked) {
             loge("prepareUnattendedReboot - Device is locked");
@@ -342,18 +341,14 @@
         }
 
         // Generate metrics
-        String callingPackage = workSource == null || workSource.size() == 0
-                                    ? "" : workSource.getPackageName(0);
         if (result == TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS) {
             logd("prepareUnattendedReboot - Stored %d PINs", storedCount);
             TelephonyStatsLog.write(PIN_STORAGE_EVENT,
-                    PIN_STORAGE_EVENT__EVENT__PIN_STORED_FOR_VERIFICATION, storedCount,
-                    callingPackage);
+                    PIN_STORAGE_EVENT__EVENT__PIN_STORED_FOR_VERIFICATION, storedCount);
         } else if (result == TelephonyManager.PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED) {
             logd("prepareUnattendedReboot - Required %d PINs after reboot", notAvailableCount);
             TelephonyStatsLog.write(PIN_STORAGE_EVENT,
-                    PIN_STORAGE_EVENT__EVENT__PIN_REQUIRED_AFTER_REBOOT, notAvailableCount,
-                    callingPackage);
+                    PIN_STORAGE_EVENT__EVENT__PIN_REQUIRED_AFTER_REBOOT, notAvailableCount);
         }
 
         // Save number of PINs to generate metrics after reboot
@@ -460,7 +455,7 @@
         if (prevCachedPinCount > verificationReadyCount) {
             TelephonyStatsLog.write(PIN_STORAGE_EVENT,
                     PIN_STORAGE_EVENT__EVENT__PIN_COUNT_NOT_MATCHING_AFTER_REBOOT,
-                    prevCachedPinCount - verificationReadyCount, /* package_name= */ "");
+                    prevCachedPinCount - verificationReadyCount);
         }
     }
 
@@ -512,8 +507,7 @@
         // Write metrics about number of discarded PINs
         if (discardedPin > 0) {
             TelephonyStatsLog.write(PIN_STORAGE_EVENT,
-                    PIN_STORAGE_EVENT__EVENT__CACHED_PIN_DISCARDED, discardedPin,
-                    /* package_name= */ "");
+                    PIN_STORAGE_EVENT__EVENT__CACHED_PIN_DISCARDED, discardedPin);
         }
     }
 
@@ -582,7 +576,7 @@
                 success
                     ? PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_SUCCESS
                     : PIN_STORAGE_EVENT__EVENT__PIN_VERIFICATION_FAILURE,
-                /* number_of_pins= */ 1, /* package_name= */ "");
+                /* number_of_pins= */ 1);
     }
 
     @Override
@@ -1158,7 +1152,7 @@
         } catch (Exception e) {
             loge("Encrypt exception", e);
             TelephonyStatsLog.write(PIN_STORAGE_EVENT,
-                    PIN_STORAGE_EVENT__EVENT__PIN_ENCRYPTION_ERROR, 1, /* package_name= */ "");
+                    PIN_STORAGE_EVENT__EVENT__PIN_ENCRYPTION_ERROR, 1);
         }
         return new byte[0];
     }
@@ -1183,7 +1177,7 @@
         } catch (Exception e) {
             loge("Decrypt exception", e);
             TelephonyStatsLog.write(PIN_STORAGE_EVENT,
-                    PIN_STORAGE_EVENT__EVENT__PIN_DECRYPTION_ERROR, 1, /* package_name= */ "");
+                    PIN_STORAGE_EVENT__EVENT__PIN_DECRYPTION_ERROR, 1);
         }
         return new byte[0];
     }
diff --git a/src/java/com/android/internal/telephony/uicc/SIMRecords.java b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
index 9958bfb..aed860b 100644
--- a/src/java/com/android/internal/telephony/uicc/SIMRecords.java
+++ b/src/java/com/android/internal/telephony/uicc/SIMRecords.java
@@ -308,9 +308,7 @@
     @Override
     public void setMsisdnNumber(String alphaTag, String number,
             Message onComplete) {
-        if (mDestroyed.get()) {
-            return;
-        }
+
         // If the SIM card is locked by PIN, we will set EF_MSISDN fail.
         // In that case, msisdn and msisdnTag should not be update.
         mNewMsisdn = number;
@@ -414,9 +412,6 @@
     @Override
     public void
     setVoiceMessageWaiting(int line, int countWaiting) {
-        if (mDestroyed.get()) {
-            return;
-        }
         if (line != 1) {
             // only profile 1 is supported
             return;
@@ -520,9 +515,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     @Override
     public void setVoiceCallForwardingFlag(int line, boolean enable, String dialNumber) {
-        if (mDestroyed.get()) {
-            return;
-        }
+
         if (line != 1) return; // only line 1 is supported
 
         mCallForwardingStatus = enable ? CALL_FORWARDING_STATUS_ENABLED :
@@ -1521,9 +1514,6 @@
     //***** Private methods
 
     private void setVoiceMailByCountry (String spn) {
-        if (mDestroyed.get()) {
-            return;
-        }
         if (mVmConfig.containsCarrier(spn)) {
             mIsVoiceMailFixed = true;
             mVoiceMailNum = mVmConfig.getVoiceMailNumber(spn);
diff --git a/src/java/com/android/internal/telephony/uicc/SimPhonebookRecord.java b/src/java/com/android/internal/telephony/uicc/SimPhonebookRecord.java
index ef5c4d7..c6c7d6d 100644
--- a/src/java/com/android/internal/telephony/uicc/SimPhonebookRecord.java
+++ b/src/java/com/android/internal/telephony/uicc/SimPhonebookRecord.java
@@ -17,13 +17,14 @@
 package com.android.internal.telephony.uicc;
 
 import android.hardware.radio.V1_6.PhonebookRecordInfo;
-import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
+import android.telephony.PhoneNumberUtils;
+import android.telephony.Rlog;
 
 import com.android.internal.telephony.util.ArrayUtils;
 
-import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 /**
  * Represents a Phonebook entry from the SIM.
@@ -32,49 +33,50 @@
  */
 public class SimPhonebookRecord {
     // Instance variables
-    private int mRecordId = 0;
+    private int mRecordIndex = 0;
     private String mAlphaTag;
     private String mNumber;
     private String[] mEmails;
     private String[] mAdditionalNumbers;
 
     // Instance methods
-    public SimPhonebookRecord (int recordId, String alphaTag, String number,
+    public SimPhonebookRecord (int recordIndex, String alphaTag, String number,
                String[] emails, String[] adNumbers) {
-        mRecordId = recordId;
+        mRecordIndex = recordIndex;
         mAlphaTag = alphaTag;
         mNumber = convertRecordFormatToNumber(number);
         mEmails = emails;
         if (adNumbers != null) {
             mAdditionalNumbers = new String[adNumbers.length];
             for (int i = 0 ; i < adNumbers.length; i++) {
-                mAdditionalNumbers[i] = convertRecordFormatToNumber(adNumbers[i]);
+                mAdditionalNumbers[i] =
+                        convertRecordFormatToNumber(adNumbers[i]);
             }
         }
     }
 
     public SimPhonebookRecord(PhonebookRecordInfo recInfo) {
-        if (recInfo != null) {
-            mRecordId = recInfo.recordId;
-            mAlphaTag = recInfo.name;
-            mNumber = recInfo.number;
-            mEmails = recInfo.emails == null ? null
-                    : recInfo.emails.toArray(new String[recInfo.emails.size()]);
-            mAdditionalNumbers = recInfo.additionalNumbers == null ? null
-                    : recInfo.additionalNumbers.toArray(
-                            new String[recInfo.additionalNumbers.size()]);
-        }
+        mRecordIndex = recInfo.recordId;
+        mAlphaTag = recInfo.name;
+        mNumber = recInfo.number;
+        mEmails = recInfo.emails == null ? null
+                : recInfo.emails.toArray(new String[recInfo.emails.size()]);
+        mAdditionalNumbers = recInfo.additionalNumbers == null ? null
+                : recInfo.additionalNumbers.toArray(
+                        new String[recInfo.additionalNumbers.size()]);
     }
 
     public SimPhonebookRecord() {}
 
     public PhonebookRecordInfo toPhonebookRecordInfo() {
         PhonebookRecordInfo pbRecordInfo = new PhonebookRecordInfo();
-        pbRecordInfo.recordId = mRecordId;
+        pbRecordInfo.recordId = mRecordIndex;
         pbRecordInfo.name = convertNullToEmptyString(mAlphaTag);
         pbRecordInfo.number = convertNullToEmptyString(convertNumberToRecordFormat(mNumber));
         if (mEmails != null) {
-            pbRecordInfo.emails = new ArrayList<>(Arrays.asList(mEmails));
+            for (String email : mEmails) {
+                pbRecordInfo.emails.add(email);
+            }
         }
         if (mAdditionalNumbers != null) {
             for (String addNum : mAdditionalNumbers) {
@@ -83,32 +85,8 @@
         }
         return pbRecordInfo;
     }
-
-    public android.hardware.radio.sim.PhonebookRecordInfo toPhonebookRecordInfoAidl() {
-        android.hardware.radio.sim.PhonebookRecordInfo pbRecordInfo =
-                new android.hardware.radio.sim.PhonebookRecordInfo();
-        pbRecordInfo.recordId = mRecordId;
-        pbRecordInfo.name = convertNullToEmptyString(mAlphaTag);
-        pbRecordInfo.number = convertNullToEmptyString(convertNumberToRecordFormat(mNumber));
-        if (mEmails != null) {
-            pbRecordInfo.emails = mEmails;
-        } else {
-            pbRecordInfo.emails = new String[0];
-        }
-        if (mAdditionalNumbers != null) {
-            String[] additionalNumbers = new String[mAdditionalNumbers.length];
-            for (int i = 0; i < additionalNumbers.length; i++) {
-                additionalNumbers[i] = convertNumberToRecordFormat(mAdditionalNumbers[i]);
-            }
-            pbRecordInfo.additionalNumbers = additionalNumbers;
-        } else {
-            pbRecordInfo.additionalNumbers = new String[0];
-        }
-        return pbRecordInfo;
-    }
-
-    public int getRecordId() {
-        return mRecordId;
+    public int getRecordIndex() {
+        return mRecordIndex;
     }
 
     public String getAlphaTag() {
@@ -127,34 +105,27 @@
         return mAdditionalNumbers;
     }
 
-    /** Convert null to an empty String */
-    private String convertNullToEmptyString(String str) {
-        return str != null ? str : "";
+    /**
+     * convert phone number in the SIM phonebook record format to GSM pause/wild/wait character
+     */
+    private static String convertRecordFormatToNumber(String input) {
+        return input == null ? null : input.replace( 'e', PhoneNumberUtils.WAIT )
+                .replace( 'T', PhoneNumberUtils.PAUSE )
+                .replace( '?', PhoneNumberUtils.WILD );
     }
 
     /**
-     * Convert the SIM PhonebookRecordInfo number to the GSM pause/wild/wait number
-     * @param input the SIM PhonebookRecordInfo number
-     * @return The converted GSM pause/wild/wait number
+     * convert the GSM pause/wild/wait character to the phone number in the SIM pb record format
      */
-    private String convertRecordFormatToNumber(String input) {
-        return input == null ? null : input.replace('e', PhoneNumberUtils.WAIT)
-                .replace('T', PhoneNumberUtils.PAUSE)
-                .replace('?', PhoneNumberUtils.WILD);
-    }
-
-    /**
-     * Convert the GSM pause/wild/wait characters to the phone number in the SIM PhonebookRecordInfo
-     * number format
-     * @param input GSM pause/wild/wait character
-     * @return The converted PhonebookRecordInfo number
-     */
-    private String convertNumberToRecordFormat(String input) {
+    private static String convertNumberToRecordFormat(String input) {
         return input == null ? null : input.replace(PhoneNumberUtils.WAIT, 'e')
                 .replace(PhoneNumberUtils.PAUSE, 'T')
                 .replace(PhoneNumberUtils.WILD, '?');
     }
 
+    private static String convertNullToEmptyString(String string) {
+        return string != null ? string : "";
+    }
 
     public boolean isEmpty() {
         return TextUtils.isEmpty(mAlphaTag)
@@ -166,8 +137,8 @@
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append("SimPhoneBookRecord{").append("ID =")
-                .append(mRecordId).append(", name = ")
+        sb.append("SimPhoneBookRecord{").append("index =")
+                .append(mRecordIndex).append(", name = ")
                 .append(mAlphaTag == null ? "null" : mAlphaTag)
                 .append(", number = ").append(mNumber == null ? "null" : mNumber)
                 .append(", email count = ").append(mEmails == null ? 0 : mEmails.length)
@@ -180,7 +151,7 @@
     }
 
     public final static class Builder {
-        private int mRecordId = 0;
+        private int mRecordIndex = 0;
         private String mAlphaTag = null;
         private String mNumber = null;
         private String[] mEmails;
@@ -189,7 +160,7 @@
         public SimPhonebookRecord build() {
             SimPhonebookRecord record = new SimPhonebookRecord();
             record.mAlphaTag = mAlphaTag;
-            record.mRecordId = mRecordId;
+            record.mRecordIndex = mRecordIndex;
             record.mNumber = mNumber;
             if (mEmails != null) {
                 record.mEmails = mEmails;
@@ -200,8 +171,8 @@
             return record;
         }
 
-        public Builder setRecordId(int recordId) {
-            mRecordId = recordId;
+        public Builder setRecordIndex(int index) {
+            mRecordIndex = index;
             return this;
         }
 
diff --git a/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java b/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java
index e06e008..ca00112 100644
--- a/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java
+++ b/src/java/com/android/internal/telephony/uicc/SimPhonebookRecordCache.java
@@ -29,16 +29,13 @@
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.RadioInterfaceCapabilityController;
 import com.android.internal.telephony.uicc.AdnCapacity;
-import com.android.internal.telephony.uicc.IccConstants;
 
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
-import java.util.concurrent.ConcurrentSkipListMap;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Map;
 import java.util.stream.Collectors;
 
 
@@ -57,11 +54,8 @@
         value = "TelephonyManager.CAPABILITY_SIM_PHONEBOOK_IN_MODEM")
 public class SimPhonebookRecordCache extends Handler {
     // Instance Variables
-    private String LOG_TAG = "SimPhonebookRecordCache";
+    private static final String LOG_TAG = "SimPhonebookRecordCache";
     private static final boolean DBG = true;
-
-    @VisibleForTesting
-    static final boolean ENABLE_INFLATE_WITH_EMPTY_RECORDS = true;
     // Event Constants
     private static final int EVENT_PHONEBOOK_CHANGED = 1;
     private static final int EVENT_PHONEBOOK_RECORDS_RECEIVED = 2;
@@ -73,7 +67,6 @@
 
     private static final int MAX_RETRY_COUNT = 3;
     private static final int RETRY_INTERVAL = 3000; // 3S
-    private static final int INVALID_RECORD_ID = -1;
 
     // member variables
     private final CommandsInterface mCi;
@@ -83,9 +76,9 @@
     // Presenting ADN capacity, including ADN, EMAIL ANR, and so on.
     private AtomicReference<AdnCapacity> mAdnCapacity = new AtomicReference<AdnCapacity>(null);
     private Object mReadLock = new Object();
-    private final ConcurrentSkipListMap<Integer, AdnRecord> mSimPbRecords =
-            new ConcurrentSkipListMap<Integer, AdnRecord>();
-    private final List<UpdateRequest> mUpdateRequests =
+    private List<AdnRecord> mSimPbRecords =
+            Collections.synchronizedList(new ArrayList<AdnRecord>());
+    private List<UpdateRequest> mUpdateRequests =
             Collections.synchronizedList(new ArrayList<UpdateRequest>());
     // If true, clear the records in the cache and re-query from modem
     private AtomicBoolean mIsCacheInvalidated = new AtomicBoolean(false);
@@ -107,7 +100,6 @@
         mCi = ci;
         mPhoneId = phoneId;
         mContext = context;
-        LOG_TAG += "[" + phoneId + "]";
         mCi.registerForSimPhonebookChanged(this, EVENT_PHONEBOOK_CHANGED, null);
         mCi.registerForIccRefresh(this, EVENT_SIM_REFRESH, null);
         mCi.registerForSimPhonebookRecordsReceived(this, EVENT_PHONEBOOK_RECORDS_RECEIVED, null);
@@ -155,9 +147,7 @@
         synchronized (mReadLock) {
             for (Message response : mAdnLoadingWaiters){
                 if (response != null) {
-                    List<AdnRecord> result =
-                            new ArrayList<AdnRecord>(mSimPbRecords.values());
-                    AsyncResult.forMessage(response, result, null);
+                    AsyncResult.forMessage(response).result = mSimPbRecords;
                     response.sendToTarget();
                 }
             }
@@ -215,7 +205,7 @@
         synchronized (mReadLock) {
             mAdnLoadingWaiters.add(response);
             final int pendingSize = mAdnLoadingWaiters.size();
-            final boolean isCapacityInvalid = isAdnCapacityInvalid();
+            boolean isCapacityInvalid = getAdnCapacity() == null;
             if (isCapacityInvalid) {
                 getSimPhonebookCapacity();
             }
@@ -237,10 +227,6 @@
         fillCache();
     }
 
-    private boolean isAdnCapacityInvalid() {
-        return getAdnCapacity() == null || !getAdnCapacity().isSimValid();
-    }
-
     @VisibleForTesting
     public boolean isLoading() {
         return mIsRecordLoading.get();
@@ -248,14 +234,7 @@
 
     @VisibleForTesting
     public List<AdnRecord> getAdnRecords() {
-        return mSimPbRecords.values().stream().collect(Collectors.toList());
-    }
-
-    @VisibleForTesting
-    public void clear() {
-        if (!ENABLE_INFLATE_WITH_EMPTY_RECORDS) {
-            mSimPbRecords.clear();
-        }
+        return mSimPbRecords;
     }
 
     private void notifyAdnLoadingWaiters() {
@@ -270,52 +249,70 @@
             sendErrorResponse(response, "There is an invalid new Adn for update");
             return;
         }
-        boolean found = mSimPbRecords.containsKey(recordId);
+        boolean found = false;
+        int index = 0;
+        for (Iterator<AdnRecord> it = mSimPbRecords.iterator(); it.hasNext();) {
+            AdnRecord oldAdn = it.next();
+            ++index;
+            if (oldAdn.getRecId() == recordId) {
+                found = true;
+                break;
+            }
+        }
         if (!found) {
             sendErrorResponse(response, "There is an invalid old Adn for update");
             return;
         }
-        updateSimPhonebookByNewAdn(recordId, newAdn, response);
+        updateSimPhonebookByNewAdn(index, newAdn, response);
     }
 
     public void updateSimPbAdnBySearch(AdnRecord oldAdn, AdnRecord newAdn, Message response) {
+        int index = -1;
+        if ((oldAdn == null || oldAdn.isEmpty()) && !newAdn.isEmpty()) {
+            // Add contact
+            index = 0;
+        } else {
+            int count = 1;
+            // Delete or update contact
+            for (Iterator<AdnRecord> it = mSimPbRecords.iterator(); it.hasNext();) {
+                if (oldAdn.isEqual(it.next())) {
+                    index = count;
+                    break;
+                }
+                count++;
+            }
+        }
+        if (index == -1) {
+            sendErrorResponse(response, "SIM Phonebook record don't exist for " + oldAdn);
+            return;
+        }
+
         if (newAdn == null) {
             sendErrorResponse(response, "There is an invalid new Adn for update");
             return;
         }
 
-        int recordId = INVALID_RECORD_ID; // The ID isn't specified by caller
-
-        if (oldAdn != null && !oldAdn.isEmpty()) {
-            for(AdnRecord adn : mSimPbRecords.values()) {
-                if (oldAdn.isEqual(adn)) {
-                    recordId = adn.getRecId();
-                    break;
-                }
-            }
-        }
-        if (recordId == INVALID_RECORD_ID
-                && mAdnCapacity.get() != null && mAdnCapacity.get().isSimFull()) {
+        if (index == 0 && mAdnCapacity.get() != null && mAdnCapacity.get().isSimFull()) {
             sendErrorResponse(response, "SIM Phonebook record is full");
             return;
         }
 
-        updateSimPhonebookByNewAdn(recordId, newAdn, response);
+        updateSimPhonebookByNewAdn(index, newAdn, response);
     }
 
-    private void updateSimPhonebookByNewAdn(int recordId, AdnRecord newAdn, Message response) {
-        logd("update sim contact for record ID = " + recordId);
-        final int updatingRecordId = recordId == INVALID_RECORD_ID ? 0 : recordId;
+    private void updateSimPhonebookByNewAdn(int index, AdnRecord newAdn, Message response) {
+        int recordIndex = (index == 0) ? newAdn.getRecId()
+                : mSimPbRecords.get(index - 1).getRecId();
         SimPhonebookRecord updateAdn = new SimPhonebookRecord.Builder()
-                .setRecordId(updatingRecordId)
+                .setRecordIndex(recordIndex)
                 .setAlphaTag(newAdn.getAlphaTag())
                 .setNumber(newAdn.getNumber())
                 .setEmails(newAdn.getEmails())
                 .setAdditionalNumbers(newAdn.getAdditionalNumbers())
                 .build();
-        UpdateRequest updateRequest = new UpdateRequest(recordId, newAdn, updateAdn, response);
+        UpdateRequest updateRequest = new UpdateRequest(index, newAdn, updateAdn, response);
         mUpdateRequests.add(updateRequest);
-        final boolean isCapacityInvalid = isAdnCapacityInvalid();
+        boolean isCapacityInvalid = getAdnCapacity() == null;
         if (isCapacityInvalid) {
             getSimPhonebookCapacity();
         }
@@ -361,11 +358,6 @@
                 if (ar != null && ar.exception == null) {
                     AdnCapacity capacity = (AdnCapacity)ar.result;
                     handlePhonebookCapacityChanged(capacity);
-                } else {
-                    if (!isAdnCapacityInvalid()) {
-                        mAdnCapacity.set(new AdnCapacity());
-                    }
-                    invalidateSimPbCache();
                 }
                 break;
             case EVENT_PHONEBOOK_RECORDS_RECEIVED:
@@ -433,14 +425,10 @@
 
     private void handlePhonebookCapacityChanged(AdnCapacity newCapacity) {
         AdnCapacity oldCapacity = mAdnCapacity.get();
-        if (newCapacity == null) {
-            newCapacity = new AdnCapacity();
-        }
         mAdnCapacity.set(newCapacity);
         if (oldCapacity == null && newCapacity != null) {
-            inflateWithEmptyRecords(newCapacity);
-            if (!newCapacity.isSimEmpty()){
-                mIsCacheInvalidated.set(true);
+            if (newCapacity.getMaxAdnCount() > 0){
+                mSimPbRecords.clear();
                 fillCacheWithoutWaiting();
             } else {
                 notifyAdnLoadingWaiters();
@@ -448,9 +436,7 @@
             mIsInitialized.set(true); // Let's say the whole process is ready
         } else {
             // There is nothing from PB, so notify waiters directly if any
-            if (newCapacity.isSimEmpty()
-                    || !newCapacity.isSimValid()) {
-                mIsCacheInvalidated.set(false);
+            if (newCapacity != null && newCapacity.getMaxAdnCount() == 0) {
                 notifyAdnLoadingWaiters();
             } else if (!mIsUpdateDone) {
                 invalidateSimPbCache();
@@ -460,18 +446,6 @@
         }
     }
 
-    private void inflateWithEmptyRecords(AdnCapacity capacity) {
-        if (ENABLE_INFLATE_WITH_EMPTY_RECORDS) {
-            logd("inflateWithEmptyRecords");
-            if (capacity != null && mSimPbRecords.isEmpty()) {
-                for (int i = 1; i <= capacity.getMaxAdnCount(); i++) {
-                    mSimPbRecords.putIfAbsent(i,
-                            new AdnRecord(IccConstants.EF_ADN, i, null, null, null, null));
-                }
-            }
-        }
-    }
-
     private void handlePhonebookRecordReceived(ReceivedPhonebookRecords records) {
         if (records != null) {
             if (records.isOk()) {
@@ -482,7 +456,6 @@
                 populateAdnRecords(records.getPhonebookRecords());
                 mIsRecordLoading.set(false);
                 mIsInRetry.set(false);
-                mIsCacheInvalidated.set(false);
                 notifyAdnLoadingWaiters();
                 tryFireUpdatePendingList();
             } else if (records.isRetryNeeded() && !mIsInRetry.get()) {
@@ -505,20 +478,41 @@
         UpdateRequest updateRequest = (UpdateRequest)ar.userObj;
         mIsUpdateDone = true;
         if (ar.exception == null) {
-            int myRecordId = updateRequest.myRecordId;
+            int index = updateRequest.index;
             AdnRecord adn = updateRequest.adnRecord;
-            int recordId = ((int[]) (ar.result))[0];
-            logd("my record ID = " + myRecordId + " new record ID = " + recordId);
-            if (myRecordId == INVALID_RECORD_ID || myRecordId == recordId) {
-                if (!adn.isEmpty()) {
-                    addOrChangeSimPbRecord(adn, recordId);
+            int recordIndex = ((int[]) (ar.result))[0];
+
+            if (index == 0) {
+                // add contact
+                addSimPbRecord(adn, recordIndex);
+            } else if (adn.isEmpty()){
+                // delete contact
+                AdnRecord deletedRecord = mSimPbRecords.get(index - 1);
+                int adnRecordIndex = deletedRecord.getRecId();
+                logd("Record number for deleted ADN is " + adnRecordIndex);
+                if(recordIndex == adnRecordIndex) {
+                    deleteSimPbRecord(index);
                 } else {
-                    deleteSimPbRecord(recordId);
+                    e = new RuntimeException(
+                            "The index for deleted ADN record did not match");
                 }
             } else {
-                e = new RuntimeException("The record ID for update doesn't match");
+                // Change contact
+                if (mSimPbRecords.size() > index - 1) {
+                    AdnRecord oldRecord = mSimPbRecords.get(index - 1);
+                    int adnRecordIndex = oldRecord.getRecId();
+                    logd("Record number for changed ADN is " + adnRecordIndex);
+                    if(recordIndex == adnRecordIndex) {
+                        updateSimPbRecord(adn, recordIndex, index);
+                    } else {
+                        e = new RuntimeException(
+                                "The index for changed ADN record did not match");
+                    }
+                } else {
+                    e = new RuntimeException(
+                            "The index for changed ADN record is out of the border");
+                }
             }
-
         } else {
             e = new RuntimeException("Update adn record failed", ar.exception);
         }
@@ -554,15 +548,14 @@
 
     private void populateAdnRecords(List<SimPhonebookRecord> records) {
         if (records != null) {
-            Map<Integer, AdnRecord> newRecords = records.stream().map(record -> {return
-                    new AdnRecord(IccConstants.EF_ADN,
-                    record.getRecordId(),
+            List<AdnRecord> newRecords = records.stream().map(record -> {return
+                    new AdnRecord(0, // PBR or ADN
+                    record.getRecordIndex(),
                     record.getAlphaTag(),
                     record.getNumber(),
                     record.getEmails(),
-                    record.getAdditionalNumbers());})
-                    .collect(Collectors.toMap(AdnRecord::getRecId, adn -> adn));
-            mSimPbRecords.putAll(newRecords);
+                    record.getAdditionalNumbers());}).collect(Collectors.toList());
+            mSimPbRecords.addAll(newRecords);
         }
     }
 
@@ -575,38 +568,29 @@
         sendMessageDelayed(message, RETRY_INTERVAL);
     }
 
-    private void addOrChangeSimPbRecord(AdnRecord record, int recordId) {
-        logd("Record number for the added or changed ADN is " + recordId);
-        record.setRecId(recordId);
-        if (ENABLE_INFLATE_WITH_EMPTY_RECORDS) {
-            mSimPbRecords.replace(recordId, record);
-        } else {
-            mSimPbRecords.put(recordId, record);
-        }
+    private void addSimPbRecord(AdnRecord addedRecord, int recordIndex) {
+        logd("Record number for the added ADN is " + recordIndex);
+        addedRecord.setRecId(recordIndex);
+        mSimPbRecords.add(addedRecord);
     }
 
 
-    private void deleteSimPbRecord(int recordId) {
-        logd("Record number for the deleted ADN is " + recordId);
-        if (ENABLE_INFLATE_WITH_EMPTY_RECORDS) {
-            mSimPbRecords.replace(recordId,
-                    new AdnRecord(IccConstants.EF_ADN, recordId, null, null, null, null));
-        } else {
-            if (mSimPbRecords.containsKey(recordId)) {
-                mSimPbRecords.remove(recordId);
-            }
-        }
+    private void deleteSimPbRecord(int index) {
+        logd("Record number for the deleted ADN is " + index);
+        mSimPbRecords.remove(index - 1);
+    }
+
+    private void updateSimPbRecord(AdnRecord newRecord,
+            int recordIndex, int index) {
+        logd("Record number for the updated ADN is " + recordIndex);
+        newRecord.setRecId(recordIndex);
+        mSimPbRecords.set(index - 1, newRecord);
     }
 
     private void invalidateSimPbCache() {
         logd("invalidateSimPbCache");
         mIsCacheInvalidated.set(true);
-        if (ENABLE_INFLATE_WITH_EMPTY_RECORDS) {
-            mSimPbRecords.replaceAll((k, v) ->
-                    new AdnRecord(IccConstants.EF_ADN, k, null, null, null, null));
-        } else {
-            mSimPbRecords.clear();
-        }
+        mSimPbRecords.clear();
     }
 
     private void logd(String msg) {
@@ -622,14 +606,14 @@
     }
 
     private final static class UpdateRequest {
-        private int myRecordId;
+        private int index;
         private Message response;
         private AdnRecord adnRecord;
         private SimPhonebookRecord phonebookRecord;
 
-        UpdateRequest(int recordId, AdnRecord record, SimPhonebookRecord phonebookRecord,
+        UpdateRequest(int index, AdnRecord record, SimPhonebookRecord phonebookRecord,
                 Message response) {
-            this.myRecordId = recordId;
+            this.index = index;
             this.adnRecord = record;
             this.phonebookRecord = phonebookRecord;
             this.response = response;
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCard.java b/src/java/com/android/internal/telephony/uicc/UiccCard.java
index 689e4b7..a8403911 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCard.java
@@ -18,19 +18,26 @@
 
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
 import android.os.Build;
+import android.os.Handler;
+import android.os.Message;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 
 import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.TelephonyComponentFactory;
+import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
-import com.android.internal.telephony.uicc.euicc.EuiccCard;
-import com.android.internal.telephony.uicc.euicc.EuiccPort;
+import com.android.internal.telephony.uicc.IccCardStatus.PinState;
 import com.android.telephony.Rlog;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.util.HashMap;
+import java.util.List;
 
 /**
  * {@hide}
@@ -43,81 +50,55 @@
             "com.android.internal.telephony.uicc.ICC_CARD_ADDED";
 
     // The lock object is created by UiccSlot that owns this UiccCard - this is to share the lock
-    // between UiccSlot, UiccCard, EuiccCard, UiccPort, EuiccPort and UiccProfile for now.
+    // between UiccSlot, UiccCard, EuiccCard, and UiccProfile for now.
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     protected final Object mLock;
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private CardState mCardState;
+    private String mIccid;
     protected String mCardId;
-    protected boolean mIsSupportsMultipleEnabledProfiles;
+    private UiccProfile mUiccProfile;
+    @UnsupportedAppUsage
+    private Context mContext;
+    @UnsupportedAppUsage
+    private CommandsInterface mCi;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private final int mPhoneId;
 
-    protected HashMap<Integer, UiccPort> mUiccPorts = new HashMap<>();
-    private HashMap<Integer, Integer> mPhoneIdToPortIdx = new HashMap<>();
-
-    public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock,
-            boolean isSupportsMultipleEnabledProfiles) {
+    public UiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock) {
         if (DBG) log("Creating");
         mCardState = ics.mCardState;
+        mPhoneId = phoneId;
         mLock = lock;
-        mIsSupportsMultipleEnabledProfiles = isSupportsMultipleEnabledProfiles;
-        update(c, ci, ics, phoneId);
+        update(c, ci, ics);
     }
 
-    /**
-     * Dispose the card and its related UiccPort objects.
-     */
     public void dispose() {
         synchronized (mLock) {
             if (DBG) log("Disposing card");
-            for (UiccPort uiccPort : mUiccPorts.values()) {
-                if (uiccPort != null) {
-                    uiccPort.dispose();
-                }
+            if (mUiccProfile != null) {
+                mUiccProfile.dispose();
             }
-            mUiccPorts.clear();
-            mUiccPorts = null;
-            mPhoneIdToPortIdx.clear();
-            mPhoneIdToPortIdx = null;
+            mUiccProfile = null;
         }
     }
 
-    /**
-     * Dispose the port corresponding to the port index.
-     */
-    public void disposePort(int portIndex) {
-        synchronized (mLock) {
-            if (DBG) log("Disposing port for index " + portIndex);
-            UiccPort port = getUiccPort(portIndex);
-            if (port != null) {
-                mPhoneIdToPortIdx.remove(port.getPhoneId());
-                port.dispose();
-            }
-            mUiccPorts.remove(portIndex);
-        }
-    }
-
-    /**
-     * Update card. The main trigger for this is a change in the ICC Card status.
-     */
-    public void update(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId) {
+    public void update(Context c, CommandsInterface ci, IccCardStatus ics) {
         synchronized (mLock) {
             mCardState = ics.mCardState;
-            updateCardId(ics.iccid);
+            mContext = c;
+            mCi = ci;
+            mIccid = ics.iccid;
+            updateCardId();
+
             if (mCardState != CardState.CARDSTATE_ABSENT) {
-                int portIdx = ics.mSlotPortMapping.mPortIndex;
-                UiccPort port = mUiccPorts.get(portIdx);
-                if (port == null) {
-                    if (this instanceof EuiccCard) {
-                        port = new EuiccPort(c, ci, ics, phoneId, mLock, this,
-                                mIsSupportsMultipleEnabledProfiles); // eSim
-                    } else {
-                        port = new UiccPort(c, ci, ics, phoneId, mLock, this); // pSim
-                    }
-                    mUiccPorts.put(portIdx, port);
+                if (mUiccProfile == null) {
+                    mUiccProfile = TelephonyComponentFactory.getInstance()
+                            .inject(UiccProfile.class.getName()).makeUiccProfile(
+                            mContext, mCi, ics, mPhoneId, this, mLock);
                 } else {
-                    port.update(c, ci, ics, this);
+                    mUiccProfile.update(mContext, mCi, ics);
                 }
-                mPhoneIdToPortIdx.put(phoneId, portIdx);
             } else {
                 throw new RuntimeException("Card state is absent when updating!");
             }
@@ -132,24 +113,59 @@
     /**
      * Updates the ID of the SIM card.
      *
-     * <p>Whenever the {@link UiccCard#update(Context, CommandsInterface, IccCardStatus, int)}
-     * is called, this function needs to be called to update the card ID. Subclasses of
-     * {@link UiccCard} could override this function to set the {@link UiccCard#mCardId} to be
-     * something else instead of setting iccId.</p>
+     * <p>Whenever the {@link UiccCard#update(Context, CommandsInterface, IccCardStatus)} is called,
+     * this function needs to be called to update the card ID. Subclasses of {@link UiccCard}
+     * could override this function to set the {@link UiccCard#mCardId} to be something else instead
+     * of {@link UiccCard#mIccid}.</p>
      */
-    protected void updateCardId(String iccId) {
-        mCardId = iccId;
+    protected void updateCardId() {
+        mCardId = mIccid;
     }
 
+    /**
+     * Notifies handler when carrier privilege rules are loaded.
+     * @deprecated Please use
+     * {@link UiccProfile#registerForCarrierPrivilegeRulesLoaded(Handler, int, Object)} instead.
+     */
+    @Deprecated
+    public void registerForCarrierPrivilegeRulesLoaded(Handler h, int what, Object obj) {
+        synchronized (mLock) {
+            if (mUiccProfile != null) {
+                mUiccProfile.registerForCarrierPrivilegeRulesLoaded(h, what, obj);
+            } else {
+                loge("registerForCarrierPrivilegeRulesLoaded Failed!");
+            }
+        }
+    }
 
     /**
-     * Updates MEP(Multiple Enabled Profile) support flag.
-     *
-     * <p>If IccSlotStatus comes later, the number of ports reported is only known after the
-     * UiccCard creation which will impact UICC MEP capability.
+     * @deprecated Please use
+     * {@link UiccProfile#unregisterForCarrierPrivilegeRulesLoaded(Handler)} instead.
      */
-    public void updateSupportMultipleEnabledProfile(boolean supported) {
-        mIsSupportsMultipleEnabledProfiles = supported;
+    @Deprecated
+    public void unregisterForCarrierPrivilegeRulesLoaded(Handler h) {
+        synchronized (mLock) {
+            if (mUiccProfile != null) {
+                mUiccProfile.unregisterForCarrierPrivilegeRulesLoaded(h);
+            } else {
+                loge("unregisterForCarrierPrivilegeRulesLoaded Failed!");
+            }
+        }
+    }
+
+    /**
+     * @deprecated Please use {@link UiccProfile#isApplicationOnIcc(AppType)} instead.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @Deprecated
+    public boolean isApplicationOnIcc(IccCardApplicationStatus.AppType type) {
+        synchronized (mLock) {
+            if (mUiccProfile != null) {
+                return mUiccProfile.isApplicationOnIcc(type);
+            } else {
+                return false;
+            }
+        }
     }
 
     @UnsupportedAppUsage
@@ -160,43 +176,342 @@
     }
 
     /**
+     * @deprecated Please use {@link UiccProfile#getUniversalPinState()} instead.
+     */
+    @Deprecated
+    public PinState getUniversalPinState() {
+        synchronized (mLock) {
+            if (mUiccProfile != null) {
+                return mUiccProfile.getUniversalPinState();
+            } else {
+                return PinState.PINSTATE_UNKNOWN;
+            }
+        }
+    }
+
+    /**
+     * @deprecated Please use {@link UiccProfile#getApplication(int)} instead.
+     */
+    @UnsupportedAppUsage
+    @Deprecated
+    public UiccCardApplication getApplication(int family) {
+        synchronized (mLock) {
+            if (mUiccProfile != null) {
+                return mUiccProfile.getApplication(family);
+            } else {
+                return null;
+            }
+        }
+    }
+
+    /**
+     * @deprecated Please use {@link UiccProfile#getApplicationIndex(int)} instead.
+     */
+    @UnsupportedAppUsage
+    @Deprecated
+    public UiccCardApplication getApplicationIndex(int index) {
+        synchronized (mLock) {
+            if (mUiccProfile != null) {
+                return mUiccProfile.getApplicationIndex(index);
+            } else {
+                return null;
+            }
+        }
+    }
+
+    /**
+     * Returns the SIM application of the specified type.
+     *
+     * @param type ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx)
+     * @return application corresponding to type or a null if no match found
+     *
+     * @deprecated Please use {@link UiccProfile#getApplicationByType(int)} instead.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @Deprecated
+    public UiccCardApplication getApplicationByType(int type) {
+        synchronized (mLock) {
+            if (mUiccProfile != null) {
+                return mUiccProfile.getApplicationByType(type);
+            } else {
+                return null;
+            }
+        }
+    }
+
+    /**
+     * Resets the application with the input AID. Returns true if any changes were made.
+     *
+     * A null aid implies a card level reset - all applications must be reset.
+     *
+     * @deprecated Please use {@link UiccProfile#resetAppWithAid(String, boolean)} instead.
+     */
+    @Deprecated
+    public boolean resetAppWithAid(String aid, boolean reset) {
+        synchronized (mLock) {
+            if (mUiccProfile != null) {
+                return mUiccProfile.resetAppWithAid(aid, reset);
+            } else {
+                return false;
+            }
+        }
+    }
+
+    /**
+     * Exposes {@link CommandsInterface#iccOpenLogicalChannel}
+     * @deprecated Please use
+     * {@link UiccProfile#iccOpenLogicalChannel(String, int, Message)} instead.
+     */
+    @Deprecated
+    public void iccOpenLogicalChannel(String AID, int p2, Message response) {
+        if (mUiccProfile != null) {
+            mUiccProfile.iccOpenLogicalChannel(AID, p2, response);
+        } else {
+            loge("iccOpenLogicalChannel Failed!");
+        }
+    }
+
+    /**
+     * Exposes {@link CommandsInterface#iccCloseLogicalChannel}
+     * @deprecated Please use
+     * {@link UiccProfile#iccCloseLogicalChannel(int, Message)} instead.
+     */
+    @Deprecated
+    public void iccCloseLogicalChannel(int channel, Message response) {
+        if (mUiccProfile != null) {
+            mUiccProfile.iccCloseLogicalChannel(channel, response);
+        } else {
+            loge("iccCloseLogicalChannel Failed!");
+        }
+    }
+
+    /**
+     * Exposes {@link CommandsInterface#iccTransmitApduLogicalChannel}
+     * @deprecated Please use {@link
+     * UiccProfile#iccTransmitApduLogicalChannel(int, int, int, int, int, int, String, Message)}
+     * instead.
+     */
+    @Deprecated
+    public void iccTransmitApduLogicalChannel(int channel, int cla, int command,
+            int p1, int p2, int p3, String data, Message response) {
+        if (mUiccProfile != null) {
+            mUiccProfile.iccTransmitApduLogicalChannel(channel, cla, command, p1, p2, p3,
+                    data, response);
+        } else {
+            loge("iccTransmitApduLogicalChannel Failed!");
+        }
+    }
+
+    /**
+     * Exposes {@link CommandsInterface#iccTransmitApduBasicChannel}
+     * @deprecated Please use
+     * {@link UiccProfile#iccTransmitApduBasicChannel(int, int, int, int, int, String, Message)}
+     * instead.
+     */
+    @Deprecated
+    public void iccTransmitApduBasicChannel(int cla, int command,
+            int p1, int p2, int p3, String data, Message response) {
+        if (mUiccProfile != null) {
+            mUiccProfile.iccTransmitApduBasicChannel(cla, command, p1, p2, p3, data, response);
+        } else {
+            loge("iccTransmitApduBasicChannel Failed!");
+        }
+    }
+
+    /**
+     * Exposes {@link CommandsInterface#iccIO}
+     * @deprecated Please use
+     * {@link UiccProfile#iccExchangeSimIO(int, int, int, int, int, String, Message)} instead.
+     */
+    @Deprecated
+    public void iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3,
+            String pathID, Message response) {
+        if (mUiccProfile != null) {
+            mUiccProfile.iccExchangeSimIO(fileID, command, p1, p2, p3, pathID, response);
+        } else {
+            loge("iccExchangeSimIO Failed!");
+        }
+    }
+
+    /**
+     * Exposes {@link CommandsInterface#sendEnvelopeWithStatus}
+     * @deprecated Please use {@link UiccProfile#sendEnvelopeWithStatus(String, Message)} instead.
+     */
+    @Deprecated
+    public void sendEnvelopeWithStatus(String contents, Message response) {
+        if (mUiccProfile != null) {
+            mUiccProfile.sendEnvelopeWithStatus(contents, response);
+        } else {
+            loge("sendEnvelopeWithStatus Failed!");
+        }
+    }
+
+    /**
+     * Returns number of applications on this card
+     * @deprecated Please use {@link UiccProfile#getNumApplications()} instead.
+     */
+    @UnsupportedAppUsage
+    @Deprecated
+    public int getNumApplications() {
+        if (mUiccProfile != null) {
+            return mUiccProfile.getNumApplications();
+        } else {
+            return 0;
+        }
+    }
+
+    public int getPhoneId() {
+        return mPhoneId;
+    }
+
+    public UiccProfile getUiccProfile() {
+        return mUiccProfile;
+    }
+
+    /**
+     * Returns true iff carrier privileges rules are null (dont need to be loaded) or loaded.
+     * @deprecated Please use {@link UiccProfile#areCarrierPriviligeRulesLoaded()} instead.
+     */
+    @Deprecated
+    public boolean areCarrierPriviligeRulesLoaded() {
+        if (mUiccProfile != null) {
+            return mUiccProfile.areCarrierPriviligeRulesLoaded();
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns true if there are some carrier privilege rules loaded and specified.
+     * @deprecated Please use {@link UiccProfile#hasCarrierPrivilegeRules()} instead.
+     */
+    @Deprecated
+    public boolean hasCarrierPrivilegeRules() {
+        if (mUiccProfile != null) {
+            return mUiccProfile.hasCarrierPrivilegeRules();
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
+     * @deprecated Please use
+     * {@link UiccProfile#getCarrierPrivilegeStatus(Signature, String)} instead.
+     */
+    @Deprecated
+    public int getCarrierPrivilegeStatus(Signature signature, String packageName) {
+        if (mUiccProfile != null) {
+            return mUiccProfile.getCarrierPrivilegeStatus(signature, packageName);
+        } else {
+            return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
+        }
+    }
+
+    /**
+     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
+     * @deprecated Please use
+     * {@link UiccProfile#getCarrierPrivilegeStatus(PackageManager, String)} instead.
+     */
+    @Deprecated
+    public int getCarrierPrivilegeStatus(PackageManager packageManager, String packageName) {
+        if (mUiccProfile != null) {
+            return mUiccProfile.getCarrierPrivilegeStatus(packageManager, packageName);
+        } else {
+            return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
+        }
+    }
+
+    /**
+     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
+     * @deprecated Please use {@link UiccProfile#getCarrierPrivilegeStatus(PackageInfo)} instead.
+     */
+    @Deprecated
+    public int getCarrierPrivilegeStatus(PackageInfo packageInfo) {
+        if (mUiccProfile != null) {
+            return mUiccProfile.getCarrierPrivilegeStatus(packageInfo);
+        } else {
+            return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
+        }
+    }
+
+    /**
+     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatusForCurrentTransaction}.
+     * @deprecated Please use
+     * {@link UiccProfile#getCarrierPrivilegeStatusForCurrentTransaction(PackageManager)} instead.
+     */
+    @Deprecated
+    public int getCarrierPrivilegeStatusForCurrentTransaction(PackageManager packageManager) {
+        if (mUiccProfile != null) {
+            return mUiccProfile.getCarrierPrivilegeStatusForCurrentTransaction(packageManager);
+        } else {
+            return TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
+        }
+    }
+
+    /**
+     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPackageNamesForIntent}.
+     * @deprecated Please use
+     * {@link UiccProfile#getCarrierPackageNamesForIntent(PackageManager, Intent)} instead.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @Deprecated
+    public List<String> getCarrierPackageNamesForIntent(
+            PackageManager packageManager, Intent intent) {
+        if (mUiccProfile != null) {
+            return mUiccProfile.getCarrierPackageNamesForIntent(packageManager, intent);
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * @deprecated Please use {@link UiccProfile#setOperatorBrandOverride(String)} instead.
+     */
+    @Deprecated
+    public boolean setOperatorBrandOverride(String brand) {
+        if (mUiccProfile != null) {
+            return mUiccProfile.setOperatorBrandOverride(brand);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * @deprecated Please use {@link UiccProfile#getOperatorBrandOverride()} instead.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    @Deprecated
+    public String getOperatorBrandOverride() {
+        if (mUiccProfile != null) {
+            return mUiccProfile.getOperatorBrandOverride();
+        } else {
+            return null;
+        }
+    }
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public String getIccId() {
+        if (mIccid != null) {
+            return mIccid;
+        } else if (mUiccProfile != null) {
+            return mUiccProfile.getIccId();
+        } else {
+            return null;
+        }
+    }
+
+    /**
      * Returns the ID of this SIM card, it is the ICCID of the active profile on the card for a UICC
      * card or the EID of the card for an eUICC card.
      */
     public String getCardId() {
         if (!TextUtils.isEmpty(mCardId)) {
             return mCardId;
+        } else if (mUiccProfile != null) {
+            return mUiccProfile.getIccId();
         } else {
-            UiccProfile uiccProfile = mUiccPorts.get(TelephonyManager.DEFAULT_PORT_INDEX)
-                    .getUiccProfile();
-            return uiccProfile == null ? null : uiccProfile.getIccId();
-        }
-    }
-
-    /**
-     * Returns all the UiccPorts associated with the card.
-     */
-    public UiccPort[] getUiccPortList() {
-        synchronized (mLock) {
-            return mUiccPorts.values().stream().toArray(UiccPort[]::new);
-        }
-    }
-
-    /**
-     * Returns the UiccPort associated with the given phoneId
-     */
-    public UiccPort getUiccPortForPhone(int phoneId) {
-        synchronized (mLock) {
-            return mUiccPorts.get(mPhoneIdToPortIdx.get(phoneId));
-        }
-    }
-
-    /**
-     * Returns the UiccPort associated with the given port index.
-     */
-    public UiccPort getUiccPort(int portIdx) {
-        synchronized (mLock) {
-            return mUiccPorts.get(portIdx);
+            return null;
         }
     }
 
@@ -212,13 +527,13 @@
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("UiccCard:");
+        pw.println(" mCi=" + mCi);
         pw.println(" mCardState=" + mCardState);
         pw.println(" mCardId=" + mCardId);
-        pw.println(" mNumberOfPorts=" + mUiccPorts.size());
-        pw.println( "mIsSupportsMultipleEnabledProfiles=" + mIsSupportsMultipleEnabledProfiles);
+        pw.println(" mPhoneId=" + mPhoneId);
         pw.println();
-        for (UiccPort uiccPort : mUiccPorts.values()) {
-            uiccPort.dump(fd, pw, args);
+        if (mUiccProfile != null) {
+            mUiccProfile.dump(fd, pw, args);
         }
     }
 }
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java b/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
index 3839610..e876efd 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCardApplication.java
@@ -113,7 +113,7 @@
         mPersoSubState = as.perso_substate;
         mAid = as.aid;
         mAppLabel = as.app_label;
-        mPin1Replaced = as.pin1_replaced;
+        mPin1Replaced = (as.pin1_replaced != 0);
         mPin1State = as.pin1;
         mPin2State = as.pin2;
         mIgnoreApp = false;
@@ -151,7 +151,7 @@
             mPersoSubState = as.perso_substate;
             mAid = as.aid;
             mAppLabel = as.app_label;
-            mPin1Replaced = as.pin1_replaced;
+            mPin1Replaced = (as.pin1_replaced != 0);
             mPin1State = as.pin1;
             mPin2State = as.pin2;
 
diff --git a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
index 08521e6..4e7e3bd 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRules.java
@@ -16,9 +16,12 @@
 
 package com.android.internal.telephony.uicc;
 
+import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.content.pm.Signature;
 import android.os.AsyncResult;
 import android.os.Binder;
@@ -193,7 +196,7 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private Message mLoadedCallback;
     // LocalLog buffer to hold important status messages for debugging.
-    private LocalLog mStatusMessage = new LocalLog(64);
+    private LocalLog mStatusMessage = new LocalLog(100);
     private int mChannelId; // Channel Id for communicating with UICC.
     private int mRetryCount;  // Number of retries for open logical channel.
     private boolean mCheckedRules = false;  // Flag that used to mark whether get rules from ARA-D.
@@ -390,6 +393,54 @@
     }
 
     /**
+     * Returns the package name of the carrier app that should handle the input intent.
+     *
+     * @param packageManager PackageManager for getting receivers.
+     * @param intent Intent that will be sent.
+     * @return list of carrier app package names that can handle the intent.
+     *         Returns null if there is an error and an empty list if there
+     *         are no matching packages.
+     */
+    public List<String> getCarrierPackageNamesForIntent(
+            PackageManager packageManager, Intent intent) {
+        List<String> packages = new ArrayList<String>();
+        List<ResolveInfo> receivers = new ArrayList<ResolveInfo>();
+        receivers.addAll(packageManager.queryBroadcastReceivers(intent, 0));
+        receivers.addAll(packageManager.queryIntentContentProviders(intent, 0));
+        receivers.addAll(packageManager.queryIntentActivities(intent, 0));
+        receivers.addAll(packageManager.queryIntentServices(intent, 0));
+
+        for (ResolveInfo resolveInfo : receivers) {
+            String packageName = getPackageName(resolveInfo);
+            if (packageName == null) {
+                continue;
+            }
+
+            int status = getCarrierPrivilegeStatus(packageManager, packageName);
+            if (status == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+                packages.add(packageName);
+            } else if (status != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) {
+                // Any status apart from HAS_ACCESS and NO_ACCESS is considered an error.
+                return null;
+            }
+        }
+
+        return packages;
+    }
+
+    @Nullable
+    private String getPackageName(ResolveInfo resolveInfo) {
+        if (resolveInfo.activityInfo != null) {
+            return resolveInfo.activityInfo.packageName;
+        } else if (resolveInfo.serviceInfo != null) {
+            return resolveInfo.serviceInfo.packageName;
+        } else if (resolveInfo.providerInfo != null) {
+            return resolveInfo.providerInfo.packageName;
+        }
+        return null;
+    }
+
+    /**
      * The following three situations could be due to logical channels temporarily unavailable, so
      * we retry up to MAX_RETRY times, with an interval of RETRY_INTERVAL_MS: 1. MISSING_RESOURCE,
      * 2. NO_SUCH_ELEMENT and the status code is 6985, 3. INTERNAL_ERR and the status code is 6999.
diff --git a/src/java/com/android/internal/telephony/uicc/UiccController.java b/src/java/com/android/internal/telephony/uicc/UiccController.java
index 70cfce0..fb64b6a 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccController.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccController.java
@@ -21,7 +21,6 @@
 
 import static java.util.Arrays.copyOf;
 
-import android.annotation.Nullable;
 import android.app.BroadcastOptions;
 import android.compat.annotation.UnsupportedAppUsage;
 import android.content.Context;
@@ -34,19 +33,15 @@
 import android.os.Message;
 import android.os.Registrant;
 import android.os.RegistrantList;
+import android.os.storage.StorageManager;
 import android.preference.PreferenceManager;
 import android.sysprop.TelephonyProperties;
-import android.telephony.AnomalyReporter;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.UiccCardInfo;
-import android.telephony.UiccPortInfo;
-import android.telephony.UiccSlotMapping;
-import android.telephony.data.ApnSetting;
 import android.text.TextUtils;
 import android.util.LocalLog;
-import android.util.Log;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CommandException;
@@ -65,9 +60,8 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
-import java.util.UUID;
-import java.util.stream.IntStream;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * This class is responsible for keeping all knowledge about
@@ -95,9 +89,6 @@
  *                        UiccCard
  *                            #
  *                            |
- *                        UiccPort[]
- *                            #
- *                            |
  *                       UiccProfile
  *                          #   #
  *                          |   ------------------
@@ -174,18 +165,12 @@
     // SharedPreference key for saving the known card strings (ICCIDs and EIDs) ordered by card ID
     private static final String CARD_STRINGS = "card_strings";
 
-    // SharedPreference key for saving the flag to set removable eSIM as default eUICC or not.
-    private static final String REMOVABLE_ESIM_AS_DEFAULT = "removable_esim";
-
     // Whether the device has an eUICC built in.
     private boolean mHasBuiltInEuicc = false;
 
     // Whether the device has a currently active built in eUICC
     private boolean mHasActiveBuiltInEuicc = false;
 
-    // Use removable eSIM as default eUICC. This flag will be set from phone debug hidden menu
-    private boolean mUseRemovableEsimAsDefault = false;
-
     // The physical slots which correspond to built-in eUICCs
     private final int[] mEuiccSlots;
 
@@ -212,7 +197,7 @@
     private final PinStorage mPinStorage;
 
     // LocalLog buffer to hold important SIM related events for debugging
-    private static LocalLog sLocalLog = new LocalLog(TelephonyUtils.IS_DEBUGGABLE ? 256 : 64);
+    private static LocalLog sLocalLog = new LocalLog(TelephonyUtils.IS_DEBUGGABLE ? 250 : 100);
 
     /**
      * API to make UiccController singleton if not already created.
@@ -251,7 +236,13 @@
         mRadioConfig.registerForSimSlotStatusChanged(this, EVENT_SLOT_STATUS_CHANGED, null);
         for (int i = 0; i < mCis.length; i++) {
             mCis[i].registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, i);
-            mCis[i].registerForAvailable(this, EVENT_RADIO_AVAILABLE, i);
+
+            if (!StorageManager.inCryptKeeperBounce()) {
+                mCis[i].registerForAvailable(this, EVENT_RADIO_AVAILABLE, i);
+            } else {
+                mCis[i].registerForOn(this, EVENT_RADIO_ON, i);
+            }
+
             mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, i);
             mCis[i].registerForIccRefresh(this, EVENT_SIM_REFRESH, i);
         }
@@ -268,22 +259,21 @@
                 this, EVENT_MULTI_SIM_CONFIG_CHANGED, null);
 
         mPinStorage = new PinStorage(mContext);
-        if (!TelephonyUtils.IS_USER) {
-            mUseRemovableEsimAsDefault = PreferenceManager.getDefaultSharedPreferences(mContext)
-                    .getBoolean(REMOVABLE_ESIM_AS_DEFAULT, false);
-        }
     }
 
     /**
-     * Given the slot index and port index, return the phone ID, or -1 if no phone is associated
-     * with the given slot and port.
+     * Given the slot index, return the phone ID, or -1 if no phone is associated with the given
+     * slot.
      * @param slotId the slot index to check
-     * @param portIndex unique index referring to a port belonging to the SIM slot
      * @return the associated phone ID or -1
      */
-    public int getPhoneIdFromSlotPortIndex(int slotId, int portIndex) {
-        UiccSlot slot = getUiccSlot(slotId);
-        return slot == null ? UiccSlot.INVALID_PHONE_ID : slot.getPhoneIdFromPortIndex(portIndex);
+    public int getPhoneIdFromSlotId(int slotId) {
+        for (int i = 0; i < mPhoneIdToSlotId.length; i++) {
+            if (mPhoneIdToSlotId[i] == slotId) {
+                return i;
+            }
+        }
+        return -1;
     }
 
     /**
@@ -317,36 +307,6 @@
     }
 
     /**
-     * Return the UiccPort associated with the given phoneId or null if no phoneId is associated.
-     * @param phoneId the phoneId to check
-     */
-    public UiccPort getUiccPort(int phoneId) {
-        synchronized (mLock) {
-            return getUiccPortForPhone(phoneId);
-        }
-    }
-
-    /**
-     * API to get UiccPort corresponding to given physical slot index and port index
-     * @param slotId index of physical slot on the device
-     * @param portIdx index of port on the card
-     * @return UiccPort object corresponding to given physical slot index and port index;
-     * null if port does not exist.
-     */
-    public UiccPort getUiccPortForSlot(int slotId, int portIdx) {
-        synchronized (mLock) {
-            UiccSlot slot = getUiccSlot(slotId);
-            if (slot != null) {
-                UiccCard uiccCard = slot.getUiccCard();
-                if (uiccCard != null) {
-                    return uiccCard.getUiccPort(portIdx);
-                }
-            }
-            return null;
-        }
-    }
-
-    /**
      * API to get UiccCard corresponding to given physical slot index
      * @param slotId index of physical slot on the device
      * @return UiccCard object corresponting to given physical slot index; null if card is
@@ -380,27 +340,6 @@
     }
 
     /**
-     * API to get UiccPort corresponding to given phone id
-     * @return UiccPort object corresponding to given phone id; null if there is no card present for
-     * the phone id
-     */
-    @Nullable
-    public UiccPort getUiccPortForPhone(int phoneId) {
-        synchronized (mLock) {
-            if (isValidPhoneIndex(phoneId)) {
-                UiccSlot uiccSlot = getUiccSlotForPhone(phoneId);
-                if (uiccSlot != null) {
-                    UiccCard uiccCard = uiccSlot.getUiccCard();
-                    if (uiccCard != null) {
-                        return uiccCard.getUiccPortForPhone(phoneId);
-                    }
-                }
-            }
-            return null;
-        }
-    }
-
-    /**
      * API to get UiccProfile corresponding to given phone id
      * @return UiccProfile object corresponding to given phone id; null if there is no card/profile
      * present for the phone id
@@ -408,8 +347,8 @@
     public UiccProfile getUiccProfileForPhone(int phoneId) {
         synchronized (mLock) {
             if (isValidPhoneIndex(phoneId)) {
-                UiccPort uiccPort = getUiccPortForPhone(phoneId);
-                return uiccPort != null ? uiccPort.getUiccProfile() : null;
+                UiccCard uiccCard = getUiccCardForPhone(phoneId);
+                return uiccCard != null ? uiccCard.getUiccProfile() : null;
             }
             return null;
         }
@@ -425,11 +364,10 @@
         }
     }
 
-    /** Map logicalSlot to physicalSlot, portIndex and activate the physicalSlot with portIndex if
-     *  it is inactive. */
-    public void switchSlots(List<UiccSlotMapping> slotMapping, Message response) {
-        logWithLocalLog("switchSlots: " + slotMapping);
-        mRadioConfig.setSimSlotsMapping(slotMapping, response);
+    /** Map logicalSlot to physicalSlot, and activate the physicalSlot if it is inactive. */
+    public void switchSlots(int[] physicalSlots, Message response) {
+        logWithLocalLog("switchSlots: " + Arrays.toString(physicalSlots));
+        mRadioConfig.setSimSlotsMapping(physicalSlots, response);
     }
 
     /**
@@ -480,12 +418,8 @@
             }
             // if a match is not found, do a lookup based on ICCID
             for (int idx = 0; idx < mUiccSlots.length; idx++) {
-                UiccSlot slot = mUiccSlots[idx];
-                if (slot != null) {
-                    if (IntStream.of(slot.getPortList()).anyMatch(porIdx -> cardId.equals(
-                            slot.getIccId(porIdx)))) {
-                        return idx;
-                    }
+                if (mUiccSlots[idx] != null && cardId.equals(mUiccSlots[idx].getIccId())) {
+                    return idx;
                 }
             }
             return INVALID_SLOT_ID;
@@ -586,10 +520,9 @@
                     break;
                 case EVENT_RADIO_UNAVAILABLE:
                     if (DBG) log("EVENT_RADIO_UNAVAILABLE, dispose card");
-                    sLastSlotStatus = null;
                     UiccSlot uiccSlot = getUiccSlotForPhone(phoneId);
                     if (uiccSlot != null) {
-                        uiccSlot.onRadioStateUnavailable(phoneId);
+                        uiccSlot.onRadioStateUnavailable();
                     }
                     mIccChangedRegistrants.notifyRegistrants(new AsyncResult(null, phoneId, null));
                     break;
@@ -629,7 +562,18 @@
         for (int i = prevActiveModemCount; i < newActiveModemCount; i++) {
             mPhoneIdToSlotId[i] = INVALID_SLOT_ID;
             mCis[i].registerForIccStatusChanged(this, EVENT_ICC_STATUS_CHANGED, i);
+
+            /*
+             * To support FDE (deprecated), additional check is needed:
+             *
+             * if (!StorageManager.inCryptKeeperBounce()) {
+             *     mCis[i].registerForAvailable(this, EVENT_RADIO_AVAILABLE, i);
+             * } else {
+             *     mCis[i].registerForOn(this, EVENT_RADIO_ON, i);
+             * }
+             */
             mCis[i].registerForAvailable(this, EVENT_RADIO_AVAILABLE, i);
+
             mCis[i].registerForNotAvailable(this, EVENT_RADIO_UNAVAILABLE, i);
             mCis[i].registerForIccRefresh(this, EVENT_SIM_REFRESH, i);
         }
@@ -677,9 +621,9 @@
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     public UiccCardApplication getUiccCardApplication(int phoneId, int family) {
         synchronized (mLock) {
-            UiccPort uiccPort = getUiccPortForPhone(phoneId);
-            if (uiccPort != null) {
-                return uiccPort.getApplication(family);
+            UiccCard uiccCard = getUiccCardForPhone(phoneId);
+            if (uiccCard != null) {
+                return uiccCard.getApplication(family);
             }
             return null;
         }
@@ -707,7 +651,7 @@
         }
     }
 
-    static void updateInternalIccStateForInactivePort(
+    static void updateInternalIccStateForInactiveSlot(
             Context context, int prevActivePhoneId, String iccId) {
         if (SubscriptionManager.isValidPhoneId(prevActivePhoneId)) {
             // Mark SIM state as ABSENT on previously phoneId.
@@ -719,7 +663,7 @@
 
         SubscriptionInfoUpdater subInfoUpdator = PhoneFactory.getSubscriptionInfoUpdater();
         if (subInfoUpdator != null) {
-            subInfoUpdator.updateInternalIccStateForInactivePort(prevActivePhoneId, iccId);
+            subInfoUpdator.updateInternalIccStateForInactiveSlot(prevActivePhoneId, iccId);
         } else {
             Rlog.e(LOG_TAG, "subInfoUpdate is null.");
         }
@@ -762,13 +706,13 @@
 
         logWithLocalLog("onGetIccCardStatusDone: phoneId " + index + " IccCardStatus: " + status);
 
-        int slotId = status.mSlotPortMapping.mPhysicalSlotIndex;
+        int slotId = status.physicalSlotIndex;
         if (VDBG) log("onGetIccCardStatusDone: phoneId " + index + " physicalSlotIndex " + slotId);
         if (slotId == INVALID_SLOT_ID) {
             slotId = index;
         }
 
-        if (!mCis[0].supportsEid()) {
+        if (eidIsNotSupported(status)) {
             // we will never get EID from the HAL, so set mDefaultEuiccCardId to UNSUPPORTED_CARD_ID
             if (DBG) log("eid is not supported");
             mDefaultEuiccCardId = UNSUPPORTED_CARD_ID;
@@ -799,7 +743,7 @@
         if (isEuicc) {
             cardString = ((EuiccCard) card).getEid();
         } else {
-            cardString = card.getUiccPort(status.mSlotPortMapping.mPortIndex).getIccId();
+            cardString = card.getIccId();
         }
 
         if (cardString != null) {
@@ -820,8 +764,7 @@
                 if (mDefaultEuiccCardId == UNINITIALIZED_CARD_ID
                         || mDefaultEuiccCardId == TEMPORARILY_UNSUPPORTED_CARD_ID) {
                     mDefaultEuiccCardId = convertToPublicCardId(cardString);
-                    logWithLocalLog("IccCardStatus eid="
-                            + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, cardString) + " slot=" + slotId
+                    logWithLocalLog("IccCardStatus eid=" + cardString + " slot=" + slotId
                             + " mDefaultEuiccCardId=" + mDefaultEuiccCardId);
                 }
             }
@@ -832,6 +775,15 @@
     }
 
     /**
+     * Returns true if EID is not supproted.
+     */
+    private boolean eidIsNotSupported(IccCardStatus status) {
+        // if card status does not contain slot ID, we know we are on HAL < 1.2, so EID will never
+        // be available
+        return status.physicalSlotIndex == INVALID_SLOT_ID;
+    }
+
+    /**
      * Add a cardString to mCardStrings. If this is an ICCID, trailing Fs will be automatically
      * stripped.
      */
@@ -901,45 +853,30 @@
             boolean isEuicc = slot.isEuicc();
             String eid = null;
             UiccCard card = slot.getUiccCard();
+            String iccid = null;
             int cardId = UNINITIALIZED_CARD_ID;
             boolean isRemovable = slot.isRemovable();
 
             // first we try to populate UiccCardInfo using the UiccCard, but if it doesn't exist
             // (e.g. the slot is for an inactive eUICC) then we try using the UiccSlot.
             if (card != null) {
+                iccid = card.getIccId();
                 if (isEuicc) {
                     eid = ((EuiccCard) card).getEid();
                     cardId = convertToPublicCardId(eid);
                 } else {
-                    // In case of non Euicc, use default port index to get the IccId.
-                    UiccPort port = card.getUiccPort(TelephonyManager.DEFAULT_PORT_INDEX);
-                    if (port == null) {
-                        AnomalyReporter.reportAnomaly(
-                                UUID.fromString("92885ba7-98bb-490a-ba19-987b1c8b2055"),
-                                "UiccController: Found UiccPort Null object.");
-                    }
-                    String iccId = (port != null) ? port.getIccId() : null;
-                    cardId = convertToPublicCardId(iccId);
+                    // leave eid null if the UICC is not embedded
+                    cardId = convertToPublicCardId(iccid);
                 }
             } else {
-                // This iccid is used for non Euicc only, so use default port index
-                String iccId = slot.getIccId(TelephonyManager.DEFAULT_PORT_INDEX);
+                iccid = slot.getIccId();
                 // Fill in the fields we can
-                if (!isEuicc && !TextUtils.isEmpty(iccId)) {
-                    cardId = convertToPublicCardId(iccId);
+                if (!isEuicc && !TextUtils.isEmpty(iccid)) {
+                    cardId = convertToPublicCardId(iccid);
                 }
             }
-
-            List<UiccPortInfo> portInfos = new ArrayList<>();
-            int[] portIndexes = slot.getPortList();
-            for (int portIdx : portIndexes) {
-                String iccId = IccUtils.stripTrailingFs(slot.getIccId(portIdx));
-                portInfos.add(new UiccPortInfo(iccId, portIdx,
-                        slot.getPhoneIdFromPortIndex(portIdx), slot.isPortActive(portIdx)));
-            }
-            UiccCardInfo info = new UiccCardInfo(
-                    isEuicc, cardId, eid, slotIndex, isRemovable,
-                    slot.isMultipleEnabledProfileSupported(), portInfos);
+            UiccCardInfo info = new UiccCardInfo(isEuicc, cardId, eid,
+                    IccUtils.stripTrailingFs(iccid), slotIndex, isRemovable);
             infos.add(info);
         }
         return infos;
@@ -952,21 +889,6 @@
         if (mDefaultEuiccCardId == TEMPORARILY_UNSUPPORTED_CARD_ID) {
             return UNSUPPORTED_CARD_ID;
         }
-        // To support removable eSIM to pass GCT/PTCRB test in DSDS mode, we should make sure all
-        // the download/activation requests are by default route to the removable eSIM slot.
-        // To satisfy above condition, we should return removable eSIM cardId as default.
-        if (mUseRemovableEsimAsDefault && !TelephonyUtils.IS_USER) {
-            for (UiccSlot slot : mUiccSlots) {
-                if (slot != null && slot.isRemovable() && slot.isEuicc() && slot.isActive()) {
-                    int cardId = convertToPublicCardId(slot.getEid());
-                    Rlog.d(LOG_TAG,
-                            "getCardIdForDefaultEuicc: Removable eSIM is default, cardId: "
-                                    + cardId);
-                    return cardId;
-                }
-            }
-            Rlog.d(LOG_TAG, "getCardIdForDefaultEuicc: No removable eSIM slot is found");
-        }
         return mDefaultEuiccCardId;
     }
 
@@ -1030,7 +952,7 @@
 
         sLastSlotStatus = status;
 
-        int numActivePorts = 0;
+        int numActiveSlots = 0;
         boolean isDefaultEuiccCardIdSet = false;
         boolean anyEuiccIsActive = false;
         mHasActiveBuiltInEuicc = false;
@@ -1044,7 +966,19 @@
 
         for (int i = 0; i < numSlots; i++) {
             IccSlotStatus iss = status.get(i);
-            boolean isActive = hasActivePort(iss.mSimPortInfos);
+            boolean isActive = (iss.slotState == IccSlotStatus.SlotState.SLOTSTATE_ACTIVE);
+            if (isActive) {
+                numActiveSlots++;
+
+                // Correctness check: logicalSlotIndex should be valid for an active slot
+                if (!isValidPhoneIndex(iss.logicalSlotIndex)) {
+                    Rlog.e(LOG_TAG, "Skipping slot " + i + " as phone " + iss.logicalSlotIndex
+                               + " is not available to communicate with this slot");
+                } else {
+                    mPhoneIdToSlotId[iss.logicalSlotIndex] = i;
+                }
+            }
+
             if (mUiccSlots[i] == null) {
                 if (VDBG) {
                     log("Creating mUiccSlot[" + i + "]; mUiccSlots.length = " + mUiccSlots.length);
@@ -1052,25 +986,13 @@
                 mUiccSlots[i] = new UiccSlot(mContext, isActive);
             }
 
-            if (isActive) { // check isActive flag so that we don't have to iterate through all
-                for (int j = 0; j < iss.mSimPortInfos.length; j++) {
-                    if (iss.mSimPortInfos[j].mPortActive) {
-                        int logicalSlotIndex = iss.mSimPortInfos[j].mLogicalSlotIndex;
-                        // Correctness check: logicalSlotIndex should be valid for an active slot
-                        if (!isValidPhoneIndex(logicalSlotIndex)) {
-                            Rlog.e(LOG_TAG, "Skipping slot " + i + " portIndex " + j + " as phone "
-                                    + logicalSlotIndex
-                                    + " is not available to communicate with this slot");
-                        } else {
-                            mPhoneIdToSlotId[logicalSlotIndex] = i;
-                        }
-                        numActivePorts++;
-                    }
-                }
+            if (!isValidPhoneIndex(iss.logicalSlotIndex)) {
+                mUiccSlots[i].update(null, iss, i /* slotIndex */);
+            } else {
+                mUiccSlots[i].update(isActive ? mCis[iss.logicalSlotIndex] : null, iss,
+                        i /* slotIndex */);
             }
 
-            mUiccSlots[i].update(mCis, iss, i);
-
             if (mUiccSlots[i].isEuicc()) {
                 if (isActive) {
                     anyEuiccIsActive = true;
@@ -1092,9 +1014,8 @@
                 if (!mUiccSlots[i].isRemovable() && !isDefaultEuiccCardIdSet) {
                     isDefaultEuiccCardIdSet = true;
                     mDefaultEuiccCardId = convertToPublicCardId(eid);
-                    logWithLocalLog("Using eid=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, eid)
-                            + " in slot=" + i + " to set mDefaultEuiccCardId="
-                            + mDefaultEuiccCardId);
+                    logWithLocalLog("Using eid=" + eid + " in slot=" + i
+                            + " to set mDefaultEuiccCardId=" + mDefaultEuiccCardId);
                 }
             }
         }
@@ -1111,10 +1032,8 @@
                     if (!TextUtils.isEmpty(eid)) {
                         isDefaultEuiccCardIdSet = true;
                         mDefaultEuiccCardId = convertToPublicCardId(eid);
-                        logWithLocalLog("Using eid="
-                                + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, eid)
-                                + " from removable eUICC in slot=" + i
-                                + " to set mDefaultEuiccCardId=" + mDefaultEuiccCardId);
+                        logWithLocalLog("Using eid=" + eid + " from removable eUICC in slot="
+                                + i + " to set mDefaultEuiccCardId=" + mDefaultEuiccCardId);
                         break;
                     }
                 }
@@ -1160,12 +1079,21 @@
 
         if (VDBG) logPhoneIdToSlotIdMapping();
 
-        // Correctness check: number of active ports should be valid
-        if (numActivePorts != mPhoneIdToSlotId.length) {
-            Rlog.e(LOG_TAG, "Number of active ports " + numActivePorts
+        // Correctness check: number of active slots should be valid
+        if (numActiveSlots != mPhoneIdToSlotId.length) {
+            Rlog.e(LOG_TAG, "Number of active slots " + numActiveSlots
                        + " does not match the number of Phones" + mPhoneIdToSlotId.length);
         }
 
+        // Correctness check: slotIds should be unique in mPhoneIdToSlotId
+        Set<Integer> slotIds = new HashSet<>();
+        for (int slotId : mPhoneIdToSlotId) {
+            if (slotIds.contains(slotId)) {
+                throw new RuntimeException("slotId " + slotId + " mapped to multiple phoneIds");
+            }
+            slotIds.add(slotId);
+        }
+
         // broadcast slot status changed
         final BroadcastOptions options = BroadcastOptions.makeBasic();
         options.setBackgroundActivityStartsAllowed(true);
@@ -1175,15 +1103,6 @@
                 options.toBundle());
     }
 
-    private boolean hasActivePort(IccSimPortInfo[] simPortInfos) {
-        for (IccSimPortInfo simPortInfo : simPortInfos) {
-            if (simPortInfo.mPortActive) {
-                return true;
-            }
-        }
-        return false;
-    }
-
     /**
      * Check if slot status has changed from the last received one
      */
@@ -1232,22 +1151,16 @@
             return;
         }
 
-        UiccPort uiccPort = getUiccPortForPhone(index);
-        if (uiccPort == null) {
-            Rlog.e(LOG_TAG, "onSimRefresh: refresh on null port : " + index);
-            return;
-        }
-
         boolean changed = false;
         switch(resp.refreshResult) {
             // Reset the required apps when we know about the refresh so that
             // anyone interested does not get stale state.
             case IccRefreshResponse.REFRESH_RESULT_RESET:
-                changed = uiccPort.resetAppWithAid(resp.aid, true /* reset */);
+                changed = uiccCard.resetAppWithAid(resp.aid, true /* reset */);
                 break;
             case IccRefreshResponse.REFRESH_RESULT_INIT:
                 // don't dispose CatService on SIM REFRESH of type INIT
-                changed = uiccPort.resetAppWithAid(resp.aid, false /* initialize */);
+                changed = uiccCard.resetAppWithAid(resp.aid, false /* initialize */);
                 break;
             default:
                 return;
@@ -1292,17 +1205,14 @@
                 || mDefaultEuiccCardId == TEMPORARILY_UNSUPPORTED_CARD_ID) {
             if (!mUiccSlots[slotId].isRemovable()) {
                 mDefaultEuiccCardId = convertToPublicCardId(eid);
-                logWithLocalLog("onEidReady: eid="
-                        + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, eid)
-                        + " slot=" + slotId + " mDefaultEuiccCardId=" + mDefaultEuiccCardId);
+                logWithLocalLog("onEidReady: eid=" + eid + " slot=" + slotId
+                        + " mDefaultEuiccCardId=" + mDefaultEuiccCardId);
             } else if (!mHasActiveBuiltInEuicc) {
                 // we only set a removable eUICC to the default if there are no active non-removable
                 // eUICCs
                 mDefaultEuiccCardId = convertToPublicCardId(eid);
-                logWithLocalLog("onEidReady: eid="
-                        + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, eid)
-                        + " from removable eUICC in slot=" + slotId + " mDefaultEuiccCardId="
-                        + mDefaultEuiccCardId);
+                logWithLocalLog("onEidReady: eid=" + eid + " from removable eUICC in slot=" + slotId
+                        + " mDefaultEuiccCardId=" + mDefaultEuiccCardId);
             }
         }
         card.unregisterForEidReady(this);
@@ -1355,105 +1265,6 @@
         return false;
     }
 
-    private static boolean iccidMatches(String mvnoData, String iccId) {
-        String[] mvnoIccidList = mvnoData.split(",");
-        for (String mvnoIccid : mvnoIccidList) {
-            if (iccId.startsWith(mvnoIccid)) {
-                Log.d(LOG_TAG, "mvno icc id match found");
-                return true;
-            }
-        }
-        return false;
-    }
-
-    private static boolean imsiMatches(String imsiDB, String imsiSIM) {
-        // Note: imsiDB value has digit number or 'x' character for separating USIM information
-        // for MVNO operator. And then digit number is matched at same order and 'x' character
-        // could replace by any digit number.
-        // ex) if imsiDB inserted '310260x10xxxxxx' for GG Operator,
-        //     that means first 6 digits, 8th and 9th digit
-        //     should be set in USIM for GG Operator.
-        int len = imsiDB.length();
-
-        if (len <= 0) return false;
-        if (len > imsiSIM.length()) return false;
-
-        for (int idx = 0; idx < len; idx++) {
-            char c = imsiDB.charAt(idx);
-            if ((c == 'x') || (c == 'X') || (c == imsiSIM.charAt(idx))) {
-                continue;
-            } else {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Check if MVNO type and data match IccRecords.
-     *
-     * @param slotIndex SIM slot index.
-     * @param mvnoType the MVNO type
-     * @param mvnoMatchData the MVNO match data
-     * @return {@code true} if MVNO type and data match IccRecords, {@code false} otherwise.
-     */
-    public boolean mvnoMatches(int slotIndex, int mvnoType, String mvnoMatchData) {
-        IccRecords iccRecords = getIccRecords(slotIndex, UiccController.APP_FAM_3GPP);
-        if (iccRecords == null) {
-            Log.d(LOG_TAG, "isMvnoMatched# IccRecords is null");
-            return false;
-        }
-        if (mvnoType == ApnSetting.MVNO_TYPE_SPN) {
-            String spn = iccRecords.getServiceProviderNameWithBrandOverride();
-            if ((spn != null) && spn.equalsIgnoreCase(mvnoMatchData)) {
-                return true;
-            }
-        } else if (mvnoType == ApnSetting.MVNO_TYPE_IMSI) {
-            String imsiSIM = iccRecords.getIMSI();
-            if ((imsiSIM != null) && imsiMatches(mvnoMatchData, imsiSIM)) {
-                return true;
-            }
-        } else if (mvnoType == ApnSetting.MVNO_TYPE_GID) {
-            String gid1 = iccRecords.getGid1();
-            int mvno_match_data_length = mvnoMatchData.length();
-            if ((gid1 != null) && (gid1.length() >= mvno_match_data_length)
-                    && gid1.substring(0, mvno_match_data_length).equalsIgnoreCase(mvnoMatchData)) {
-                return true;
-            }
-        } else if (mvnoType == ApnSetting.MVNO_TYPE_ICCID) {
-            String iccId = iccRecords.getIccId();
-            if ((iccId != null) && iccidMatches(mvnoMatchData, iccId)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    /**
-     * Set removable eSIM as default.
-     * This API is added for test purpose to set removable eSIM as default eUICC.
-     * @param isDefault Flag to set removable eSIM as default or not.
-     */
-    public void setRemovableEsimAsDefaultEuicc(boolean isDefault) {
-        mUseRemovableEsimAsDefault = isDefault;
-        SharedPreferences.Editor editor =
-                PreferenceManager.getDefaultSharedPreferences(mContext).edit();
-        editor.putBoolean(REMOVABLE_ESIM_AS_DEFAULT, isDefault);
-        editor.apply();
-        Rlog.d(LOG_TAG, "setRemovableEsimAsDefaultEuicc isDefault: " + isDefault);
-    }
-
-    /**
-     * Returns whether the removable eSIM is default eUICC or not.
-     * This API is added for test purpose to check whether removable eSIM is default eUICC or not.
-     */
-    public boolean isRemovableEsimDefaultEuicc() {
-        Rlog.d(LOG_TAG, "mUseRemovableEsimAsDefault: " + mUseRemovableEsimAsDefault);
-        return mUseRemovableEsimAsDefault;
-    }
-
-
     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
     private void log(String string) {
         Rlog.d(LOG_TAG, string);
@@ -1491,7 +1302,6 @@
         pw.println(" mCardStrings=" + mCardStrings);
         pw.println(" mDefaultEuiccCardId=" + mDefaultEuiccCardId);
         pw.println(" mPhoneIdToSlotId=" + Arrays.toString(mPhoneIdToSlotId));
-        pw.println(" mUseRemovableEsimAsDefault=" + mUseRemovableEsimAsDefault);
         pw.println(" mUiccSlots: size=" + mUiccSlots.length);
         for (int i = 0; i < mUiccSlots.length; i++) {
             if (mUiccSlots[i] == null) {
diff --git a/src/java/com/android/internal/telephony/uicc/UiccPort.java b/src/java/com/android/internal/telephony/uicc/UiccPort.java
deleted file mode 100644
index 0152dda..0000000
--- a/src/java/com/android/internal/telephony/uicc/UiccPort.java
+++ /dev/null
@@ -1,461 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.uicc;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.Message;
-import android.os.RemoteException;
-import android.telephony.SubscriptionInfo;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.IccLogicalChannelRequest;
-import com.android.internal.telephony.TelephonyComponentFactory;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.List;
-
-public class UiccPort {
-    protected static final String LOG_TAG = "UiccPort";
-    protected static final boolean DBG = true;
-
-    // The lock object is created by UiccSlot that owns this UiccCard - this is to share the lock
-    // between UiccSlot, UiccCard, EuiccCard, UiccPort, EuiccPort and UiccProfile for now.
-    protected final Object mLock;
-
-    private String mIccid;
-    protected String mCardId;
-    private Context mContext;
-    private CommandsInterface mCi;
-    private UiccProfile mUiccProfile;
-
-    private final int mPhoneId;
-    private int mPortIdx;
-    private int mPhysicalSlotIndex;
-
-    // The list of the opened logical channel record. The channels will be closed by us when
-    // detecting client died without closing them in advance.
-    @GuardedBy("mOpenChannelRecords")
-    private final List<OpenLogicalChannelRecord> mOpenChannelRecords = new ArrayList<>();
-
-    public UiccPort(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock,
-            UiccCard uiccCard) {
-        if (DBG) log("Creating");
-        mPhoneId = phoneId;
-        mLock = lock;
-        update(c, ci, ics, uiccCard);
-    }
-
-    /**
-     * Update port. The main trigger for this is a change in the ICC Card status.
-     */
-    public void update(Context c, CommandsInterface ci, IccCardStatus ics, UiccCard uiccCard) {
-        synchronized (mLock) {
-            mContext = c;
-            mCi = ci;
-            mIccid = ics.iccid;
-            mPortIdx = ics.mSlotPortMapping.mPortIndex;
-            mPhysicalSlotIndex = ics.mSlotPortMapping.mPhysicalSlotIndex;
-            if (mUiccProfile == null) {
-                mUiccProfile = TelephonyComponentFactory.getInstance()
-                        .inject(UiccProfile.class.getName()).makeUiccProfile(
-                                mContext, mCi, ics, mPhoneId, uiccCard, mLock);
-            } else {
-                mUiccProfile.update(mContext, mCi, ics);
-            }
-        }
-    }
-
-    /**
-     * Dispose the port and its related Uicc profiles.
-     */
-    public void dispose() {
-        synchronized (mLock) {
-            if (DBG) log("Disposing Port");
-            if (mUiccProfile != null) {
-                mUiccProfile.dispose();
-            }
-            mUiccProfile = null;
-        }
-    }
-
-    @Override
-    protected void finalize() {
-        if (DBG) log("UiccPort finalized");
-    }
-
-    /**
-     * @deprecated Please use
-     * {@link UiccProfile#isApplicationOnIcc(IccCardApplicationStatus.AppType)} instead.
-     */
-    @Deprecated
-    public boolean isApplicationOnIcc(IccCardApplicationStatus.AppType type) {
-        synchronized (mLock) {
-            if (mUiccProfile != null) {
-                return mUiccProfile.isApplicationOnIcc(type);
-            } else {
-                return false;
-            }
-        }
-    }
-
-    /**
-     * @deprecated Please use {@link UiccProfile#getUniversalPinState()} instead.
-     */
-    @Deprecated
-    public IccCardStatus.PinState getUniversalPinState() {
-        synchronized (mLock) {
-            if (mUiccProfile != null) {
-                return mUiccProfile.getUniversalPinState();
-            } else {
-                return IccCardStatus.PinState.PINSTATE_UNKNOWN;
-            }
-        }
-    }
-
-    /**
-     * @deprecated Please use {@link UiccProfile#getApplication(int)} instead.
-     */
-    @Deprecated
-    public UiccCardApplication getApplication(int family) {
-        synchronized (mLock) {
-            if (mUiccProfile != null) {
-                return mUiccProfile.getApplication(family);
-            } else {
-                return null;
-            }
-        }
-    }
-
-    /**
-     * @deprecated Please use {@link UiccProfile#getApplicationIndex(int)} instead.
-     */
-    @Deprecated
-    public UiccCardApplication getApplicationIndex(int index) {
-        synchronized (mLock) {
-            if (mUiccProfile != null) {
-                return mUiccProfile.getApplicationIndex(index);
-            } else {
-                return null;
-            }
-        }
-    }
-
-    /**
-     * Returns the SIM application of the specified type.
-     *
-     * @param type ICC application type
-     * (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx)
-     * @return application corresponding to type or a null if no match found
-     *
-     * @deprecated Please use {@link UiccProfile#getApplicationByType(int)} instead.
-     */
-    @Deprecated
-    public UiccCardApplication getApplicationByType(int type) {
-        synchronized (mLock) {
-            if (mUiccProfile != null) {
-                return mUiccProfile.getApplicationByType(type);
-            } else {
-                return null;
-            }
-        }
-    }
-
-    /**
-     * Resets the application with the input AID. Returns true if any changes were made.
-     *
-     * A null aid implies a card level reset - all applications must be reset.
-     *
-     * @deprecated Please use {@link UiccProfile#resetAppWithAid(String, boolean)} instead.
-     */
-    @Deprecated
-    public boolean resetAppWithAid(String aid, boolean reset) {
-        synchronized (mLock) {
-            if (mUiccProfile != null) {
-                return mUiccProfile.resetAppWithAid(aid, reset);
-            } else {
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Exposes {@link CommandsInterface#iccOpenLogicalChannel}
-     * @deprecated Please use
-     * {@link UiccProfile#iccOpenLogicalChannel(String, int, Message)} instead.
-     */
-    @Deprecated
-    public void iccOpenLogicalChannel(String AID, int p2, Message response) {
-        if (mUiccProfile != null) {
-            mUiccProfile.iccOpenLogicalChannel(AID, p2, response);
-        } else {
-            loge("iccOpenLogicalChannel Failed!");
-        }
-    }
-
-    /**
-     * Exposes {@link CommandsInterface#iccCloseLogicalChannel}
-     * @deprecated Please use
-     * {@link UiccProfile#iccCloseLogicalChannel(int, Message)} instead.
-     */
-    @Deprecated
-    public void iccCloseLogicalChannel(int channel, Message response) {
-        if (mUiccProfile != null) {
-            mUiccProfile.iccCloseLogicalChannel(channel, response);
-        } else {
-            loge("iccCloseLogicalChannel Failed!");
-        }
-    }
-
-    /**
-     * Exposes {@link CommandsInterface#iccTransmitApduLogicalChannel}
-     * @deprecated Please use {@link
-     * UiccProfile#iccTransmitApduLogicalChannel(int, int, int, int, int, int, String, Message)}
-     * instead.
-     */
-    @Deprecated
-    public void iccTransmitApduLogicalChannel(int channel, int cla, int command,
-            int p1, int p2, int p3, String data, Message response) {
-        if (mUiccProfile != null) {
-            mUiccProfile.iccTransmitApduLogicalChannel(channel, cla, command, p1, p2, p3,
-                    data, response);
-        } else {
-            loge("iccTransmitApduLogicalChannel Failed!");
-        }
-    }
-
-    /**
-     * Exposes {@link CommandsInterface#iccTransmitApduBasicChannel}
-     * @deprecated Please use
-     * {@link UiccProfile#iccTransmitApduBasicChannel(int, int, int, int, int, String, Message)}
-     * instead.
-     */
-    @Deprecated
-    public void iccTransmitApduBasicChannel(int cla, int command,
-            int p1, int p2, int p3, String data, Message response) {
-        if (mUiccProfile != null) {
-            mUiccProfile.iccTransmitApduBasicChannel(cla, command, p1, p2, p3, data, response);
-        } else {
-            loge("iccTransmitApduBasicChannel Failed!");
-        }
-    }
-
-    /**
-     * Exposes {@link CommandsInterface#iccIO}
-     * @deprecated Please use
-     * {@link UiccProfile#iccExchangeSimIO(int, int, int, int, int, String, Message)} instead.
-     */
-    @Deprecated
-    public void iccExchangeSimIO(int fileID, int command, int p1, int p2, int p3,
-            String pathID, Message response) {
-        if (mUiccProfile != null) {
-            mUiccProfile.iccExchangeSimIO(fileID, command, p1, p2, p3, pathID, response);
-        } else {
-            loge("iccExchangeSimIO Failed!");
-        }
-    }
-
-    /**
-     * Exposes {@link CommandsInterface#sendEnvelopeWithStatus}
-     * @deprecated Please use {@link UiccProfile#sendEnvelopeWithStatus(String, Message)} instead.
-     */
-    @Deprecated
-    public void sendEnvelopeWithStatus(String contents, Message response) {
-        if (mUiccProfile != null) {
-            mUiccProfile.sendEnvelopeWithStatus(contents, response);
-        } else {
-            loge("sendEnvelopeWithStatus Failed!");
-        }
-    }
-
-    /**
-     * Returns number of applications on this card
-     * @deprecated Please use {@link UiccProfile#getNumApplications()} instead.
-     */
-    @Deprecated
-    public int getNumApplications() {
-        if (mUiccProfile != null) {
-            return mUiccProfile.getNumApplications();
-        } else {
-            return 0;
-        }
-    }
-
-    public int getPhoneId() {
-        return mPhoneId;
-    }
-
-    public int getPortIdx() {
-        return mPortIdx;
-    }
-
-    public UiccProfile getUiccProfile() {
-        return mUiccProfile;
-    }
-
-    /**
-     * @deprecated Please use {@link UiccProfile#setOperatorBrandOverride(String)} instead.
-     */
-    @Deprecated
-    public boolean setOperatorBrandOverride(String brand) {
-        if (mUiccProfile != null) {
-            return mUiccProfile.setOperatorBrandOverride(brand);
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * @deprecated Please use {@link UiccProfile#getOperatorBrandOverride()} instead.
-     */
-    @Deprecated
-    public String getOperatorBrandOverride() {
-        if (mUiccProfile != null) {
-            return mUiccProfile.getOperatorBrandOverride();
-        } else {
-            return null;
-        }
-    }
-
-    /**
-     * Return the IccId corresponding to the port.
-     */
-    public String getIccId() {
-        if (mIccid != null) {
-            return mIccid;
-        } else if (mUiccProfile != null) {
-            return mUiccProfile.getIccId();
-        } else {
-            return null;
-        }
-    }
-
-    private void log(String msg) {
-        Rlog.d(LOG_TAG, msg);
-    }
-
-    private void loge(String msg) {
-        Rlog.e(LOG_TAG, msg);
-    }
-
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        pw.println("UiccPort:");
-        pw.println(" this=" + this);
-        pw.println(" mPortIdx=" + mPortIdx);
-        pw.println(" mCi=" + mCi);
-        pw.println(" mIccid=" + SubscriptionInfo.givePrintableIccid(mIccid));
-        pw.println(" mPhoneId=" + mPhoneId);
-        pw.println(" mPhysicalSlotIndex=" + mPhysicalSlotIndex);
-        synchronized (mOpenChannelRecords) {
-            pw.println(" mOpenChannelRecords=" + mOpenChannelRecords);
-        }
-        pw.println();
-        if (mUiccProfile != null) {
-            mUiccProfile.dump(fd, pw, args);
-        }
-    }
-
-    /**
-     * Informed that a logical channel has been successfully opened.
-     *
-     * @param request the original request to open the channel, with channel id attached.
-     * @hide
-     */
-    public void onLogicalChannelOpened(@NonNull IccLogicalChannelRequest request) {
-        OpenLogicalChannelRecord record = new OpenLogicalChannelRecord(request);
-        try {
-            request.binder.linkToDeath(record, /*flags=*/ 0);
-            addOpenLogicalChannelRecord(record);
-            if (DBG) log("onLogicalChannelOpened: monitoring client " + record);
-        } catch (RemoteException | NullPointerException ex) {
-            loge("IccOpenLogicChannel client has died, clean up manually");
-            record.binderDied();
-        }
-    }
-
-    /**
-     * Informed that a logical channel has been successfully closed.
-     *
-     * @param channelId the channel id of the logical channel that was just closed.
-     * @hide
-     */
-    public void onLogicalChannelClosed(int channelId) {
-        OpenLogicalChannelRecord record = getOpenLogicalChannelRecord(channelId);
-        if (record != null && record.mRequest != null && record.mRequest.binder != null) {
-            if (DBG) log("onLogicalChannelClosed: stop monitoring client " + record);
-            record.mRequest.binder.unlinkToDeath(record, /*flags=*/ 0);
-            removeOpenLogicalChannelRecord(record);
-            record.mRequest.binder = null;
-        }
-    }
-
-    /** Get the OpenLogicalChannelRecord matching the channel id. */
-    @VisibleForTesting
-    public OpenLogicalChannelRecord getOpenLogicalChannelRecord(int channelId) {
-        synchronized (mOpenChannelRecords) {
-            for (OpenLogicalChannelRecord channelRecord : mOpenChannelRecords) {
-                if (channelRecord.mRequest != null
-                        && channelRecord.mRequest.channel == channelId) {
-                    return channelRecord;
-                }
-            }
-        }
-        return null;
-    }
-
-    private void addOpenLogicalChannelRecord(OpenLogicalChannelRecord record) {
-        synchronized (mOpenChannelRecords) {
-            mOpenChannelRecords.add(record);
-        }
-    }
-
-    private void removeOpenLogicalChannelRecord(OpenLogicalChannelRecord record) {
-        synchronized (mOpenChannelRecords) {
-            mOpenChannelRecords.remove(record);
-        }
-    }
-
-    /** Record to keep open logical channel info. */
-    @VisibleForTesting
-    public class OpenLogicalChannelRecord implements IBinder.DeathRecipient {
-        IccLogicalChannelRequest mRequest;
-
-        OpenLogicalChannelRecord(IccLogicalChannelRequest request) {
-            this.mRequest = request;
-        }
-
-        @Override
-        public void binderDied() {
-            loge("IccOpenLogicalChannelRecord: client died, close channel in record " + this);
-            iccCloseLogicalChannel(mRequest.channel, /* response= */ null);
-            onLogicalChannelClosed(mRequest.channel);
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder("OpenLogicalChannelRecord {");
-            sb.append(" mRequest=" + mRequest).append("}");
-            return sb.toString();
-        }
-    }
-}
diff --git a/src/java/com/android/internal/telephony/uicc/UiccProfile.java b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
index 2809895..9b60185 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccProfile.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccProfile.java
@@ -28,7 +28,9 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
+import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.Signature;
 import android.database.ContentObserver;
 import android.net.Uri;
 import android.os.AsyncResult;
@@ -53,7 +55,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CarrierAppUtils;
-import com.android.internal.telephony.CarrierPrivilegesTracker;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.IccCard;
 import com.android.internal.telephony.IccCardConstants;
@@ -110,12 +111,13 @@
             new UiccCardApplication[IccCardStatus.CARD_MAX_APPS];
     private Context mContext;
     private CommandsInterface mCi;
-    private final UiccCard mUiccCard;
+    private final UiccCard mUiccCard; //parent
     private CatService mCatService;
     private UiccCarrierPrivilegeRules mCarrierPrivilegeRules;
     private UiccCarrierPrivilegeRules mTestOverrideCarrierPrivilegeRules;
     private boolean mDisposed = false;
 
+    private RegistrantList mCarrierPrivilegeRegistrants = new RegistrantList();
     private RegistrantList mOperatorBrandOverrideRegistrants = new RegistrantList();
 
     private final int mPhoneId;
@@ -239,13 +241,6 @@
 
                 case EVENT_CARRIER_PRIVILEGES_LOADED:
                     if (VDBG) log("handleMessage: EVENT_CARRIER_PRIVILEGES_LOADED");
-                    Phone phone = PhoneFactory.getPhone(mPhoneId);
-                    if (phone != null) {
-                        CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
-                        if (cpt != null) {
-                            cpt.onUiccAccessRulesLoaded();
-                        }
-                    }
                     onCarrierPrivilegesLoadedMessage();
                     updateExternalState();
                     break;
@@ -265,13 +260,8 @@
                         logWithLocalLog("handleMessage: Error in SIM access with exception "
                                 + ar.exception);
                     }
-                    if (ar.userObj != null) {
-                        AsyncResult.forMessage((Message) ar.userObj, ar.result, ar.exception);
-                        ((Message) ar.userObj).sendToTarget();
-                    } else {
-                        loge("handleMessage: ar.userObj is null in event:" + eventName
-                                + ", failed to post status back to caller");
-                    }
+                    AsyncResult.forMessage((Message) ar.userObj, ar.result, ar.exception);
+                    ((Message) ar.userObj).sendToTarget();
                     break;
                 }
 
@@ -407,21 +397,16 @@
 
     private void setCurrentAppType(boolean isGsm) {
         if (VDBG) log("setCurrentAppType");
-        int primaryAppType;
-        int secondaryAppType;
-        if (isGsm) {
-            primaryAppType = UiccController.APP_FAM_3GPP;
-            secondaryAppType = UiccController.APP_FAM_3GPP2;
-        } else {
-            primaryAppType = UiccController.APP_FAM_3GPP2;
-            secondaryAppType = UiccController.APP_FAM_3GPP;
-        }
         synchronized (mLock) {
-            UiccCardApplication newApp = getApplication(primaryAppType);
-            if (newApp != null || getApplication(secondaryAppType) == null) {
-                mCurrentAppType = primaryAppType;
+            if (isGsm) {
+                mCurrentAppType = UiccController.APP_FAM_3GPP;
             } else {
-                mCurrentAppType = secondaryAppType;
+                UiccCardApplication newApp = getApplication(UiccController.APP_FAM_3GPP2);
+                if (newApp != null || getApplication(UiccController.APP_FAM_3GPP) == null) {
+                    mCurrentAppType = UiccController.APP_FAM_3GPP2;
+                } else {
+                    mCurrentAppType = UiccController.APP_FAM_3GPP;
+                }
             }
         }
     }
@@ -691,14 +676,14 @@
             case APPSTATE_READY:
                 checkAndUpdateIfAnyAppToBeIgnored();
                 if (areAllApplicationsReady()) {
-                    if (areAllRecordsLoaded() && areCarrierPrivilegeRulesLoaded()) {
+                    if (areAllRecordsLoaded() && areCarrierPriviligeRulesLoaded()) {
                         if (VDBG) log("updateExternalState: setting state to LOADED");
                         setExternalState(IccCardConstants.State.LOADED);
                     } else {
                         if (VDBG) {
                             log("updateExternalState: setting state to READY; records loaded "
                                     + areAllRecordsLoaded() + ", carrier privilige rules loaded "
-                                    + areCarrierPrivilegeRulesLoaded());
+                                    + areCarrierPriviligeRulesLoaded());
                         }
                         setExternalState(IccCardConstants.State.READY);
                     }
@@ -1282,6 +1267,36 @@
     }
 
     /**
+     * Registers the handler when carrier privilege rules are loaded.
+     *
+     * @param h Handler for notification message.
+     * @param what User-defined message code.
+     * @param obj User object.
+     */
+    public void registerForCarrierPrivilegeRulesLoaded(Handler h, int what, Object obj) {
+        synchronized (mLock) {
+            Registrant r = new Registrant(h, what, obj);
+
+            mCarrierPrivilegeRegistrants.add(r);
+
+            if (areCarrierPriviligeRulesLoaded()) {
+                r.notifyRegistrant();
+            }
+        }
+    }
+
+    /**
+     * Unregister for notifications when carrier privilege rules are loaded.
+     *
+     * @param h Handler to be removed from the registrant list.
+     */
+    public void unregisterForCarrierPrivilegeRulesLoaded(Handler h) {
+        synchronized (mLock) {
+            mCarrierPrivilegeRegistrants.remove(h);
+        }
+    }
+
+    /**
      * Unregister for notifications when operator brand name is overriden.
      *
      * @param h Handler to be removed from the registrant list.
@@ -1314,7 +1329,6 @@
     }
 
     private void onCarrierPrivilegesLoadedMessage() {
-        // TODO(b/211796398): clean up logic below once all carrier privilege check migration done
         // Update set of enabled carrier apps now that the privilege rules may have changed.
         ActivityManager am = mContext.getSystemService(ActivityManager.class);
         CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(),
@@ -1330,6 +1344,7 @@
         InstallCarrierAppUtils.unregisterPackageInstallReceiver(mContext);
 
         synchronized (mLock) {
+            mCarrierPrivilegeRegistrants.notifyRegistrants();
             boolean isProvisioned = isProvisioned();
             boolean isUnlocked = isUserUnlocked();
             // Only show dialog if the phone is through with Setup Wizard and is unlocked.
@@ -1640,14 +1655,72 @@
     /**
      * Returns true iff carrier privileges rules are null (dont need to be loaded) or loaded.
      */
-    @VisibleForTesting
-    public boolean areCarrierPrivilegeRulesLoaded() {
+    public boolean areCarrierPriviligeRulesLoaded() {
         UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
         return carrierPrivilegeRules == null
                 || carrierPrivilegeRules.areCarrierPriviligeRulesLoaded();
     }
 
     /**
+     * Returns true if there are some carrier privilege rules loaded and specified.
+     */
+    public boolean hasCarrierPrivilegeRules() {
+        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
+        return carrierPrivilegeRules != null && carrierPrivilegeRules.hasCarrierPrivilegeRules();
+    }
+
+    /**
+     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
+     */
+    public int getCarrierPrivilegeStatus(Signature signature, String packageName) {
+        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
+        return carrierPrivilegeRules == null
+                ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
+                carrierPrivilegeRules.getCarrierPrivilegeStatus(signature, packageName);
+    }
+
+    /**
+     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
+     */
+    public int getCarrierPrivilegeStatus(PackageManager packageManager, String packageName) {
+        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
+        return carrierPrivilegeRules == null
+                ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
+                carrierPrivilegeRules.getCarrierPrivilegeStatus(packageManager, packageName);
+    }
+
+    /**
+     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatus}.
+     */
+    public int getCarrierPrivilegeStatus(PackageInfo packageInfo) {
+        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
+        return carrierPrivilegeRules == null
+                ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
+                carrierPrivilegeRules.getCarrierPrivilegeStatus(packageInfo);
+    }
+
+    /**
+     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatusForCurrentTransaction}.
+     */
+    public int getCarrierPrivilegeStatusForCurrentTransaction(PackageManager packageManager) {
+        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
+        return carrierPrivilegeRules == null
+                ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
+                carrierPrivilegeRules.getCarrierPrivilegeStatusForCurrentTransaction(
+                        packageManager);
+    }
+
+    /**
+     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPrivilegeStatusForUid}.
+     */
+    public int getCarrierPrivilegeStatusForUid(PackageManager packageManager, int uid) {
+        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
+        return carrierPrivilegeRules == null
+                ? TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED :
+                carrierPrivilegeRules.getCarrierPrivilegeStatusForUid(packageManager, uid);
+    }
+
+    /**
      * Return a list of certs in hex string from loaded carrier privileges access rules.
      *
      * @return a list of certificate in hex string. return {@code null} if there is no certs
@@ -1674,6 +1747,17 @@
         return new ArrayList<>(carrierPrivilegeRules.getAccessRules());
     }
 
+    /**
+     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPackageNamesForIntent}.
+     */
+    public List<String> getCarrierPackageNamesForIntent(
+            PackageManager packageManager, Intent intent) {
+        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
+        return carrierPrivilegeRules == null ? null :
+                carrierPrivilegeRules.getCarrierPackageNamesForIntent(
+                        packageManager, intent);
+    }
+
     /** Returns a reference to the current {@link UiccCarrierPrivilegeRules}. */
     private UiccCarrierPrivilegeRules getCarrierPrivilegeRules() {
         synchronized (mLock) {
@@ -1806,6 +1890,10 @@
         pw.println("UiccProfile:");
         pw.println(" mCi=" + mCi);
         pw.println(" mCatService=" + mCatService);
+        for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) {
+            pw.println("  mCarrierPrivilegeRegistrants[" + i + "]="
+                    + ((Registrant) mCarrierPrivilegeRegistrants.get(i)).getHandler());
+        }
         for (int i = 0; i < mOperatorBrandOverrideRegistrants.size(); i++) {
             pw.println("  mOperatorBrandOverrideRegistrants[" + i + "]="
                     + ((Registrant) mOperatorBrandOverrideRegistrants.get(i)).getHandler());
@@ -1853,6 +1941,11 @@
                     + mTestOverrideCarrierPrivilegeRules);
             mTestOverrideCarrierPrivilegeRules.dump(fd, pw, args);
         }
+        pw.println(" mCarrierPrivilegeRegistrants: size=" + mCarrierPrivilegeRegistrants.size());
+        for (int i = 0; i < mCarrierPrivilegeRegistrants.size(); i++) {
+            pw.println("  mCarrierPrivilegeRegistrants[" + i + "]="
+                    + ((Registrant) mCarrierPrivilegeRegistrants.get(i)).getHandler());
+        }
         pw.flush();
 
         pw.println(" mNetworkLockedRegistrants: size=" + mNetworkLockedRegistrants.size());
diff --git a/src/java/com/android/internal/telephony/uicc/UiccSlot.java b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
index 9b5b315..24e5a31 100644
--- a/src/java/com/android/internal/telephony/uicc/UiccSlot.java
+++ b/src/java/com/android/internal/telephony/uicc/UiccSlot.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.telephony.uicc;
 
-import android.annotation.IntDef;
-import android.annotation.NonNull;
 import android.app.AlertDialog;
 import android.content.ActivityNotFoundException;
 import android.content.ComponentName;
@@ -29,8 +27,6 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.UserHandle;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import android.view.WindowManager;
@@ -42,17 +38,10 @@
 import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
 import com.android.internal.telephony.uicc.euicc.EuiccCard;
-import com.android.internal.telephony.util.TelephonyUtils;
 import com.android.telephony.Rlog;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
 
 /**
  * This class represents a physical slot on the device.
@@ -65,34 +54,20 @@
             "com.android.internal.telephony.uicc.ICC_CARD_ADDED";
     public static final int INVALID_PHONE_ID = -1;
 
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(
-            prefix = {"VOLTAGE_CLASS_"},
-            value = {VOLTAGE_CLASS_UNKNOWN, VOLTAGE_CLASS_A, VOLTAGE_CLASS_B, VOLTAGE_CLASS_C})
-    public @interface VoltageClass {}
-
-    public static final int VOLTAGE_CLASS_UNKNOWN = 0;
-    public static final int VOLTAGE_CLASS_A = 1;
-    public static final int VOLTAGE_CLASS_B = 2;
-    public static final int VOLTAGE_CLASS_C = 3;
-
     private final Object mLock = new Object();
     private boolean mActive;
     private boolean mStateIsUnknown = true;
     private CardState mCardState;
     private Context mContext;
+    private CommandsInterface mCi;
     private UiccCard mUiccCard;
+    private int mLastRadioState = TelephonyManager.RADIO_POWER_UNAVAILABLE;
     private boolean mIsEuicc;
-    private @VoltageClass int mMinimumVoltageClass;
+    private String mIccId;
     private String mEid;
     private AnswerToReset mAtr;
+    private int mPhoneId = INVALID_PHONE_ID;
     private boolean mIsRemovable;
-    // Map each available portIdx to phoneId
-    private HashMap<Integer, Integer> mPortIdxToPhoneId = new HashMap<>();
-    //Map each available portIdx with old radio state for state checking
-    private HashMap<Integer, Integer> mLastRadioState = new HashMap<>();
-    // Store iccId of each port.
-    private HashMap<Integer, String> mIccIds = new HashMap<>();
 
     private static final int EVENT_CARD_REMOVED = 13;
     private static final int EVENT_CARD_ADDED = 14;
@@ -110,21 +85,21 @@
     public void update(CommandsInterface ci, IccCardStatus ics, int phoneId, int slotIndex) {
         if (DBG) log("cardStatus update: " + ics.toString());
         synchronized (mLock) {
-            mPortIdxToPhoneId.put(ics.mSlotPortMapping.mPortIndex, phoneId);
             CardState oldState = mCardState;
             mCardState = ics.mCardState;
-            mIccIds.put(ics.mSlotPortMapping.mPortIndex, ics.iccid);
+            mIccId = ics.iccid;
+            mPhoneId = phoneId;
             parseAtr(ics.atr);
+            mCi = ci;
             mIsRemovable = isSlotRemovable(slotIndex);
 
-            int radioState = ci.getRadioState();
+            int radioState = mCi.getRadioState();
             if (DBG) {
                 log("update: radioState=" + radioState + " mLastRadioState=" + mLastRadioState);
             }
 
             if (absentStateUpdateNeeded(oldState)) {
-                updateCardStateAbsent(ci.getRadioState(), phoneId,
-                        ics.mSlotPortMapping.mPortIndex);
+                updateCardStateAbsent();
             // Because mUiccCard may be updated in both IccCardStatus and IccSlotStatus, we need to
             // create a new UiccCard instance in two scenarios:
             //   1. mCardState is changing from ABSENT to non ABSENT.
@@ -133,9 +108,7 @@
                     || mUiccCard == null) && mCardState != CardState.CARDSTATE_ABSENT) {
                 // No notification while we are just powering up
                 if (radioState != TelephonyManager.RADIO_POWER_UNAVAILABLE
-                        && mLastRadioState.getOrDefault(ics.mSlotPortMapping.mPortIndex,
-                        TelephonyManager.RADIO_POWER_UNAVAILABLE)
-                        != TelephonyManager.RADIO_POWER_UNAVAILABLE) {
+                        && mLastRadioState != TelephonyManager.RADIO_POWER_UNAVAILABLE) {
                     if (DBG) log("update: notify card added");
                     sendMessage(obtainMessage(EVENT_CARD_ADDED, null));
                 }
@@ -147,185 +120,81 @@
                 }
 
                 if (!mIsEuicc) {
-                    // Uicc does not support MEP, passing false by default.
-                    mUiccCard = new UiccCard(mContext, ci, ics, phoneId, mLock, false);
+                    mUiccCard = new UiccCard(mContext, mCi, ics, mPhoneId, mLock);
                 } else {
                     // The EID should be reported with the card status, but in case it's not we want
                     // to catch that here
                     if (TextUtils.isEmpty(ics.eid)) {
-                        loge("update: eid is missing. ics.eid="
-                                + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, ics.eid));
+                        loge("update: eid is missing. ics.eid=" + ics.eid);
                     }
-                    mUiccCard = new EuiccCard(mContext, ci, ics, phoneId, mLock,
-                            isMultipleEnabledProfileSupported());
+                    mUiccCard = new EuiccCard(mContext, mCi, ics, phoneId, mLock);
                 }
             } else {
                 if (mUiccCard != null) {
-                    mUiccCard.update(mContext, ci, ics, phoneId);
+                    mUiccCard.update(mContext, mCi, ics);
                 }
             }
-            mLastRadioState.put(ics.mSlotPortMapping.mPortIndex, radioState);
+            mLastRadioState = radioState;
         }
     }
 
     /**
      * Update slot based on IccSlotStatus.
      */
-    public void update(CommandsInterface[] ci, IccSlotStatus iss, int slotIndex) {
+    public void update(CommandsInterface ci, IccSlotStatus iss, int slotIndex) {
         if (DBG) log("slotStatus update: " + iss.toString());
         synchronized (mLock) {
-            IccSimPortInfo[] simPortInfos = iss.mSimPortInfos;
             CardState oldState = mCardState;
+            mCi = ci;
             parseAtr(iss.atr);
             mCardState = iss.cardState;
+            mIccId = iss.iccid;
             mEid = iss.eid;
             mIsRemovable = isSlotRemovable(slotIndex);
-
-            for (int i = 0; i < simPortInfos.length; i++) {
-                int phoneId = iss.mSimPortInfos[i].mLogicalSlotIndex;
-                mIccIds.put(i, simPortInfos[i].mIccId);
-                if (!iss.mSimPortInfos[i].mPortActive) {
-                    // TODO: (b/79432584) evaluate whether should broadcast card state change
-                    // even if it's inactive.
-                    UiccController.updateInternalIccStateForInactivePort(mContext,
-                            mPortIdxToPhoneId.getOrDefault(i, INVALID_PHONE_ID),
-                            iss.mSimPortInfos[i].mIccId);
-                    mLastRadioState.put(i, TelephonyManager.RADIO_POWER_UNAVAILABLE);
-                    if (mUiccCard != null) {
-                        // Dispose the port
-                        mUiccCard.disposePort(i);
-                    }
-                } else {
-                    if (absentStateUpdateNeeded(oldState)) {
-                        int radioState = SubscriptionManager.isValidPhoneId(phoneId) ?
-                                ci[phoneId].getRadioState() :
-                                TelephonyManager.RADIO_POWER_UNAVAILABLE;
-                        updateCardStateAbsent(radioState, phoneId, i);
-                    }
-                    // TODO: (b/79432584) Create UiccCard or EuiccCard object here.
-                    // Right now It's OK not creating it because Card status update will do it.
-                    // But we should really make them symmetric.
-                }
-            }
-            // From MEP, Card can have multiple ports. So dispose UiccCard only when all the
-            // ports are inactive.
-            if (!hasActivePort(simPortInfos)) {
+            if (iss.slotState == IccSlotStatus.SlotState.SLOTSTATE_INACTIVE) {
+                // TODO: (b/79432584) evaluate whether should broadcast card state change
+                // even if it's inactive.
+                UiccController.updateInternalIccStateForInactiveSlot(mContext, mPhoneId, mIccId);
                 if (mActive) {
                     mActive = false;
+                    mLastRadioState = TelephonyManager.RADIO_POWER_UNAVAILABLE;
+                    mPhoneId = INVALID_PHONE_ID;
                     nullifyUiccCard(true /* sim state is unknown */);
                 }
             } else {
                 mActive = true;
-            }
-            mPortIdxToPhoneId.clear();
-            for (int i = 0; i < simPortInfos.length; i++) {
-                // If port is not active, update with invalid phone id(i.e. -1)
-                mPortIdxToPhoneId.put(i, simPortInfos[i].mPortActive ?
-                        simPortInfos[i].mLogicalSlotIndex : INVALID_PHONE_ID);
-            }
-            // Since the MEP capability is related with number ports reported, thus need to
-            // update the flag after UiccCard creation.
-            if (mUiccCard != null) {
-                mUiccCard.updateSupportMultipleEnabledProfile(isMultipleEnabledProfileSupported());
-            }
-        }
-    }
-
-    private boolean hasActivePort(IccSimPortInfo[] simPortInfos) {
-        for (IccSimPortInfo simPortInfo : simPortInfos) {
-            if (simPortInfo.mPortActive) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /* Return valid phoneId if possible from the portIdx mapping*/
-    private int getAnyValidPhoneId() {
-        for (int phoneId : mPortIdxToPhoneId.values()) {
-            if (SubscriptionManager.isValidPhoneId(phoneId)) {
-                return phoneId;
-            }
-        }
-        return INVALID_PHONE_ID;
-    }
-
-    @NonNull
-    public int[] getPortList() {
-        synchronized (mLock) {
-            return mPortIdxToPhoneId.keySet().stream().mapToInt(Integer::valueOf).toArray();
-        }
-    }
-
-    /** Return whether the passing portIndex belong to this physical slot */
-    public boolean isValidPortIndex(int portIndex) {
-        return mPortIdxToPhoneId.containsKey(portIndex);
-    }
-
-    public int getPortIndexFromPhoneId(int phoneId) {
-        synchronized (mLock) {
-            for (Map.Entry<Integer, Integer> entry : mPortIdxToPhoneId.entrySet()) {
-                if (entry.getValue() == phoneId) {
-                    return entry.getKey();
+                mPhoneId = iss.logicalSlotIndex;
+                if (absentStateUpdateNeeded(oldState)) {
+                    updateCardStateAbsent();
                 }
+                // TODO: (b/79432584) Create UiccCard or EuiccCard object here.
+                // Right now It's OK not creating it because Card status update will do it.
+                // But we should really make them symmetric.
             }
-            return TelephonyManager.DEFAULT_PORT_INDEX;
         }
     }
 
-    public int getPortIndexFromIccId(String iccId) {
-        synchronized (mLock) {
-            for (Map.Entry<Integer, String> entry : mIccIds.entrySet()) {
-                if (IccUtils.compareIgnoreTrailingFs(entry.getValue(), iccId)) {
-                    return entry.getKey();
-                }
-            }
-            // If iccId is not found, return invalid port index.
-            return TelephonyManager.INVALID_PORT_INDEX;
-        }
-    }
-
-    public int getPhoneIdFromPortIndex(int portIndex) {
-        synchronized (mLock) {
-            return mPortIdxToPhoneId.getOrDefault(portIndex, INVALID_PHONE_ID);
-        }
-    }
-
-    public boolean isPortActive(int portIdx) {
-        synchronized (mLock) {
-            return SubscriptionManager.isValidPhoneId(
-                    mPortIdxToPhoneId.getOrDefault(portIdx, INVALID_PHONE_ID));
-        }
-    }
-
-    /* Returns true if multiple enabled profiles are supported */
-    public boolean isMultipleEnabledProfileSupported() {
-        // even ATR suggest UICC supports multiple enabled profiles, MEP can be disabled per
-        // carrier restrictions, so checking the real number of ports reported from modem is
-        // necessary.
-        return mPortIdxToPhoneId.size() > 1 && mAtr != null &&
-                mAtr.isMultipleEnabledProfilesSupported();
-    }
-
     private boolean absentStateUpdateNeeded(CardState oldState) {
         return (oldState != CardState.CARDSTATE_ABSENT || mUiccCard != null)
                 && mCardState == CardState.CARDSTATE_ABSENT;
     }
 
-    private void updateCardStateAbsent(int radioState, int phoneId, int portIndex) {
+    private void updateCardStateAbsent() {
+        int radioState =
+                (mCi == null) ? TelephonyManager.RADIO_POWER_UNAVAILABLE : mCi.getRadioState();
         // No notification while we are just powering up
         if (radioState != TelephonyManager.RADIO_POWER_UNAVAILABLE
-                && mLastRadioState.getOrDefault(
-                        portIndex, TelephonyManager.RADIO_POWER_UNAVAILABLE)
-                != TelephonyManager.RADIO_POWER_UNAVAILABLE) {
+                && mLastRadioState != TelephonyManager.RADIO_POWER_UNAVAILABLE) {
             if (DBG) log("update: notify card removed");
             sendMessage(obtainMessage(EVENT_CARD_REMOVED, null));
         }
-        UiccController.updateInternalIccState(mContext, IccCardConstants.State.ABSENT,
-                null, phoneId);
+
+        UiccController.updateInternalIccState(
+                mContext, IccCardConstants.State.ABSENT, null, mPhoneId);
+
         // no card present in the slot now; dispose card and make mUiccCard null
         nullifyUiccCard(false /* sim state is not unknown */);
-        mLastRadioState.put(portIndex, TelephonyManager.RADIO_POWER_UNAVAILABLE);
+        mLastRadioState = radioState;
     }
 
     // whenever we set mUiccCard to null, we lose the ability to differentiate between absent and
@@ -367,74 +236,42 @@
     }
 
     private void checkIsEuiccSupported() {
-        if (mAtr == null) {
+        if (mAtr != null && mAtr.isEuiccSupported()) {
+            mIsEuicc = true;
+        } else {
             mIsEuicc = false;
-            return;
         }
-        mIsEuicc = mAtr.isEuiccSupported();
-        log(" checkIsEuiccSupported : " + mIsEuicc);
-    }
-
-    private void checkMinimumVoltageClass() {
-        mMinimumVoltageClass = VOLTAGE_CLASS_UNKNOWN;
-        if (mAtr == null) {
-            return;
-        }
-        // Supported voltage classes are stored in the 5 least significant bits of the TA byte for
-        // global interface.
-        List<AnswerToReset.InterfaceByte> interfaceBytes = mAtr.getInterfaceBytes();
-        for (int i = 0; i < interfaceBytes.size() - 1; i++) {
-            if (interfaceBytes.get(i).getTD() != null
-                    && (interfaceBytes.get(i).getTD() & AnswerToReset.T_MASK)
-                            == AnswerToReset.T_VALUE_FOR_GLOBAL_INTERFACE
-                    && interfaceBytes.get(i + 1).getTA() != null) {
-                byte ta = interfaceBytes.get(i + 1).getTA();
-                if ((ta & 0x01) != 0) {
-                    mMinimumVoltageClass = VOLTAGE_CLASS_A;
-                }
-                if ((ta & 0x02) != 0) {
-                    mMinimumVoltageClass = VOLTAGE_CLASS_B;
-                }
-                if ((ta & 0x04) != 0) {
-                    mMinimumVoltageClass = VOLTAGE_CLASS_C;
-                }
-                return;
-            }
-        }
-        // Use default value - only class A
-        mMinimumVoltageClass = VOLTAGE_CLASS_A;
     }
 
     private void parseAtr(String atr) {
         mAtr = AnswerToReset.parseAtr(atr);
         checkIsEuiccSupported();
-        checkMinimumVoltageClass();
     }
 
     public boolean isEuicc() {
         return mIsEuicc;
     }
 
-    @VoltageClass
-    public int getMinimumVoltageClass() {
-        return mMinimumVoltageClass;
-    }
-
     public boolean isActive() {
         return mActive;
     }
 
+    public int getPhoneId() {
+        return mPhoneId;
+    }
+
     public boolean isRemovable() {
         return mIsRemovable;
     }
 
-    /**
-     *  Returns the iccId specific to the port index.
-     *  Always use {@link com.android.internal.telephony.uicc.UiccPort#getIccId} to get the iccId.
-     *  Use this API to get the iccId of the inactive port only.
-     */
-    public String getIccId(int portIdx) {
-        return mIccIds.get(portIdx);
+    public String getIccId() {
+        if (mIccId != null) {
+            return mIccId;
+        } else if (mUiccCard != null) {
+            return mUiccCard.getIccId();
+        } else {
+            return null;
+        }
     }
 
     public String getEid() {
@@ -459,8 +296,8 @@
             log("onIccSwap: isHotSwapSupported is true, don't prompt for rebooting");
             return;
         }
-        // As this check is for shutdown status check, use any phoneId
-        Phone phone = PhoneFactory.getPhone(getAnyValidPhoneId());
+
+        Phone phone = PhoneFactory.getPhone(mPhoneId);
         if (phone != null && phone.isShuttingDown()) {
             log("onIccSwap: already doing shutdown, no need to prompt");
             return;
@@ -474,11 +311,11 @@
     private void promptForRestart(boolean isAdded) {
         synchronized (mLock) {
             final Resources res = mContext.getResources();
-            final ComponentName dialogComponent = ComponentName.unflattenFromString(
-                    res.getString(R.string.config_iccHotswapPromptForRestartDialogComponent));
+            final String dialogComponent = res.getString(
+                    R.string.config_iccHotswapPromptForRestartDialogComponent);
             if (dialogComponent != null) {
-                Intent intent = new Intent().setComponent(dialogComponent)
-                        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+                Intent intent = new Intent().setComponent(ComponentName.unflattenFromString(
+                        dialogComponent)).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                         .putExtra(EXTRA_ICC_CARD_ADDED, isAdded);
                 try {
                     mContext.startActivityAsUser(intent, UserHandle.CURRENT);
@@ -571,17 +408,16 @@
     /**
      * Processes radio state unavailable event
      */
-    public void onRadioStateUnavailable(int phoneId) {
+    public void onRadioStateUnavailable() {
         nullifyUiccCard(true /* sim state is unknown */);
 
-        if (phoneId != INVALID_PHONE_ID) {
+        if (mPhoneId != INVALID_PHONE_ID) {
             UiccController.updateInternalIccState(
-                    mContext, IccCardConstants.State.UNKNOWN, null, phoneId);
-            mLastRadioState.put(getPortIndexFromPhoneId(phoneId),
-                    TelephonyManager.RADIO_POWER_UNAVAILABLE);
+                    mContext, IccCardConstants.State.UNKNOWN, null, mPhoneId);
         }
 
         mCardState = null;
+        mLastRadioState = TelephonyManager.RADIO_POWER_UNAVAILABLE;
     }
 
     private void log(String msg) {
@@ -592,27 +428,18 @@
         Rlog.e(TAG, msg);
     }
 
-    private Map<Integer, String> getPrintableIccIds() {
-        Map<Integer, String> printableIccIds = mIccIds.entrySet().stream()
-                .collect(Collectors.toMap(Map.Entry::getKey,
-                        e -> SubscriptionInfo.givePrintableIccid(e.getValue())));
-        return printableIccIds;
-    }
-
     /**
      * Dump
      */
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("UiccSlot:");
+        pw.println(" mCi=" + mCi);
         pw.println(" mActive=" + mActive);
         pw.println(" mIsEuicc=" + mIsEuicc);
-        pw.println(" isEuiccSupportsMultipleEnabledProfiles="
-                + isMultipleEnabledProfileSupported());
         pw.println(" mIsRemovable=" + mIsRemovable);
         pw.println(" mLastRadioState=" + mLastRadioState);
-        pw.println(" mIccIds=" + getPrintableIccIds());
-        pw.println(" mPortIdxToPhoneId=" + mPortIdxToPhoneId);
-        pw.println(" mEid=" + Rlog.pii(TelephonyUtils.IS_DEBUGGABLE, mEid));
+        pw.println(" mIccId=" + mIccId);
+        pw.println(" mEid=" + mEid);
         pw.println(" mCardState=" + mCardState);
         if (mUiccCard != null) {
             pw.println(" mUiccCard=" + mUiccCard);
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java b/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
index 75bc3ba..7ec5e60 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/EuiccCard.java
@@ -16,35 +16,122 @@
 
 package com.android.internal.telephony.uicc.euicc;
 
+import android.annotation.Nullable;
 import android.content.Context;
+import android.content.res.Resources;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Registrant;
 import android.os.RegistrantList;
-import android.telephony.TelephonyManager;
+import android.service.carrier.CarrierIdentifier;
+import android.service.euicc.EuiccProfileInfo;
+import android.telephony.SubscriptionInfo;
+import android.telephony.UiccAccessRule;
+import android.telephony.euicc.EuiccCardManager;
+import android.telephony.euicc.EuiccNotification;
+import android.telephony.euicc.EuiccRulesAuthTable;
 import android.text.TextUtils;
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.CommandsInterface;
+import com.android.internal.telephony.Phone;
+import com.android.internal.telephony.PhoneFactory;
 import com.android.internal.telephony.uicc.IccCardStatus;
+import com.android.internal.telephony.uicc.IccIoResult;
+import com.android.internal.telephony.uicc.IccUtils;
 import com.android.internal.telephony.uicc.UiccCard;
-import com.android.internal.telephony.uicc.UiccPort;
+import com.android.internal.telephony.uicc.asn1.Asn1Decoder;
+import com.android.internal.telephony.uicc.asn1.Asn1Node;
+import com.android.internal.telephony.uicc.asn1.InvalidAsn1DataException;
+import com.android.internal.telephony.uicc.asn1.TagNotFoundException;
+import com.android.internal.telephony.uicc.euicc.EuiccCardErrorException.OperationCode;
+import com.android.internal.telephony.uicc.euicc.apdu.ApduException;
+import com.android.internal.telephony.uicc.euicc.apdu.ApduSender;
+import com.android.internal.telephony.uicc.euicc.apdu.ApduSenderResultCallback;
+import com.android.internal.telephony.uicc.euicc.apdu.RequestBuilder;
+import com.android.internal.telephony.uicc.euicc.apdu.RequestProvider;
 import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback;
+import com.android.internal.telephony.uicc.euicc.async.AsyncResultHelper;
 import com.android.telephony.Rlog;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.List;
 
+/**
+ * This represents an eUICC card to perform profile management operations asynchronously. This class
+ * includes methods defined by different versions of GSMA Spec (SGP.22).
+ */
 public class EuiccCard extends UiccCard {
     private static final String LOG_TAG = "EuiccCard";
     private static final boolean DBG = true;
 
-    private volatile String mEid;
-    private RegistrantList mEidReadyRegistrants;
+    private static final String ISD_R_AID = "A0000005591010FFFFFFFF8900000100";
+    private static final int ICCID_LENGTH = 20;
 
-    public EuiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock,
-            boolean isSupportsMultipleEnabledProfiles) {
-        super(c, ci, ics, phoneId, lock, isSupportsMultipleEnabledProfiles);
+    // APDU status for SIM refresh
+    private static final int APDU_ERROR_SIM_REFRESH = 0x6F00;
+
+    // These error codes are defined in GSMA SGP.22. 0 is the code for success.
+    private static final int CODE_OK = 0;
+
+    // Error code for profile not in expected state for the operation. This error includes the case
+    // that profile is not in disabled state when being enabled or deleted, and that profile is not
+    // in enabled state when being disabled.
+    private static final int CODE_PROFILE_NOT_IN_EXPECTED_STATE = 2;
+
+    // Error code for nothing to delete when resetting eUICC memory or removing notifications.
+    private static final int CODE_NOTHING_TO_DELETE = 1;
+
+    // Error code for no result available when retrieving notifications.
+    private static final int CODE_NO_RESULT_AVAILABLE = 1;
+
+    private static final EuiccSpecVersion SGP22_V_2_0 = new EuiccSpecVersion(2, 0, 0);
+    private static final EuiccSpecVersion SGP22_V_2_1 = new EuiccSpecVersion(2, 1, 0);
+
+    // Device capabilities.
+    private static final String DEV_CAP_GSM = "gsm";
+    private static final String DEV_CAP_UTRAN = "utran";
+    private static final String DEV_CAP_CDMA_1X = "cdma1x";
+    private static final String DEV_CAP_HRPD = "hrpd";
+    private static final String DEV_CAP_EHRPD = "ehrpd";
+    private static final String DEV_CAP_EUTRAN = "eutran";
+    private static final String DEV_CAP_NFC = "nfc";
+    private static final String DEV_CAP_CRL = "crl";
+    private static final String DEV_CAP_NREPC = "nrepc";
+    private static final String DEV_CAP_NR5GC = "nr5gc";
+    private static final String DEV_CAP_EUTRAN5GC = "eutran5gc";
+
+    // These interfaces are used for simplifying the code by leveraging lambdas.
+    private interface ApduRequestBuilder {
+        void build(RequestBuilder requestBuilder)
+                throws EuiccCardException, TagNotFoundException, InvalidAsn1DataException;
+    }
+
+    private interface ApduResponseHandler<T> {
+        T handleResult(byte[] response)
+                throws EuiccCardException, TagNotFoundException, InvalidAsn1DataException;
+    }
+
+    private interface ApduIntermediateResultHandler {
+        boolean shouldContinue(IccIoResult intermediateResult);
+    }
+
+    private interface ApduExceptionHandler {
+        void handleException(Throwable e);
+    }
+
+    private final ApduSender mApduSender;
+    private RegistrantList mEidReadyRegistrants;
+    private EuiccSpecVersion mSpecVersion;
+    private volatile String mEid;
+
+    public EuiccCard(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock) {
+        super(c, ci, ics, phoneId, lock);
+        // TODO: Set supportExtendedApdu based on ATR.
+        mApduSender = new ApduSender(ci, ISD_R_AID, false /* supportExtendedApdu */);
+
         if (TextUtils.isEmpty(ics.eid)) {
             loge("no eid given in constructor for phone " + phoneId);
             loadEidAndNotifyRegistrants();
@@ -55,43 +142,6 @@
     }
 
     /**
-     * Updates MEP(Multiple Enabled Profile) support flag.
-     *
-     * <p>If IccSlotStatus comes later, the number of ports reported is only known after the
-     * UiccCard creation which will impact UICC MEP capability.
-     */
-    @Override
-    public void updateSupportMultipleEnabledProfile(boolean supported) {
-        mIsSupportsMultipleEnabledProfiles = supported;
-        for (UiccPort port : mUiccPorts.values()) {
-            if (port instanceof EuiccPort) {
-                ((EuiccPort) port).updateSupportMultipleEnabledProfile(supported);
-            } else {
-                loge("eUICC card has non-euicc port object:" + port.toString());
-            }
-        }
-    }
-
-    @Override
-    public void update(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId) {
-        synchronized (mLock) {
-            if (!TextUtils.isEmpty(ics.eid)) {
-                mEid = ics.eid;
-            }
-            super.update(c, ci, ics, phoneId);
-        }
-    }
-
-    @Override
-    protected void updateCardId(String iccId) {
-        if (TextUtils.isEmpty(mEid)) {
-            super.updateCardId(iccId);
-        } else {
-            mCardId = mEid;
-        }
-    }
-
-    /**
      * Registers to be notified when EID is ready. If the EID is ready when this method is called,
      * the registrant will be notified immediately.
      */
@@ -124,11 +174,6 @@
         AsyncResultCallback<String> cardCb = new AsyncResultCallback<String>() {
             @Override
             public void onResult(String result) {
-                mEid = result;
-                mCardId = result;
-                if (TextUtils.isEmpty(result)) {
-                    logd("eid is loaded but empty ");
-                }
                 if (mEidReadyRegistrants != null) {
                     mEidReadyRegistrants.notifyRegistrants(new AsyncResult(null, null, null));
                 }
@@ -145,8 +190,191 @@
                 Rlog.e(LOG_TAG, "Failed loading eid", e);
             }
         };
-        ((EuiccPort) mUiccPorts.get(TelephonyManager.DEFAULT_PORT_INDEX)).getEid(cardCb,
-                euiccMainThreadHandler);
+        getEid(cardCb, euiccMainThreadHandler);
+    }
+
+    /**
+     * Gets the GSMA RSP specification version supported by this eUICC. This may return null if the
+     * version cannot be read.
+     */
+    public void getSpecVersion(AsyncResultCallback<EuiccSpecVersion> callback, Handler handler) {
+        if (mSpecVersion != null) {
+            AsyncResultHelper.returnResult(mSpecVersion, callback, handler);
+            return;
+        }
+
+        sendApdu(newRequestProvider((RequestBuilder requestBuilder) -> { /* Do nothing */ }),
+                (byte[] response) -> mSpecVersion, callback, handler);
+    }
+
+    @Override
+    public void update(Context c, CommandsInterface ci, IccCardStatus ics) {
+        synchronized (mLock) {
+            if (!TextUtils.isEmpty(ics.eid)) {
+                mEid = ics.eid;
+            }
+            super.update(c, ci, ics);
+        }
+    }
+
+    @Override
+    protected void updateCardId() {
+        if (TextUtils.isEmpty(mEid)) {
+            super.updateCardId();
+        } else {
+            mCardId = mEid;
+        }
+    }
+
+    /**
+     * Gets a list of user-visible profiles.
+     *
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 1.1.0 [GSMA SGP.22]
+     */
+    public void getAllProfiles(AsyncResultCallback<EuiccProfileInfo[]> callback, Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_PROFILES)
+                                .addChildAsBytes(Tags.TAG_TAG_LIST, Tags.EUICC_PROFILE_TAGS)
+                                .build().toHex())),
+                response -> {
+                    List<Asn1Node> profileNodes = new Asn1Decoder(response).nextNode()
+                            .getChild(Tags.TAG_CTX_COMP_0).getChildren(Tags.TAG_PROFILE_INFO);
+                    int size = profileNodes.size();
+                    EuiccProfileInfo[] profiles = new EuiccProfileInfo[size];
+                    int profileCount = 0;
+                    for (int i = 0; i < size; i++) {
+                        Asn1Node profileNode = profileNodes.get(i);
+                        if (!profileNode.hasChild(Tags.TAG_ICCID)) {
+                            loge("Profile must have an ICCID.");
+                            continue;
+                        }
+                        String strippedIccIdString =
+                                stripTrailingFs(profileNode.getChild(Tags.TAG_ICCID).asBytes());
+                        EuiccProfileInfo.Builder profileBuilder =
+                                new EuiccProfileInfo.Builder(strippedIccIdString);
+                        buildProfile(profileNode, profileBuilder);
+
+                        EuiccProfileInfo profile = profileBuilder.build();
+                        profiles[profileCount++] = profile;
+                    }
+                    return profiles;
+                },
+                callback, handler);
+    }
+
+    /**
+     * Gets a profile.
+     *
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 1.1.0 [GSMA SGP.22]
+     */
+    public final void getProfile(String iccid, AsyncResultCallback<EuiccProfileInfo> callback,
+            Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_PROFILES)
+                                .addChild(Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0)
+                                    .addChildAsBytes(
+                                        Tags.TAG_ICCID, IccUtils.bcdToBytes(padTrailingFs(iccid)))
+                                    .build())
+                                .addChildAsBytes(Tags.TAG_TAG_LIST, Tags.EUICC_PROFILE_TAGS)
+                                .build().toHex())),
+                response -> {
+                    List<Asn1Node> profileNodes = new Asn1Decoder(response).nextNode()
+                            .getChild(Tags.TAG_CTX_COMP_0).getChildren(Tags.TAG_PROFILE_INFO);
+                    if (profileNodes.isEmpty()) {
+                        return null;
+                    }
+                    Asn1Node profileNode = profileNodes.get(0);
+                    String strippedIccIdString =
+                            stripTrailingFs(profileNode.getChild(Tags.TAG_ICCID).asBytes());
+                    EuiccProfileInfo.Builder profileBuilder =
+                            new EuiccProfileInfo.Builder(strippedIccIdString);
+                    buildProfile(profileNode, profileBuilder);
+                    return profileBuilder.build();
+                },
+                callback, handler);
+    }
+
+    /**
+     * Disables a profile of the given {@code iccid}.
+     *
+     * @param refresh Whether sending the REFRESH command to modem.
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 1.1.0 [GSMA SGP.22]
+     */
+    public void disableProfile(String iccid, boolean refresh, AsyncResultCallback<Void> callback,
+            Handler handler) {
+        sendApduWithSimResetErrorWorkaround(
+                newRequestProvider((RequestBuilder requestBuilder) -> {
+                    byte[] iccidBytes = IccUtils.bcdToBytes(padTrailingFs(iccid));
+                    requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_DISABLE_PROFILE)
+                            .addChild(Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0)
+                                    .addChildAsBytes(Tags.TAG_ICCID, iccidBytes))
+                            .addChildAsBoolean(Tags.TAG_CTX_1, refresh)
+                            .build().toHex());
+                }),
+                response -> {
+                    int result;
+                    // SGP.22 v2.0 DisableProfileResponse
+                    result = parseSimpleResult(response);
+                    switch (result) {
+                        case CODE_OK:
+                            return null;
+                        case CODE_PROFILE_NOT_IN_EXPECTED_STATE:
+                            logd("Profile is already disabled, iccid: "
+                                    + SubscriptionInfo.givePrintableIccid(iccid));
+                            return null;
+                        default:
+                            throw new EuiccCardErrorException(
+                                    EuiccCardErrorException.OPERATION_DISABLE_PROFILE, result);
+                    }
+                },
+                callback, handler);
+    }
+
+    /**
+     * Switches from the current profile to another profile. The current profile will be disabled
+     * and the specified profile will be enabled.
+     *
+     * @param refresh Whether sending the REFRESH command to modem.
+     * @param callback The callback to get the EuiccProfile enabled.
+     * @param handler The handler to run the callback.
+     * @since 1.1.0 [GSMA SGP.22]
+     */
+    public void switchToProfile(String iccid, boolean refresh, AsyncResultCallback<Void> callback,
+            Handler handler) {
+        sendApduWithSimResetErrorWorkaround(
+                newRequestProvider((RequestBuilder requestBuilder) -> {
+                    byte[] iccidBytes = IccUtils.bcdToBytes(padTrailingFs(iccid));
+                    requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_ENABLE_PROFILE)
+                            .addChild(Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0)
+                                    .addChildAsBytes(Tags.TAG_ICCID, iccidBytes))
+                            .addChildAsBoolean(Tags.TAG_CTX_1, refresh)
+                            .build().toHex());
+                }),
+                response -> {
+                    int result;
+                    // SGP.22 v2.0 EnableProfileResponse
+                    result = parseSimpleResult(response);
+                    switch (result) {
+                        case CODE_OK:
+                            return null;
+                        case CODE_PROFILE_NOT_IN_EXPECTED_STATE:
+                            logd("Profile is already enabled, iccid: "
+                                    + SubscriptionInfo.givePrintableIccid(iccid));
+                            return null;
+                        default:
+                            throw new EuiccCardErrorException(
+                                    EuiccCardErrorException.OPERATION_SWITCH_TO_PROFILE, result);
+                    }
+                },
+                callback, handler);
     }
 
     /**
@@ -157,6 +385,1052 @@
         return mEid;
     }
 
+    /**
+     * Gets the EID of the eUICC and overwrites mCardId in UiccCard.
+     *
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 1.1.0 [GSMA SGP.22]
+     */
+    public void getEid(AsyncResultCallback<String> callback, Handler handler) {
+        if (mEid != null) {
+            AsyncResultHelper.returnResult(mEid, callback, handler);
+            return;
+        }
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_EID)
+                                .addChildAsBytes(Tags.TAG_TAG_LIST, new byte[] {Tags.TAG_EID})
+                                .build().toHex())),
+                response -> {
+                    String eid = IccUtils.bytesToHexString(parseResponse(response)
+                            .getChild(Tags.TAG_EID).asBytes());
+                    synchronized (mLock) {
+                        mEid = eid;
+                        mCardId = eid;
+                    }
+                    return eid;
+                },
+                callback, handler);
+    }
+
+    /**
+     * Sets the nickname of a profile.
+     *
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 1.1.0 [GSMA SGP.22]
+     */
+    public void setNickname(String iccid, String nickname, AsyncResultCallback<Void> callback,
+            Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_SET_NICKNAME)
+                                .addChildAsBytes(Tags.TAG_ICCID,
+                                        IccUtils.bcdToBytes(padTrailingFs(iccid)))
+                                .addChildAsString(Tags.TAG_NICKNAME, nickname)
+                                .build().toHex())),
+                response -> {
+                    // SGP.22 v2.0 SetNicknameResponse
+                    int result = parseSimpleResult(response);
+                    if (result != CODE_OK) {
+                        throw new EuiccCardErrorException(
+                                EuiccCardErrorException.OPERATION_SET_NICKNAME, result);
+                    }
+                    return null;
+                },
+                callback, handler);
+    }
+
+    /**
+     * Deletes a profile from eUICC.
+     *
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 1.1.0 [GSMA SGP.22]
+     */
+    public void deleteProfile(String iccid, AsyncResultCallback<Void> callback, Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) -> {
+                    byte[] iccidBytes = IccUtils.bcdToBytes(padTrailingFs(iccid));
+                    requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_DELETE_PROFILE)
+                            .addChildAsBytes(Tags.TAG_ICCID, iccidBytes)
+                            .build().toHex());
+                }),
+                response -> {
+                    // SGP.22 v2.0 DeleteProfileRequest
+                    int result = parseSimpleResult(response);
+                    if (result != CODE_OK) {
+                        throw new EuiccCardErrorException(
+                                EuiccCardErrorException.OPERATION_DELETE_PROFILE, result);
+                    }
+                    return null;
+                },
+                callback, handler);
+    }
+
+    /**
+     * Resets the eUICC memory (e.g., remove all profiles).
+     *
+     * @param options Bits of the options of resetting which parts of the eUICC memory.
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 1.1.0 [GSMA SGP.22]
+     */
+    public void resetMemory(@EuiccCardManager.ResetOption int options,
+            AsyncResultCallback<Void> callback, Handler handler) {
+        sendApduWithSimResetErrorWorkaround(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_EUICC_MEMORY_RESET)
+                                .addChildAsBits(Tags.TAG_CTX_2, options)
+                                .build().toHex())),
+                response -> {
+                    int result = parseSimpleResult(response);
+                    if (result != CODE_OK && result != CODE_NOTHING_TO_DELETE) {
+                        throw new EuiccCardErrorException(
+                                EuiccCardErrorException.OPERATION_RESET_MEMORY, result);
+                    }
+                    return null;
+                },
+                callback, handler);
+    }
+
+    /**
+     * Gets the default SM-DP+ address from eUICC.
+     *
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void getDefaultSmdpAddress(AsyncResultCallback<String> callback, Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(
+                                Asn1Node.newBuilder(Tags.TAG_GET_CONFIGURED_ADDRESSES)
+                                        .build().toHex())),
+                (byte[] response) -> parseResponse(response).getChild(Tags.TAG_CTX_0).asString(),
+                callback, handler);
+    }
+
+    /**
+     * Gets the SM-DS address from eUICC.
+     *
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void getSmdsAddress(AsyncResultCallback<String> callback, Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(
+                                Asn1Node.newBuilder(Tags.TAG_GET_CONFIGURED_ADDRESSES)
+                                        .build().toHex())),
+                (byte[] response) -> parseResponse(response).getChild(Tags.TAG_CTX_1).asString(),
+                callback, handler);
+    }
+
+    /**
+     * Sets the default SM-DP+ address of eUICC.
+     *
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void setDefaultSmdpAddress(String defaultSmdpAddress, AsyncResultCallback<Void> callback,
+            Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(
+                                Asn1Node.newBuilder(Tags.TAG_SET_DEFAULT_SMDP_ADDRESS)
+                                        .addChildAsString(Tags.TAG_CTX_0, defaultSmdpAddress)
+                                        .build().toHex())),
+                response -> {
+                    // SGP.22 v2.0 SetDefaultDpAddressResponse
+                    int result = parseSimpleResult(response);
+                    if (result != CODE_OK) {
+                        throw new EuiccCardErrorException(
+                                EuiccCardErrorException.OPERATION_SET_DEFAULT_SMDP_ADDRESS, result);
+                    }
+                    return null;
+                },
+                callback, handler);
+    }
+
+    /**
+     * Gets Rules Authorisation Table.
+     *
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void getRulesAuthTable(AsyncResultCallback<EuiccRulesAuthTable> callback,
+            Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_RAT)
+                                .build().toHex())),
+                response -> {
+                    Asn1Node root = parseResponse(response);
+                    List<Asn1Node> nodes = root.getChildren(Tags.TAG_CTX_COMP_0);
+                    EuiccRulesAuthTable.Builder builder =
+                            new EuiccRulesAuthTable.Builder(nodes.size());
+                    int size = nodes.size();
+                    for (int i = 0; i < size; i++) {
+                        Asn1Node node = nodes.get(i);
+                        List<Asn1Node> opIdNodes =
+                                node.getChild(Tags.TAG_SEQUENCE, Tags.TAG_CTX_COMP_1).getChildren();
+                        int opIdSize = opIdNodes.size();
+                        CarrierIdentifier[] opIds = new CarrierIdentifier[opIdSize];
+                        for (int j = 0; j < opIdSize; j++) {
+                            opIds[j] = buildCarrierIdentifier(opIdNodes.get(j));
+                        }
+                        builder.add(node.getChild(Tags.TAG_SEQUENCE, Tags.TAG_CTX_0).asBits(),
+                                Arrays.asList(opIds), node.getChild(Tags.TAG_SEQUENCE,
+                                Tags.TAG_CTX_2).asBits());
+                    }
+                    return builder.build();
+                },
+                callback, handler);
+    }
+
+    /**
+     * Gets the eUICC challenge for new profile downloading.
+     *
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void getEuiccChallenge(AsyncResultCallback<byte[]> callback, Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(
+                                Asn1Node.newBuilder(Tags.TAG_GET_EUICC_CHALLENGE)
+                                        .build().toHex())),
+                (byte[] response) -> parseResponse(response).getChild(Tags.TAG_CTX_0).asBytes(),
+                callback, handler);
+    }
+
+    /**
+     * Gets the eUICC info1 for new profile downloading.
+     *
+     * @param callback The callback to get the result, which represents an {@code EUICCInfo1}
+     *     defined in GSMA RSP v2.0+.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void getEuiccInfo1(AsyncResultCallback<byte[]> callback, Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_EUICC_INFO_1)
+                                .build().toHex())),
+                (response) -> response,
+                callback, handler);
+    }
+
+    /**
+     * Gets the eUICC info2 for new profile downloading.
+     *
+     * @param callback The callback to get the result, which represents an {@code EUICCInfo2}
+     *     defined in GSMA RSP v2.0+.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void getEuiccInfo2(AsyncResultCallback<byte[]> callback, Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_EUICC_INFO_2)
+                                .build().toHex())),
+                (response) -> response,
+                callback, handler);
+    }
+
+    /**
+     * Authenticates the SM-DP+ server by the eUICC. The parameters {@code serverSigned1}, {@code
+     * serverSignature1}, {@code euiccCiPkIdToBeUsed}, and {@code serverCertificate} are the ASN.1
+     * data returned by SM-DP+ server.
+     *
+     * @param matchingId The activation code or an empty string.
+     * @param callback The callback to get the result, which represents an {@code
+     *     AuthenticateServerResponse} defined in GSMA RSP v2.0+.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void authenticateServer(String matchingId, byte[] serverSigned1, byte[] serverSignature1,
+            byte[] euiccCiPkIdToBeUsed, byte[] serverCertificate,
+            AsyncResultCallback<byte[]> callback, Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) -> {
+                    byte[] imeiBytes = getDeviceId();
+                    // TAC is the first 8 digits (4 bytes) of IMEI.
+                    byte[] tacBytes = new byte[4];
+                    System.arraycopy(imeiBytes, 0, tacBytes, 0, 4);
+
+                    Asn1Node.Builder devCapsBuilder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1);
+                    String[] devCapsStrings = getResources().getStringArray(
+                            com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities);
+                    if (devCapsStrings != null) {
+                        for (String devCapItem : devCapsStrings) {
+                            addDeviceCapability(devCapsBuilder, devCapItem);
+                        }
+                    } else {
+                        if (DBG) logd("No device capabilities set.");
+                    }
+
+                    Asn1Node.Builder ctxParams1Builder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0)
+                            .addChildAsString(Tags.TAG_CTX_0, matchingId)
+                            .addChild(Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1)
+                                    .addChildAsBytes(Tags.TAG_CTX_0, tacBytes)
+                                    .addChild(devCapsBuilder)
+                                    .addChildAsBytes(Tags.TAG_CTX_2, imeiBytes));
+
+                    requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_AUTHENTICATE_SERVER)
+                            .addChild(new Asn1Decoder(serverSigned1).nextNode())
+                            .addChild(new Asn1Decoder(serverSignature1).nextNode())
+                            .addChild(new Asn1Decoder(euiccCiPkIdToBeUsed).nextNode())
+                            .addChild(new Asn1Decoder(serverCertificate).nextNode())
+                            .addChild(ctxParams1Builder)
+                            .build().toHex());
+                }),
+                response -> {
+                    Asn1Node root = parseResponse(response);
+                    if (root.hasChild(Tags.TAG_CTX_COMP_1, Tags.TAG_UNI_2)) {
+                        throw new EuiccCardErrorException(
+                                EuiccCardErrorException.OPERATION_AUTHENTICATE_SERVER,
+                                root.getChild(Tags.TAG_CTX_COMP_1, Tags.TAG_UNI_2).asInteger());
+                    }
+                    return root.toBytes();
+                },
+                callback, handler);
+    }
+
+    /**
+     * Prepares the profile download request sent to SM-DP+. The parameters {@code smdpSigned2},
+     * {@code smdpSignature2}, and {@code smdpCertificate} are the ASN.1 data returned by SM-DP+
+     * server.
+     *
+     * @param hashCc The hash of confirmation code. It can be null if there is no confirmation code
+     *     required.
+     * @param callback The callback to get the result, which represents an {@code
+     *     PrepareDownloadResponse} defined in GSMA RSP v2.0+.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void prepareDownload(@Nullable byte[] hashCc, byte[] smdpSigned2, byte[] smdpSignature2,
+            byte[] smdpCertificate, AsyncResultCallback<byte[]> callback, Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) -> {
+                    Asn1Node.Builder builder = Asn1Node.newBuilder(Tags.TAG_PREPARE_DOWNLOAD)
+                            .addChild(new Asn1Decoder(smdpSigned2).nextNode())
+                            .addChild(new Asn1Decoder(smdpSignature2).nextNode());
+                    if (hashCc != null) {
+                        builder.addChildAsBytes(Tags.TAG_UNI_4, hashCc);
+                    }
+                    requestBuilder.addStoreData(
+                            builder.addChild(new Asn1Decoder(smdpCertificate).nextNode())
+                                    .build().toHex());
+                }),
+                response -> {
+                    Asn1Node root = parseResponse(response);
+                    if (root.hasChild(Tags.TAG_CTX_COMP_1, Tags.TAG_UNI_2)) {
+                        throw new EuiccCardErrorException(
+                                EuiccCardErrorException.OPERATION_PREPARE_DOWNLOAD,
+                                root.getChild(Tags.TAG_CTX_COMP_1, Tags.TAG_UNI_2).asInteger());
+                    }
+                    return root.toBytes();
+                },
+                callback, handler);
+    }
+
+    /**
+     * Loads a downloaded bound profile package onto the eUICC.
+     *
+     * @param boundProfilePackage The Bound Profile Package data returned by SM-DP+ server.
+     * @param callback The callback to get the result, which represents an {@code
+     *     LoadBoundProfilePackageResponse} defined in GSMA RSP v2.0+.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void loadBoundProfilePackage(byte[] boundProfilePackage,
+            AsyncResultCallback<byte[]> callback, Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) -> {
+                    Asn1Node bppNode = new Asn1Decoder(boundProfilePackage).nextNode();
+                    int actualLength = bppNode.getDataLength();
+                    int segmentedLength = 0;
+                    // initialiseSecureChannelRequest (ES8+.InitialiseSecureChannel)
+                    Asn1Node initialiseSecureChannelRequest = bppNode.getChild(
+                            Tags.TAG_INITIALISE_SECURE_CHANNEL);
+                    segmentedLength += initialiseSecureChannelRequest.getEncodedLength();
+                    // firstSequenceOf87 (ES8+.ConfigureISDP)
+                    Asn1Node firstSequenceOf87 = bppNode.getChild(Tags.TAG_CTX_COMP_0);
+                    segmentedLength += firstSequenceOf87.getEncodedLength();
+                    // sequenceOf88 (ES8+.StoreMetadata)
+                    Asn1Node sequenceOf88 = bppNode.getChild(Tags.TAG_CTX_COMP_1);
+                    List<Asn1Node> metaDataSeqs = sequenceOf88.getChildren(Tags.TAG_CTX_8);
+                    segmentedLength += sequenceOf88.getEncodedLength();
+                    // secondSequenceOf87 (ES8+.ReplaceSessionKeys), optional
+                    Asn1Node secondSequenceOf87 = null;
+                    if (bppNode.hasChild(Tags.TAG_CTX_COMP_2)) {
+                        secondSequenceOf87 = bppNode.getChild(Tags.TAG_CTX_COMP_2);
+                        segmentedLength += secondSequenceOf87.getEncodedLength();
+                    }
+                    // sequenceOf86 (ES8+.LoadProfileElements)
+                    Asn1Node sequenceOf86 = bppNode.getChild(Tags.TAG_CTX_COMP_3);
+                    List<Asn1Node> elementSeqs = sequenceOf86.getChildren(Tags.TAG_CTX_6);
+                    segmentedLength += sequenceOf86.getEncodedLength();
+
+                    if (mSpecVersion.compareTo(SGP22_V_2_1) >= 0) {
+                        // Per SGP.22 v2.1+ section 2.5.5, it's the LPA's job to "segment" the BPP
+                        // before sending it to the eUICC. This check was only instituted in SGP.22
+                        // v2.1 and higher. SGP.22 v2.0 doesn't mention this "segmentation" process
+                        // at all, or what the LPA should do in the case of unrecognized or missing
+                        // tags. Per section 3.1.3.3: "If the LPAd is unable to perform the
+                        // segmentation (e.g., because of an error in the BPP structure), ... the
+                        // LPAd SHALL perform the Sub-procedure "Profile Download and installation -
+                        // Download rejection" with reason code 'Load BPP execution error'." This
+                        // implies that if we detect an invalid BPP, we should short-circuit before
+                        // sending anything to the eUICC. There are two cases to account for:
+                        if (elementSeqs == null || elementSeqs.isEmpty()) {
+                            // 1. The BPP is missing a required tag. Upon calling bppNode.getChild,
+                            // an exception will occur if the expected tag is missing, though we
+                            // should make sure that the sequences are non-empty when appropriate as
+                            // well. A profile with no profile elements is invalid. This is
+                            // explicitly tested by SGP.23 case 4.4.25.2.1_03.
+                            throw new EuiccCardException("No profile elements in BPP");
+                        } else if (actualLength != segmentedLength) {
+                            // 2. The BPP came with extraneous tags other than what the spec
+                            // mandates. We keep track of the total length of the BPP and compare it
+                            // to the length of the segments we care about. If they're different,
+                            // we'll throw an exception to indicate this. This is explicitly tested
+                            // by SGP.23 case 4.4.25.2.1_05.
+                            throw new EuiccCardException(
+                                    "Actual BPP length ("
+                                            + actualLength
+                                            + ") does not match segmented length ("
+                                            + segmentedLength
+                                            + "), this must be due to a malformed BPP");
+                        }
+                    }
+
+                    requestBuilder.addStoreData(bppNode.getHeadAsHex()
+                            + initialiseSecureChannelRequest.toHex());
+
+                    requestBuilder.addStoreData(firstSequenceOf87.toHex());
+
+                    requestBuilder.addStoreData(sequenceOf88.getHeadAsHex());
+                    int size = metaDataSeqs.size();
+                    for (int i = 0; i < size; i++) {
+                        requestBuilder.addStoreData(metaDataSeqs.get(i).toHex());
+                    }
+
+                    if (secondSequenceOf87 != null) {
+                        requestBuilder.addStoreData(secondSequenceOf87.toHex());
+                    }
+
+                    requestBuilder.addStoreData(sequenceOf86.getHeadAsHex());
+                    size = elementSeqs.size();
+                    for (int i = 0; i < size; i++) {
+                        requestBuilder.addStoreData(elementSeqs.get(i).toHex());
+                    }
+                }),
+                response -> {
+                    // SGP.22 v2.0 ErrorResult
+                    Asn1Node root = parseResponse(response);
+                    if (root.hasChild(Tags.TAG_PROFILE_INSTALLATION_RESULT_DATA,
+                            Tags.TAG_CTX_COMP_2, Tags.TAG_CTX_COMP_1, Tags.TAG_CTX_1)) {
+                        Asn1Node errorNode = root.getChild(
+                                Tags.TAG_PROFILE_INSTALLATION_RESULT_DATA, Tags.TAG_CTX_COMP_2,
+                                Tags.TAG_CTX_COMP_1, Tags.TAG_CTX_1);
+                        throw new EuiccCardErrorException(
+                                EuiccCardErrorException.OPERATION_LOAD_BOUND_PROFILE_PACKAGE,
+                                errorNode.asInteger(), errorNode);
+                    }
+                    return root.toBytes();
+                },
+                intermediateResult -> {
+                    byte[] payload = intermediateResult.payload;
+                    if (payload != null && payload.length > 2) {
+                        int tag = (payload[0] & 0xFF) << 8 | (payload[1] & 0xFF);
+                        // Stops if the installation result has been returned
+                        if (tag == Tags.TAG_PROFILE_INSTALLATION_RESULT) {
+                            logd("loadBoundProfilePackage failed due to an early error.");
+                            return false;
+                        }
+                    }
+                    return true;
+                },
+                callback, handler);
+    }
+
+    /**
+     * Cancels the current profile download session.
+     *
+     * @param transactionId The transaction ID returned by SM-DP+ server.
+     * @param callback The callback to get the result, which represents an {@code
+     *     CancelSessionResponse} defined in GSMA RSP v2.0+.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void cancelSession(byte[] transactionId, @EuiccCardManager.CancelReason int reason,
+            AsyncResultCallback<byte[]> callback, Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_CANCEL_SESSION)
+                                .addChildAsBytes(Tags.TAG_CTX_0, transactionId)
+                                .addChildAsInteger(Tags.TAG_CTX_1, reason)
+                                .build().toHex())),
+                (byte[] response) ->
+                        parseResponseAndCheckSimpleError(response,
+                                EuiccCardErrorException.OPERATION_CANCEL_SESSION).toBytes(),
+                callback, handler);
+    }
+
+    /**
+     * Lists all notifications of the given {@code notificationEvents}.
+     *
+     * @param events Bits of the event types ({@link EuiccNotification.Event}) to list.
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void listNotifications(@EuiccNotification.Event int events,
+            AsyncResultCallback<EuiccNotification[]> callback, Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_LIST_NOTIFICATION)
+                                .addChildAsBits(Tags.TAG_CTX_1, events)
+                                .build().toHex())),
+                response -> {
+                    Asn1Node root = parseResponseAndCheckSimpleError(response,
+                            EuiccCardErrorException.OPERATION_LIST_NOTIFICATIONS);
+                    List<Asn1Node> nodes = root.getChild(Tags.TAG_CTX_COMP_0).getChildren();
+                    EuiccNotification[] notifications = new EuiccNotification[nodes.size()];
+                    for (int i = 0; i < notifications.length; ++i) {
+                        notifications[i] = createNotification(nodes.get(i));
+                    }
+                    return notifications;
+                },
+                callback, handler);
+    }
+
+    /**
+     * Retrieves contents of all notification of the given {@code events}.
+     *
+     * @param events Bits of the event types ({@link EuiccNotification.Event}) to list.
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void retrieveNotificationList(@EuiccNotification.Event int events,
+            AsyncResultCallback<EuiccNotification[]> callback, Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(
+                                Asn1Node.newBuilder(Tags.TAG_RETRIEVE_NOTIFICATIONS_LIST)
+                                        .addChild(Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0)
+                                                .addChildAsBits(Tags.TAG_CTX_1, events))
+                                        .build().toHex())),
+                response -> {
+                    Asn1Node root = parseResponse(response);
+                    if (root.hasChild(Tags.TAG_CTX_1)) {
+                        // SGP.22 v2.0 RetrieveNotificationsListResponse
+                        int error = root.getChild(Tags.TAG_CTX_1).asInteger();
+                        switch (error) {
+                            case CODE_NO_RESULT_AVAILABLE:
+                                return new EuiccNotification[0];
+                            default:
+                                throw new EuiccCardErrorException(
+                                        EuiccCardErrorException.OPERATION_RETRIEVE_NOTIFICATION,
+                                        error);
+                        }
+                    }
+                    List<Asn1Node> nodes = root.getChild(Tags.TAG_CTX_COMP_0).getChildren();
+                    EuiccNotification[] notifications = new EuiccNotification[nodes.size()];
+                    for (int i = 0; i < notifications.length; ++i) {
+                        notifications[i] = createNotification(nodes.get(i));
+                    }
+                    return notifications;
+                },
+                callback, handler);
+    }
+
+    /**
+     * Retrieves the content of a notification of the given {@code seqNumber}.
+     *
+     * @param seqNumber The sequence number of the notification.
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void retrieveNotification(int seqNumber, AsyncResultCallback<EuiccNotification> callback,
+            Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(
+                                Asn1Node.newBuilder(Tags.TAG_RETRIEVE_NOTIFICATIONS_LIST)
+                                        .addChild(Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0)
+                                                .addChildAsInteger(Tags.TAG_CTX_0, seqNumber))
+                                        .build().toHex())),
+                response -> {
+                    Asn1Node root = parseResponseAndCheckSimpleError(response,
+                            EuiccCardErrorException.OPERATION_RETRIEVE_NOTIFICATION);
+                    List<Asn1Node> nodes = root.getChild(Tags.TAG_CTX_COMP_0).getChildren();
+                    if (nodes.size() > 0) {
+                        return createNotification(nodes.get(0));
+                    }
+                    return null;
+                },
+                callback, handler);
+    }
+
+    /**
+     * Removes a notification from eUICC.
+     *
+     * @param seqNumber The sequence number of the notification.
+     * @param callback The callback to get the result.
+     * @param handler The handler to run the callback.
+     * @since 2.0.0 [GSMA SGP.22]
+     */
+    public void removeNotificationFromList(int seqNumber, AsyncResultCallback<Void> callback,
+            Handler handler) {
+        sendApdu(
+                newRequestProvider((RequestBuilder requestBuilder) ->
+                        requestBuilder.addStoreData(
+                                Asn1Node.newBuilder(Tags.TAG_REMOVE_NOTIFICATION_FROM_LIST)
+                                        .addChildAsInteger(Tags.TAG_CTX_0, seqNumber)
+                                        .build().toHex())),
+                response -> {
+                    // SGP.22 v2.0 NotificationSentResponse
+                    int result = parseSimpleResult(response);
+                    if (result != CODE_OK && result != CODE_NOTHING_TO_DELETE) {
+                        throw new EuiccCardErrorException(
+                                EuiccCardErrorException.OPERATION_REMOVE_NOTIFICATION_FROM_LIST,
+                                result);
+                    }
+                    return null;
+                },
+                callback, handler);
+    }
+
+    /**
+     * Sets a device capability version as the child of the given device capability ASN1 node
+     * builder.
+     *
+     * @param devCapBuilder The ASN1 node builder to modify.
+     * @param devCapItem The device capability and its supported version in pair.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    public void addDeviceCapability(Asn1Node.Builder devCapBuilder, String devCapItem) {
+        String[] split = devCapItem.split(",");
+        if (split.length != 2) {
+            loge("Invalid device capability item: " + Arrays.toString(split));
+            return;
+        }
+
+        String devCap = split[0].trim();
+        Integer version;
+        try {
+            version = Integer.parseInt(split[1].trim());
+        } catch (NumberFormatException e) {
+            loge("Invalid device capability version number.", e);
+            return;
+        }
+
+        byte[] versionBytes = new byte[] { version.byteValue(), 0, 0 };
+        switch (devCap) {
+            case DEV_CAP_GSM:
+                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_0, versionBytes);
+                break;
+            case DEV_CAP_UTRAN:
+                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_1, versionBytes);
+                break;
+            case DEV_CAP_CDMA_1X:
+                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_2, versionBytes);
+                break;
+            case DEV_CAP_HRPD:
+                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_3, versionBytes);
+                break;
+            case DEV_CAP_EHRPD:
+                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_4, versionBytes);
+                break;
+            case DEV_CAP_EUTRAN:
+                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_5, versionBytes);
+                break;
+            case DEV_CAP_NFC:
+                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_6, versionBytes);
+                break;
+            case DEV_CAP_CRL:
+                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_7, versionBytes);
+                break;
+            case DEV_CAP_NREPC:
+                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_8, versionBytes);
+                break;
+            case DEV_CAP_NR5GC:
+                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_9, versionBytes);
+                break;
+            case DEV_CAP_EUTRAN5GC:
+                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_10, versionBytes);
+                break;
+            default:
+                loge("Invalid device capability name: " + devCap);
+                break;
+        }
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected byte[] getDeviceId() {
+        Phone phone = PhoneFactory.getPhone(getPhoneId());
+        if (phone == null) {
+            return new byte[8];
+        }
+        return getDeviceId(phone.getDeviceId(), mSpecVersion);
+    }
+
+    /**
+     * Different versions of SGP.22 specify different encodings of the device's IMEI, so we handle
+     * those differences here.
+     *
+     * @param imei The IMEI of the device. Assumed to be 15 decimal digits.
+     * @param specVersion The SGP.22 version which we're encoding the IMEI for.
+     * @return A byte string representing the given IMEI according to the specified SGP.22 version.
+     */
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    public static byte[] getDeviceId(String imei, EuiccSpecVersion specVersion) {
+        byte[] imeiBytes = new byte[8];
+        // The IMEI's encoding is version-dependent.
+        if (specVersion.compareTo(SGP22_V_2_1) >= 0) {
+            /*
+             * In SGP.22 v2.1, a clarification was added to clause 4.2 that requires the nibbles of
+             * the last byte to be swapped from normal TBCD encoding (so put back in normal order):
+             *
+             * The IMEI (including the check digit) SHALL be represented as a string of 8 octets
+             * that is coded as a Telephony Binary Coded Decimal String as defined in 3GPP TS 29.002
+             * [63], except that the last octet contains the check digit (in high nibble) and an 'F'
+             * filler (in low nibble). It SHOULD be present if the Device contains a non-removable
+             * eUICC.
+             *
+             * 3GPP TS 29.002 clause 17.7.8 in turn says this:
+             *
+             * TBCD-STRING ::= OCTET STRING
+             * This type (Telephony Binary Coded Decimal String) is used to represent several digits
+             * from 0 through 9, *, #, a, b, c, two digits per octet, each digit encoded 0000 to
+             * 1001 (0 to 9), 1010 (*), 1011 (#), 1100 (a), 1101 (b) or 1110 (c); 1111 used as
+             * filler when there is an odd number of digits.
+             * Bits 8765 of octet n encoding digit 2n
+             * Bits 4321 of octet n encoding digit 2(n-1) + 1
+             */
+            // Since the IMEI is always just decimal digits, we can still use BCD encoding (which
+            // correctly swaps digit ordering within bytes), but we have to manually pad a 0xF value
+            // instead of 0.
+            imei += 'F';
+            IccUtils.bcdToBytes(imei, imeiBytes);
+            // And now the funky last byte flip (this is not normal TBCD, the GSMA added it on top
+            // just for the IMEI for some reason). Bitwise operations promote to int first, so we
+            // have to do some extra masking.
+            byte last = imeiBytes[7];
+            imeiBytes[7] = (byte) ((last & 0xFF) << 4 | ((last & 0xFF) >>> 4));
+        } else {
+            /*
+             * Prior to SGP.22 v2.1, clause 4.2 reads as follows:
+             *
+             * The IMEI (including the check digit) SHALL be represented as a string of 8 octets
+             * that is BCD coded as defined in 3GPP TS 23.003 [35]. It SHOULD be present if the
+             * Device contains a non-removable eUICC.
+             *
+             * It appears that 3GPP TS 23.003 doesn't define anything about BCD encoding, it just
+             * defines what IMEI and a few other telephony identifiers are. We default to normal BCD
+             * encoding since the spec is unclear here.
+             */
+            IccUtils.bcdToBytes(imei, imeiBytes);
+        }
+        return imeiBytes;
+    }
+
+    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+    protected Resources getResources()  {
+        return Resources.getSystem();
+    }
+
+    private RequestProvider newRequestProvider(ApduRequestBuilder builder) {
+        return (selectResponse, requestBuilder) -> {
+            EuiccSpecVersion ver = getOrExtractSpecVersion(selectResponse);
+            if (ver == null) {
+                throw new EuiccCardException("Cannot get eUICC spec version.");
+            }
+            try {
+                if (ver.compareTo(SGP22_V_2_0) < 0) {
+                    throw new EuiccCardException("eUICC spec version is unsupported: " + ver);
+                }
+                builder.build(requestBuilder);
+            } catch (InvalidAsn1DataException | TagNotFoundException e) {
+                throw new EuiccCardException("Cannot parse ASN1 to build request.", e);
+            }
+        };
+    }
+
+    private EuiccSpecVersion getOrExtractSpecVersion(byte[] selectResponse) {
+        // Uses the cached version.
+        if (mSpecVersion != null) {
+            return mSpecVersion;
+        }
+        // Parses and caches the version.
+        EuiccSpecVersion ver = EuiccSpecVersion.fromOpenChannelResponse(selectResponse);
+        if (ver != null) {
+            synchronized (mLock) {
+                if (mSpecVersion == null) {
+                    mSpecVersion = ver;
+                }
+            }
+        }
+        return ver;
+    }
+
+    /**
+     * A wrapper on {@link ApduSender#send(RequestProvider, ApduSenderResultCallback, Handler)} to
+     * leverage lambda to simplify the sending APDU code.EuiccCardErrorException.
+     *
+     * @param requestBuilder Builds the request of APDU commands.
+     * @param responseHandler Converts the APDU response from bytes to expected result.
+     * @param <T> Type of the originally expected result.
+     */
+    private <T> void sendApdu(RequestProvider requestBuilder,
+            ApduResponseHandler<T> responseHandler, AsyncResultCallback<T> callback,
+            Handler handler) {
+        sendApdu(requestBuilder, responseHandler,
+                (e) -> callback.onException(new EuiccCardException("Cannot send APDU.", e)),
+                null, callback, handler);
+    }
+
+    private <T> void sendApdu(RequestProvider requestBuilder,
+            ApduResponseHandler<T> responseHandler,
+            ApduIntermediateResultHandler intermediateResultHandler,
+            AsyncResultCallback<T> callback, Handler handler) {
+        sendApdu(requestBuilder, responseHandler,
+                (e) -> callback.onException(new EuiccCardException("Cannot send APDU.", e)),
+                intermediateResultHandler, callback, handler);
+    }
+
+    /**
+     * This is a workaround solution to the bug that a SIM refresh may interrupt the modem to return
+     * the reset of responses of the original APDU command. This applies to disable profile, switch
+     * profile, and reset eUICC memory.
+     *
+     * <p>TODO: Use
+     * {@link #sendApdu(RequestProvider, ApduResponseHandler, AsyncResultCallback, Handler)} when
+     * this workaround is not needed.
+     */
+    private void sendApduWithSimResetErrorWorkaround(
+            RequestProvider requestBuilder, ApduResponseHandler<Void> responseHandler,
+            AsyncResultCallback<Void> callback, Handler handler) {
+        sendApdu(requestBuilder, responseHandler, (e) -> {
+            if (e instanceof ApduException
+                    && ((ApduException) e).getApduStatus() == APDU_ERROR_SIM_REFRESH) {
+                logi("Sim is refreshed after disabling profile, no response got.");
+                callback.onResult(null);
+            } else {
+                callback.onException(new EuiccCardException("Cannot send APDU.", e));
+            }
+        }, null, callback, handler);
+    }
+
+    private <T> void sendApdu(RequestProvider requestBuilder,
+            ApduResponseHandler<T> responseHandler,
+            ApduExceptionHandler exceptionHandler,
+            @Nullable ApduIntermediateResultHandler intermediateResultHandler,
+            AsyncResultCallback<T> callback,
+            Handler handler) {
+        mApduSender.send(requestBuilder, new ApduSenderResultCallback() {
+            @Override
+            public void onResult(byte[] response) {
+                try {
+                    callback.onResult(responseHandler.handleResult(response));
+                } catch (EuiccCardException e) {
+                    callback.onException(e);
+                } catch (InvalidAsn1DataException | TagNotFoundException e) {
+                    callback.onException(new EuiccCardException(
+                            "Cannot parse response: " + IccUtils.bytesToHexString(response), e));
+                }
+            }
+
+            @Override
+            public boolean shouldContinueOnIntermediateResult(IccIoResult result) {
+                if (intermediateResultHandler == null) {
+                    return true;
+                }
+                return intermediateResultHandler.shouldContinue(result);
+            }
+
+            @Override
+            public void onException(Throwable e) {
+                exceptionHandler.handleException(e);
+            }
+        }, handler);
+    }
+
+    private static void buildProfile(Asn1Node profileNode, EuiccProfileInfo.Builder profileBuilder)
+            throws TagNotFoundException, InvalidAsn1DataException {
+        if (profileNode.hasChild(Tags.TAG_NICKNAME)) {
+            profileBuilder.setNickname(profileNode.getChild(Tags.TAG_NICKNAME).asString());
+        }
+
+        if (profileNode.hasChild(Tags.TAG_SERVICE_PROVIDER_NAME)) {
+            profileBuilder.setServiceProviderName(
+                    profileNode.getChild(Tags.TAG_SERVICE_PROVIDER_NAME).asString());
+        }
+
+        if (profileNode.hasChild(Tags.TAG_PROFILE_NAME)) {
+            profileBuilder.setProfileName(
+                    profileNode.getChild(Tags.TAG_PROFILE_NAME).asString());
+        }
+
+        if (profileNode.hasChild(Tags.TAG_OPERATOR_ID)) {
+            profileBuilder.setCarrierIdentifier(
+                    buildCarrierIdentifier(profileNode.getChild(Tags.TAG_OPERATOR_ID)));
+        }
+
+        if (profileNode.hasChild(Tags.TAG_PROFILE_STATE)) {
+            // noinspection WrongConstant
+            profileBuilder.setState(profileNode.getChild(Tags.TAG_PROFILE_STATE).asInteger());
+        } else {
+            profileBuilder.setState(EuiccProfileInfo.PROFILE_STATE_DISABLED);
+        }
+
+        if (profileNode.hasChild(Tags.TAG_PROFILE_CLASS)) {
+            // noinspection WrongConstant
+            profileBuilder.setProfileClass(
+                    profileNode.getChild(Tags.TAG_PROFILE_CLASS).asInteger());
+        } else {
+            profileBuilder.setProfileClass(EuiccProfileInfo.PROFILE_CLASS_OPERATIONAL);
+        }
+
+        if (profileNode.hasChild(Tags.TAG_PROFILE_POLICY_RULE)) {
+            // noinspection WrongConstant
+            profileBuilder.setPolicyRules(
+                    profileNode.getChild(Tags.TAG_PROFILE_POLICY_RULE).asBits());
+        }
+
+        if (profileNode.hasChild(Tags.TAG_CARRIER_PRIVILEGE_RULES)) {
+            List<Asn1Node> refArDoNodes = profileNode.getChild(Tags.TAG_CARRIER_PRIVILEGE_RULES)
+                    .getChildren(Tags.TAG_REF_AR_DO);
+            UiccAccessRule[] rules = buildUiccAccessRule(refArDoNodes);
+            List<UiccAccessRule> rulesList = null;
+            if (rules != null) {
+                rulesList = Arrays.asList(rules);
+            }
+            profileBuilder.setUiccAccessRule(rulesList);
+        }
+    }
+
+    private static CarrierIdentifier buildCarrierIdentifier(Asn1Node node)
+            throws InvalidAsn1DataException, TagNotFoundException {
+        String gid1 = null;
+        if (node.hasChild(Tags.TAG_CTX_1)) {
+            gid1 = IccUtils.bytesToHexString(node.getChild(Tags.TAG_CTX_1).asBytes());
+        }
+        String gid2 = null;
+        if (node.hasChild(Tags.TAG_CTX_2)) {
+            gid2 = IccUtils.bytesToHexString(node.getChild(Tags.TAG_CTX_2).asBytes());
+        }
+        return new CarrierIdentifier(node.getChild(Tags.TAG_CTX_0).asBytes(), gid1, gid2);
+    }
+
+    @Nullable
+    private static UiccAccessRule[] buildUiccAccessRule(List<Asn1Node> nodes)
+            throws InvalidAsn1DataException, TagNotFoundException {
+        if (nodes.isEmpty()) {
+            return null;
+        }
+        int count = nodes.size();
+        UiccAccessRule[] rules = new UiccAccessRule[count];
+        for (int i = 0; i < count; i++) {
+            Asn1Node node = nodes.get(i);
+            Asn1Node refDoNode = node.getChild(Tags.TAG_REF_DO);
+            byte[] signature = refDoNode.getChild(Tags.TAG_DEVICE_APP_ID_REF_DO).asBytes();
+
+            String packageName = null;
+            if (refDoNode.hasChild(Tags.TAG_PKG_REF_DO)) {
+                packageName = refDoNode.getChild(Tags.TAG_PKG_REF_DO).asString();
+            }
+            long accessType = 0;
+            if (node.hasChild(Tags.TAG_AR_DO, Tags.TAG_PERM_AR_DO)) {
+                Asn1Node permArDoNode = node.getChild(Tags.TAG_AR_DO, Tags.TAG_PERM_AR_DO);
+                accessType = permArDoNode.asRawLong();
+            }
+            rules[i] = new UiccAccessRule(signature, packageName, accessType);
+        }
+        return rules;
+    }
+
+    /**
+     * Creates an instance from the ASN.1 data.
+     *
+     * @param node This should be either {@code NotificationMetadata} or {@code PendingNotification}
+     *     defined by SGP.22 v2.0.
+     * @throws TagNotFoundException If no notification tag is found in the bytes.
+     * @throws InvalidAsn1DataException If no valid data is found in the bytes.
+     */
+    private static EuiccNotification createNotification(Asn1Node node)
+            throws TagNotFoundException, InvalidAsn1DataException {
+        Asn1Node metadataNode;
+        if (node.getTag() == Tags.TAG_NOTIFICATION_METADATA) {
+            metadataNode = node;
+        } else if (node.getTag() == Tags.TAG_PROFILE_INSTALLATION_RESULT) {
+            metadataNode = node.getChild(Tags.TAG_PROFILE_INSTALLATION_RESULT_DATA,
+                    Tags.TAG_NOTIFICATION_METADATA);
+        } else {
+            // Other signed notification
+            metadataNode = node.getChild(Tags.TAG_NOTIFICATION_METADATA);
+        }
+        // noinspection WrongConstant
+        return new EuiccNotification(metadataNode.getChild(Tags.TAG_SEQ).asInteger(),
+                metadataNode.getChild(Tags.TAG_TARGET_ADDR).asString(),
+                metadataNode.getChild(Tags.TAG_EVENT).asBits(),
+                node.getTag() == Tags.TAG_NOTIFICATION_METADATA ? null : node.toBytes());
+    }
+
+    /** Returns the first CONTEXT [0] as an integer. */
+    private static int parseSimpleResult(byte[] response)
+            throws EuiccCardException, TagNotFoundException, InvalidAsn1DataException {
+        return parseResponse(response).getChild(Tags.TAG_CTX_0).asInteger();
+    }
+
+    private static Asn1Node parseResponse(byte[] response)
+            throws EuiccCardException, InvalidAsn1DataException {
+        Asn1Decoder decoder = new Asn1Decoder(response);
+        if (!decoder.hasNextNode()) {
+            throw new EuiccCardException("Empty response", null);
+        }
+        return decoder.nextNode();
+    }
+
+    /**
+     * Parses the bytes into an ASN1 node and check if there is an error code represented at the
+     * context 1 tag. If there is an error code, an {@link EuiccCardErrorException} will be thrown
+     * with the given operation code.
+     */
+    private static Asn1Node parseResponseAndCheckSimpleError(byte[] response,
+            @OperationCode int opCode)
+            throws EuiccCardException, InvalidAsn1DataException, TagNotFoundException {
+        Asn1Node root = parseResponse(response);
+        if (root.hasChild(Tags.TAG_CTX_1)) {
+            throw new EuiccCardErrorException(opCode, root.getChild(Tags.TAG_CTX_1).asInteger());
+        }
+        return root;
+    }
+
+    /** Strip all the trailing 'F' characters of an iccId. */
+    private static String stripTrailingFs(byte[] iccId) {
+        return IccUtils.stripTrailingFs(IccUtils.bchToString(iccId, 0, iccId.length));
+    }
+
+    /** Pad an iccId with trailing 'F' characters until the length is 20. */
+    private static String padTrailingFs(String iccId) {
+        if (!TextUtils.isEmpty(iccId) && iccId.length() < ICCID_LENGTH) {
+            iccId += new String(new char[20 - iccId.length()]).replace('\0', 'F');
+        }
+        return iccId;
+    }
+
     private static void loge(String message) {
         Rlog.e(LOG_TAG, message);
     }
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java b/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java
deleted file mode 100644
index e797107..0000000
--- a/src/java/com/android/internal/telephony/uicc/euicc/EuiccPort.java
+++ /dev/null
@@ -1,1419 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.uicc.euicc;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Handler;
-import android.service.carrier.CarrierIdentifier;
-import android.service.euicc.EuiccProfileInfo;
-import android.telephony.SubscriptionInfo;
-import android.telephony.UiccAccessRule;
-import android.telephony.euicc.EuiccCardManager;
-import android.telephony.euicc.EuiccNotification;
-import android.telephony.euicc.EuiccRulesAuthTable;
-import android.text.TextUtils;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.uicc.IccCardStatus;
-import com.android.internal.telephony.uicc.IccIoResult;
-import com.android.internal.telephony.uicc.IccUtils;
-import com.android.internal.telephony.uicc.UiccCard;
-import com.android.internal.telephony.uicc.UiccPort;
-import com.android.internal.telephony.uicc.asn1.Asn1Decoder;
-import com.android.internal.telephony.uicc.asn1.Asn1Node;
-import com.android.internal.telephony.uicc.asn1.InvalidAsn1DataException;
-import com.android.internal.telephony.uicc.asn1.TagNotFoundException;
-import com.android.internal.telephony.uicc.euicc.apdu.ApduException;
-import com.android.internal.telephony.uicc.euicc.apdu.ApduSender;
-import com.android.internal.telephony.uicc.euicc.apdu.ApduSenderResultCallback;
-import com.android.internal.telephony.uicc.euicc.apdu.RequestBuilder;
-import com.android.internal.telephony.uicc.euicc.apdu.RequestProvider;
-import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback;
-import com.android.internal.telephony.uicc.euicc.async.AsyncResultHelper;
-import com.android.telephony.Rlog;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.util.Arrays;
-import java.util.List;
-
-/**
- * This class performs profile management operations asynchronously. It includes methods defined
- * by different versions of GSMA Spec (SGP.22).
- */
-public class EuiccPort extends UiccPort {
-
-    private static final String LOG_TAG = "EuiccPort";
-    private static final boolean DBG = true;
-
-    private static final String ISD_R_AID = "A0000005591010FFFFFFFF8900000100";
-    private static final int ICCID_LENGTH = 20;
-
-    // APDU status for SIM refresh
-    private static final int APDU_ERROR_SIM_REFRESH = 0x6F00;
-
-    // These error codes are defined in GSMA SGP.22. 0 is the code for success.
-    private static final int CODE_OK = 0;
-
-    // Error code for profile not in expected state for the operation. This error includes the case
-    // that profile is not in disabled state when being enabled or deleted, and that profile is not
-    // in enabled state when being disabled.
-    private static final int CODE_PROFILE_NOT_IN_EXPECTED_STATE = 2;
-
-    // Error code for nothing to delete when resetting eUICC memory or removing notifications.
-    private static final int CODE_NOTHING_TO_DELETE = 1;
-
-    // Error code for no result available when retrieving notifications.
-    private static final int CODE_NO_RESULT_AVAILABLE = 1;
-
-    private static final EuiccSpecVersion SGP22_V_2_0 = new EuiccSpecVersion(2, 0, 0);
-    private static final EuiccSpecVersion SGP22_V_2_1 = new EuiccSpecVersion(2, 1, 0);
-
-    // Device capabilities.
-    private static final String DEV_CAP_GSM = "gsm";
-    private static final String DEV_CAP_UTRAN = "utran";
-    private static final String DEV_CAP_CDMA_1X = "cdma1x";
-    private static final String DEV_CAP_HRPD = "hrpd";
-    private static final String DEV_CAP_EHRPD = "ehrpd";
-    private static final String DEV_CAP_EUTRAN = "eutran";
-    private static final String DEV_CAP_NFC = "nfc";
-    private static final String DEV_CAP_CRL = "crl";
-    private static final String DEV_CAP_NREPC = "nrepc";
-    private static final String DEV_CAP_NR5GC = "nr5gc";
-    private static final String DEV_CAP_EUTRAN5GC = "eutran5gc";
-
-    // These interfaces are used for simplifying the code by leveraging lambdas.
-    private interface ApduRequestBuilder {
-        void build(RequestBuilder requestBuilder)
-                throws EuiccCardException, TagNotFoundException, InvalidAsn1DataException;
-    }
-
-    private interface ApduResponseHandler<T> {
-        T handleResult(byte[] response)
-                throws EuiccCardException, TagNotFoundException, InvalidAsn1DataException;
-    }
-
-    private interface ApduIntermediateResultHandler {
-        boolean shouldContinue(IccIoResult intermediateResult);
-    }
-
-    private interface ApduExceptionHandler {
-        void handleException(Throwable e);
-    }
-
-    private final ApduSender mApduSender;
-    private EuiccSpecVersion mSpecVersion;
-    private volatile String mEid;
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public boolean mIsSupportsMultipleEnabledProfiles;
-
-    public EuiccPort(Context c, CommandsInterface ci, IccCardStatus ics, int phoneId, Object lock,
-            UiccCard card, boolean isSupportsMultipleEnabledProfiles) {
-        super(c, ci, ics, phoneId, lock, card);
-        // TODO: Set supportExtendedApdu based on ATR.
-        mApduSender = new ApduSender(ci, ISD_R_AID, false /* supportExtendedApdu */);
-        if (TextUtils.isEmpty(ics.eid)) {
-            loge("no eid given in constructor for phone " + phoneId);
-        } else {
-            mEid = ics.eid;
-            mCardId = ics.eid;
-        }
-        mIsSupportsMultipleEnabledProfiles = isSupportsMultipleEnabledProfiles;
-    }
-
-    /**
-     * Gets the GSMA RSP specification version supported by this eUICC. This may return null if the
-     * version cannot be read.
-     */
-    public void getSpecVersion(AsyncResultCallback<EuiccSpecVersion> callback, Handler handler) {
-        if (mSpecVersion != null) {
-            AsyncResultHelper.returnResult(mSpecVersion, callback, handler);
-            return;
-        }
-
-        sendApdu(newRequestProvider((RequestBuilder requestBuilder) -> { /* Do nothing */ }),
-                (byte[] response) -> mSpecVersion, callback, handler);
-    }
-
-    @Override
-    public void update(Context c, CommandsInterface ci, IccCardStatus ics, UiccCard uiccCard) {
-        synchronized (mLock) {
-            if (!TextUtils.isEmpty(ics.eid)) {
-                mEid = ics.eid;
-            }
-            super.update(c, ci, ics, uiccCard);
-        }
-    }
-
-    /**
-     * Updates MEP(Multiple Enabled Profile) support flag.
-     * The flag can be updated after the port creation.
-     */
-    public void updateSupportMultipleEnabledProfile(boolean supported) {
-        logd("updateSupportMultipleEnabledProfile");
-        mIsSupportsMultipleEnabledProfiles = supported;
-    }
-
-    /**
-     * Gets a list of user-visible profiles.
-     *
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 1.1.0 [GSMA SGP.22]
-     */
-    public void getAllProfiles(AsyncResultCallback<EuiccProfileInfo[]> callback, Handler handler) {
-        byte[] profileTags = mIsSupportsMultipleEnabledProfiles ? Tags.EUICC_PROFILE_MEP_TAGS
-                : Tags.EUICC_PROFILE_TAGS;
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_PROFILES)
-                                .addChildAsBytes(Tags.TAG_TAG_LIST, profileTags)
-                                .build().toHex())),
-                response -> {
-                    List<Asn1Node> profileNodes = new Asn1Decoder(response).nextNode()
-                            .getChild(Tags.TAG_CTX_COMP_0).getChildren(Tags.TAG_PROFILE_INFO);
-                    int size = profileNodes.size();
-                    EuiccProfileInfo[] profiles = new EuiccProfileInfo[size];
-                    int profileCount = 0;
-                    for (int i = 0; i < size; i++) {
-                        Asn1Node profileNode = profileNodes.get(i);
-                        if (!profileNode.hasChild(Tags.TAG_ICCID)) {
-                            loge("Profile must have an ICCID.");
-                            continue;
-                        }
-                        String strippedIccIdString =
-                                stripTrailingFs(profileNode.getChild(Tags.TAG_ICCID).asBytes());
-                        EuiccProfileInfo.Builder profileBuilder =
-                                new EuiccProfileInfo.Builder(strippedIccIdString);
-                        buildProfile(profileNode, profileBuilder);
-
-                        EuiccProfileInfo profile = profileBuilder.build();
-                        profiles[profileCount++] = profile;
-                    }
-                    return profiles;
-                },
-                callback, handler);
-    }
-
-    /**
-     * Gets a profile.
-     *
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 1.1.0 [GSMA SGP.22]
-     */
-    public final void getProfile(String iccid, AsyncResultCallback<EuiccProfileInfo> callback,
-            Handler handler) {
-        byte[] profileTags = mIsSupportsMultipleEnabledProfiles ? Tags.EUICC_PROFILE_MEP_TAGS
-                : Tags.EUICC_PROFILE_TAGS;
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_PROFILES)
-                                .addChild(Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0)
-                                        .addChildAsBytes(Tags.TAG_ICCID,
-                                                IccUtils.bcdToBytes(padTrailingFs(iccid)))
-                                        .build())
-                                .addChildAsBytes(Tags.TAG_TAG_LIST, profileTags)
-                                .build().toHex())),
-                response -> {
-                    List<Asn1Node> profileNodes = new Asn1Decoder(response).nextNode()
-                            .getChild(Tags.TAG_CTX_COMP_0).getChildren(Tags.TAG_PROFILE_INFO);
-                    if (profileNodes.isEmpty()) {
-                        return null;
-                    }
-                    Asn1Node profileNode = profileNodes.get(0);
-                    String strippedIccIdString =
-                            stripTrailingFs(profileNode.getChild(Tags.TAG_ICCID).asBytes());
-                    EuiccProfileInfo.Builder profileBuilder =
-                            new EuiccProfileInfo.Builder(strippedIccIdString);
-                    buildProfile(profileNode, profileBuilder);
-                    return profileBuilder.build();
-                },
-                callback, handler);
-    }
-
-    /**
-     * Disables a profile of the given {@code iccid}.
-     *
-     * @param refresh Whether sending the REFRESH command to modem.
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 1.1.0 [GSMA SGP.22]
-     */
-    public void disableProfile(String iccid, boolean refresh, AsyncResultCallback<Void> callback,
-            Handler handler) {
-        sendApduWithSimResetErrorWorkaround(
-                newRequestProvider((RequestBuilder requestBuilder) -> {
-                    byte[] iccidBytes = IccUtils.bcdToBytes(padTrailingFs(iccid));
-                    requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_DISABLE_PROFILE)
-                            .addChild(Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0)
-                                    .addChildAsBytes(Tags.TAG_ICCID, iccidBytes))
-                            .addChildAsBoolean(Tags.TAG_CTX_1, refresh)
-                            .build().toHex());
-                }),
-                response -> {
-                    int result;
-                    // SGP.22 v2.0 DisableProfileResponse
-                    result = parseSimpleResult(response);
-                    switch (result) {
-                        case CODE_OK:
-                            return null;
-                        case CODE_PROFILE_NOT_IN_EXPECTED_STATE:
-                            logd("Profile is already disabled, iccid: "
-                                    + SubscriptionInfo.givePrintableIccid(iccid));
-                            return null;
-                        default:
-                            throw new EuiccCardErrorException(
-                                    EuiccCardErrorException.OPERATION_DISABLE_PROFILE, result);
-                    }
-                },
-                callback, handler);
-    }
-
-    /**
-     * Switches from the current profile to another profile. The current profile will be disabled
-     * and the specified profile will be enabled.
-     *
-     * @param refresh Whether sending the REFRESH command to modem.
-     * @param callback The callback to get the EuiccProfile enabled.
-     * @param handler The handler to run the callback.
-     * @since 1.1.0 [GSMA SGP.22]
-     */
-    public void switchToProfile(String iccid, boolean refresh, AsyncResultCallback<Void> callback,
-            Handler handler) {
-        sendApduWithSimResetErrorWorkaround(
-                newRequestProvider((RequestBuilder requestBuilder) -> {
-                    byte[] iccidBytes = IccUtils.bcdToBytes(padTrailingFs(iccid));
-                    requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_ENABLE_PROFILE)
-                            .addChild(Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0)
-                                    .addChildAsBytes(Tags.TAG_ICCID, iccidBytes))
-                            .addChildAsBoolean(Tags.TAG_CTX_1, refresh)
-                            .build().toHex());
-                }),
-                response -> {
-                    int result;
-                    // SGP.22 v2.0 EnableProfileResponse
-                    result = parseSimpleResult(response);
-                    switch (result) {
-                        case CODE_OK:
-                            return null;
-                        case CODE_PROFILE_NOT_IN_EXPECTED_STATE:
-                            logd("Profile is already enabled, iccid: "
-                                    + SubscriptionInfo.givePrintableIccid(iccid));
-                            return null;
-                        default:
-                            throw new EuiccCardErrorException(
-                                    EuiccCardErrorException.OPERATION_SWITCH_TO_PROFILE, result);
-                    }
-                },
-                callback, handler);
-    }
-
-    /**
-     * Gets the EID synchronously.
-     * @return The EID string. Returns null if it is not ready yet.
-     */
-    public String getEid() {
-        return mEid;
-    }
-
-    /**
-     * Gets the EID of the eUICC and overwrites mCardId in UiccCard.
-     *
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 1.1.0 [GSMA SGP.22]
-     */
-    public void getEid(AsyncResultCallback<String> callback, Handler handler) {
-        if (mEid != null) {
-            AsyncResultHelper.returnResult(mEid, callback, handler);
-            return;
-        }
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_EID)
-                                .addChildAsBytes(Tags.TAG_TAG_LIST, new byte[] {Tags.TAG_EID})
-                                .build().toHex())),
-                response -> {
-                    String eid = IccUtils.bytesToHexString(parseResponse(response)
-                            .getChild(Tags.TAG_EID).asBytes());
-                    synchronized (mLock) {
-                        mEid = eid;
-                        mCardId = eid;
-                    }
-                    return eid;
-                },
-                callback, handler);
-    }
-
-    /**
-     * Sets the nickname of a profile.
-     *
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 1.1.0 [GSMA SGP.22]
-     */
-    public void setNickname(String iccid, String nickname, AsyncResultCallback<Void> callback,
-            Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_SET_NICKNAME)
-                                .addChildAsBytes(Tags.TAG_ICCID,
-                                        IccUtils.bcdToBytes(padTrailingFs(iccid)))
-                                .addChildAsString(Tags.TAG_NICKNAME, nickname)
-                                .build().toHex())),
-                response -> {
-                    // SGP.22 v2.0 SetNicknameResponse
-                    int result = parseSimpleResult(response);
-                    if (result != CODE_OK) {
-                        throw new EuiccCardErrorException(
-                                EuiccCardErrorException.OPERATION_SET_NICKNAME, result);
-                    }
-                    return null;
-                },
-                callback, handler);
-    }
-
-    /**
-     * Deletes a profile from eUICC.
-     *
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 1.1.0 [GSMA SGP.22]
-     */
-    public void deleteProfile(String iccid, AsyncResultCallback<Void> callback, Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) -> {
-                    byte[] iccidBytes = IccUtils.bcdToBytes(padTrailingFs(iccid));
-                    requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_DELETE_PROFILE)
-                            .addChildAsBytes(Tags.TAG_ICCID, iccidBytes)
-                            .build().toHex());
-                }),
-                response -> {
-                    // SGP.22 v2.0 DeleteProfileRequest
-                    int result = parseSimpleResult(response);
-                    if (result != CODE_OK) {
-                        throw new EuiccCardErrorException(
-                                EuiccCardErrorException.OPERATION_DELETE_PROFILE, result);
-                    }
-                    return null;
-                },
-                callback, handler);
-    }
-
-    /**
-     * Resets the eUICC memory (e.g., remove all profiles).
-     *
-     * @param options Bits of the options of resetting which parts of the eUICC memory.
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 1.1.0 [GSMA SGP.22]
-     */
-    public void resetMemory(@EuiccCardManager.ResetOption int options,
-            AsyncResultCallback<Void> callback, Handler handler) {
-        sendApduWithSimResetErrorWorkaround(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_EUICC_MEMORY_RESET)
-                                .addChildAsBits(Tags.TAG_CTX_2, options)
-                                .build().toHex())),
-                response -> {
-                    int result = parseSimpleResult(response);
-                    if (result != CODE_OK && result != CODE_NOTHING_TO_DELETE) {
-                        throw new EuiccCardErrorException(
-                                EuiccCardErrorException.OPERATION_RESET_MEMORY, result);
-                    }
-                    return null;
-                },
-                callback, handler);
-    }
-
-    /**
-     * Gets the default SM-DP+ address from eUICC.
-     *
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void getDefaultSmdpAddress(AsyncResultCallback<String> callback, Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(
-                                Asn1Node.newBuilder(Tags.TAG_GET_CONFIGURED_ADDRESSES)
-                                        .build().toHex())),
-                (byte[] response) -> parseResponse(response).getChild(Tags.TAG_CTX_0).asString(),
-                callback, handler);
-    }
-
-    /**
-     * Gets the SM-DS address from eUICC.
-     *
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void getSmdsAddress(AsyncResultCallback<String> callback, Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(
-                                Asn1Node.newBuilder(Tags.TAG_GET_CONFIGURED_ADDRESSES)
-                                        .build().toHex())),
-                (byte[] response) -> parseResponse(response).getChild(Tags.TAG_CTX_1).asString(),
-                callback, handler);
-    }
-
-    /**
-     * Sets the default SM-DP+ address of eUICC.
-     *
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void setDefaultSmdpAddress(String defaultSmdpAddress, AsyncResultCallback<Void> callback,
-            Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(
-                                Asn1Node.newBuilder(Tags.TAG_SET_DEFAULT_SMDP_ADDRESS)
-                                        .addChildAsString(Tags.TAG_CTX_0, defaultSmdpAddress)
-                                        .build().toHex())),
-                response -> {
-                    // SGP.22 v2.0 SetDefaultDpAddressResponse
-                    int result = parseSimpleResult(response);
-                    if (result != CODE_OK) {
-                        throw new EuiccCardErrorException(
-                                EuiccCardErrorException.OPERATION_SET_DEFAULT_SMDP_ADDRESS, result);
-                    }
-                    return null;
-                },
-                callback, handler);
-    }
-
-    /**
-     * Gets Rules Authorisation Table.
-     *
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void getRulesAuthTable(AsyncResultCallback<EuiccRulesAuthTable> callback,
-            Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_RAT)
-                                .build().toHex())),
-                response -> {
-                    Asn1Node root = parseResponse(response);
-                    List<Asn1Node> nodes = root.getChildren(Tags.TAG_CTX_COMP_0);
-                    EuiccRulesAuthTable.Builder builder =
-                            new EuiccRulesAuthTable.Builder(nodes.size());
-                    int size = nodes.size();
-                    for (int i = 0; i < size; i++) {
-                        Asn1Node node = nodes.get(i);
-                        List<Asn1Node> opIdNodes =
-                                node.getChild(Tags.TAG_SEQUENCE, Tags.TAG_CTX_COMP_1).getChildren();
-                        int opIdSize = opIdNodes.size();
-                        CarrierIdentifier[] opIds = new CarrierIdentifier[opIdSize];
-                        for (int j = 0; j < opIdSize; j++) {
-                            opIds[j] = buildCarrierIdentifier(opIdNodes.get(j));
-                        }
-                        builder.add(node.getChild(Tags.TAG_SEQUENCE, Tags.TAG_CTX_0).asBits(),
-                                Arrays.asList(opIds), node.getChild(Tags.TAG_SEQUENCE,
-                                        Tags.TAG_CTX_2).asBits());
-                    }
-                    return builder.build();
-                },
-                callback, handler);
-    }
-
-    /**
-     * Gets the eUICC challenge for new profile downloading.
-     *
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void getEuiccChallenge(AsyncResultCallback<byte[]> callback, Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(
-                                Asn1Node.newBuilder(Tags.TAG_GET_EUICC_CHALLENGE)
-                                        .build().toHex())),
-                (byte[] response) -> parseResponse(response).getChild(Tags.TAG_CTX_0).asBytes(),
-                callback, handler);
-    }
-
-    /**
-     * Gets the eUICC info1 for new profile downloading.
-     *
-     * @param callback The callback to get the result, which represents an {@code EUICCInfo1}
-     *     defined in GSMA RSP v2.0+.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void getEuiccInfo1(AsyncResultCallback<byte[]> callback, Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_EUICC_INFO_1)
-                                .build().toHex())),
-                (response) -> response,
-                callback, handler);
-    }
-
-    /**
-     * Gets the eUICC info2 for new profile downloading.
-     *
-     * @param callback The callback to get the result, which represents an {@code EUICCInfo2}
-     *     defined in GSMA RSP v2.0+.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void getEuiccInfo2(AsyncResultCallback<byte[]> callback, Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_GET_EUICC_INFO_2)
-                                .build().toHex())),
-                (response) -> response,
-                callback, handler);
-    }
-
-    /**
-     * Authenticates the SM-DP+ server by the eUICC. The parameters {@code serverSigned1}, {@code
-     * serverSignature1}, {@code euiccCiPkIdToBeUsed}, and {@code serverCertificate} are the ASN.1
-     * data returned by SM-DP+ server.
-     *
-     * @param matchingId The activation code or an empty string.
-     * @param callback The callback to get the result, which represents an {@code
-     *     AuthenticateServerResponse} defined in GSMA RSP v2.0+.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void authenticateServer(String matchingId, byte[] serverSigned1, byte[] serverSignature1,
-            byte[] euiccCiPkIdToBeUsed, byte[] serverCertificate,
-            AsyncResultCallback<byte[]> callback, Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) -> {
-                    byte[] imeiBytes = getDeviceId();
-                    // TAC is the first 8 digits (4 bytes) of IMEI.
-                    byte[] tacBytes = new byte[4];
-                    System.arraycopy(imeiBytes, 0, tacBytes, 0, 4);
-
-                    Asn1Node.Builder devCapsBuilder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1);
-                    String[] devCapsStrings = getResources().getStringArray(
-                            com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities);
-                    if (devCapsStrings != null) {
-                        for (String devCapItem : devCapsStrings) {
-                            addDeviceCapability(devCapsBuilder, devCapItem);
-                        }
-                    } else {
-                        if (DBG) logd("No device capabilities set.");
-                    }
-
-                    Asn1Node.Builder ctxParams1Builder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0)
-                            .addChildAsString(Tags.TAG_CTX_0, matchingId)
-                            .addChild(Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1)
-                                    .addChildAsBytes(Tags.TAG_CTX_0, tacBytes)
-                                    .addChild(devCapsBuilder)
-                                    .addChildAsBytes(Tags.TAG_CTX_2, imeiBytes));
-
-                    requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_AUTHENTICATE_SERVER)
-                            .addChild(new Asn1Decoder(serverSigned1).nextNode())
-                            .addChild(new Asn1Decoder(serverSignature1).nextNode())
-                            .addChild(new Asn1Decoder(euiccCiPkIdToBeUsed).nextNode())
-                            .addChild(new Asn1Decoder(serverCertificate).nextNode())
-                            .addChild(ctxParams1Builder)
-                            .build().toHex());
-                }),
-                response -> {
-                    Asn1Node root = parseResponse(response);
-                    if (root.hasChild(Tags.TAG_CTX_COMP_1, Tags.TAG_UNI_2)) {
-                        throw new EuiccCardErrorException(
-                                EuiccCardErrorException.OPERATION_AUTHENTICATE_SERVER,
-                                root.getChild(Tags.TAG_CTX_COMP_1, Tags.TAG_UNI_2).asInteger());
-                    }
-                    return root.toBytes();
-                },
-                callback, handler);
-    }
-
-    /**
-     * Prepares the profile download request sent to SM-DP+. The parameters {@code smdpSigned2},
-     * {@code smdpSignature2}, and {@code smdpCertificate} are the ASN.1 data returned by SM-DP+
-     * server.
-     *
-     * @param hashCc The hash of confirmation code. It can be null if there is no confirmation code
-     *     required.
-     * @param callback The callback to get the result, which represents an {@code
-     *     PrepareDownloadResponse} defined in GSMA RSP v2.0+.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void prepareDownload(@Nullable byte[] hashCc, byte[] smdpSigned2, byte[] smdpSignature2,
-            byte[] smdpCertificate, AsyncResultCallback<byte[]> callback, Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) -> {
-                    Asn1Node.Builder builder = Asn1Node.newBuilder(Tags.TAG_PREPARE_DOWNLOAD)
-                            .addChild(new Asn1Decoder(smdpSigned2).nextNode())
-                            .addChild(new Asn1Decoder(smdpSignature2).nextNode());
-                    if (hashCc != null) {
-                        builder.addChildAsBytes(Tags.TAG_UNI_4, hashCc);
-                    }
-                    requestBuilder.addStoreData(
-                            builder.addChild(new Asn1Decoder(smdpCertificate).nextNode())
-                                    .build().toHex());
-                }),
-                response -> {
-                    Asn1Node root = parseResponse(response);
-                    if (root.hasChild(Tags.TAG_CTX_COMP_1, Tags.TAG_UNI_2)) {
-                        throw new EuiccCardErrorException(
-                                EuiccCardErrorException.OPERATION_PREPARE_DOWNLOAD,
-                                root.getChild(Tags.TAG_CTX_COMP_1, Tags.TAG_UNI_2).asInteger());
-                    }
-                    return root.toBytes();
-                },
-                callback, handler);
-    }
-
-    /**
-     * Loads a downloaded bound profile package onto the eUICC.
-     *
-     * @param boundProfilePackage The Bound Profile Package data returned by SM-DP+ server.
-     * @param callback The callback to get the result, which represents an {@code
-     *     LoadBoundProfilePackageResponse} defined in GSMA RSP v2.0+.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void loadBoundProfilePackage(byte[] boundProfilePackage,
-            AsyncResultCallback<byte[]> callback, Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) -> {
-                    Asn1Node bppNode = new Asn1Decoder(boundProfilePackage).nextNode();
-                    int actualLength = bppNode.getDataLength();
-                    int segmentedLength = 0;
-                    // initialiseSecureChannelRequest (ES8+.InitialiseSecureChannel)
-                    Asn1Node initialiseSecureChannelRequest = bppNode.getChild(
-                            Tags.TAG_INITIALISE_SECURE_CHANNEL);
-                    segmentedLength += initialiseSecureChannelRequest.getEncodedLength();
-                    // firstSequenceOf87 (ES8+.ConfigureISDP)
-                    Asn1Node firstSequenceOf87 = bppNode.getChild(Tags.TAG_CTX_COMP_0);
-                    segmentedLength += firstSequenceOf87.getEncodedLength();
-                    // sequenceOf88 (ES8+.StoreMetadata)
-                    Asn1Node sequenceOf88 = bppNode.getChild(Tags.TAG_CTX_COMP_1);
-                    List<Asn1Node> metaDataSeqs = sequenceOf88.getChildren(Tags.TAG_CTX_8);
-                    segmentedLength += sequenceOf88.getEncodedLength();
-                    // secondSequenceOf87 (ES8+.ReplaceSessionKeys), optional
-                    Asn1Node secondSequenceOf87 = null;
-                    if (bppNode.hasChild(Tags.TAG_CTX_COMP_2)) {
-                        secondSequenceOf87 = bppNode.getChild(Tags.TAG_CTX_COMP_2);
-                        segmentedLength += secondSequenceOf87.getEncodedLength();
-                    }
-                    // sequenceOf86 (ES8+.LoadProfileElements)
-                    Asn1Node sequenceOf86 = bppNode.getChild(Tags.TAG_CTX_COMP_3);
-                    List<Asn1Node> elementSeqs = sequenceOf86.getChildren(Tags.TAG_CTX_6);
-                    segmentedLength += sequenceOf86.getEncodedLength();
-
-                    if (mSpecVersion.compareTo(SGP22_V_2_1) >= 0) {
-                        // Per SGP.22 v2.1+ section 2.5.5, it's the LPA's job to "segment" the BPP
-                        // before sending it to the eUICC. This check was only instituted in SGP.22
-                        // v2.1 and higher. SGP.22 v2.0 doesn't mention this "segmentation" process
-                        // at all, or what the LPA should do in the case of unrecognized or missing
-                        // tags. Per section 3.1.3.3: "If the LPAd is unable to perform the
-                        // segmentation (e.g., because of an error in the BPP structure), ... the
-                        // LPAd SHALL perform the Sub-procedure "Profile Download and installation -
-                        // Download rejection" with reason code 'Load BPP execution error'." This
-                        // implies that if we detect an invalid BPP, we should short-circuit before
-                        // sending anything to the eUICC. There are two cases to account for:
-                        if (elementSeqs == null || elementSeqs.isEmpty()) {
-                            // 1. The BPP is missing a required tag. Upon calling bppNode.getChild,
-                            // an exception will occur if the expected tag is missing, though we
-                            // should make sure that the sequences are non-empty when appropriate as
-                            // well. A profile with no profile elements is invalid. This is
-                            // explicitly tested by SGP.23 case 4.4.25.2.1_03.
-                            throw new EuiccCardException("No profile elements in BPP");
-                        } else if (actualLength != segmentedLength) {
-                            // 2. The BPP came with extraneous tags other than what the spec
-                            // mandates. We keep track of the total length of the BPP and compare it
-                            // to the length of the segments we care about. If they're different,
-                            // we'll throw an exception to indicate this. This is explicitly tested
-                            // by SGP.23 case 4.4.25.2.1_05.
-                            throw new EuiccCardException(
-                                    "Actual BPP length ("
-                                            + actualLength
-                                            + ") does not match segmented length ("
-                                            + segmentedLength
-                                            + "), this must be due to a malformed BPP");
-                        }
-                    }
-
-                    requestBuilder.addStoreData(bppNode.getHeadAsHex()
-                            + initialiseSecureChannelRequest.toHex());
-
-                    requestBuilder.addStoreData(firstSequenceOf87.toHex());
-
-                    requestBuilder.addStoreData(sequenceOf88.getHeadAsHex());
-                    int size = metaDataSeqs.size();
-                    for (int i = 0; i < size; i++) {
-                        requestBuilder.addStoreData(metaDataSeqs.get(i).toHex());
-                    }
-
-                    if (secondSequenceOf87 != null) {
-                        requestBuilder.addStoreData(secondSequenceOf87.toHex());
-                    }
-
-                    requestBuilder.addStoreData(sequenceOf86.getHeadAsHex());
-                    size = elementSeqs.size();
-                    for (int i = 0; i < size; i++) {
-                        requestBuilder.addStoreData(elementSeqs.get(i).toHex());
-                    }
-                }),
-                response -> {
-                    // SGP.22 v2.0 ErrorResult
-                    Asn1Node root = parseResponse(response);
-                    if (root.hasChild(Tags.TAG_PROFILE_INSTALLATION_RESULT_DATA,
-                            Tags.TAG_CTX_COMP_2, Tags.TAG_CTX_COMP_1, Tags.TAG_CTX_1)) {
-                        Asn1Node errorNode = root.getChild(
-                                Tags.TAG_PROFILE_INSTALLATION_RESULT_DATA, Tags.TAG_CTX_COMP_2,
-                                Tags.TAG_CTX_COMP_1, Tags.TAG_CTX_1);
-                        throw new EuiccCardErrorException(
-                                EuiccCardErrorException.OPERATION_LOAD_BOUND_PROFILE_PACKAGE,
-                                errorNode.asInteger(), errorNode);
-                    }
-                    return root.toBytes();
-                },
-                intermediateResult -> {
-                    byte[] payload = intermediateResult.payload;
-                    if (payload != null && payload.length > 2) {
-                        int tag = (payload[0] & 0xFF) << 8 | (payload[1] & 0xFF);
-                        // Stops if the installation result has been returned
-                        if (tag == Tags.TAG_PROFILE_INSTALLATION_RESULT) {
-                            logd("loadBoundProfilePackage failed due to an early error.");
-                            return false;
-                        }
-                    }
-                    return true;
-                },
-                callback, handler);
-    }
-
-    /**
-     * Cancels the current profile download session.
-     *
-     * @param transactionId The transaction ID returned by SM-DP+ server.
-     * @param callback The callback to get the result, which represents an {@code
-     *     CancelSessionResponse} defined in GSMA RSP v2.0+.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void cancelSession(byte[] transactionId, @EuiccCardManager.CancelReason int reason,
-            AsyncResultCallback<byte[]> callback, Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_CANCEL_SESSION)
-                                .addChildAsBytes(Tags.TAG_CTX_0, transactionId)
-                                .addChildAsInteger(Tags.TAG_CTX_1, reason)
-                                .build().toHex())),
-                (byte[] response) ->
-                        parseResponseAndCheckSimpleError(response,
-                                EuiccCardErrorException.OPERATION_CANCEL_SESSION).toBytes(),
-                callback, handler);
-    }
-
-    /**
-     * Lists all notifications of the given {@code notificationEvents}.
-     *
-     * @param events Bits of the event types ({@link EuiccNotification.Event}) to list.
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void listNotifications(@EuiccNotification.Event int events,
-            AsyncResultCallback<EuiccNotification[]> callback, Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(Asn1Node.newBuilder(Tags.TAG_LIST_NOTIFICATION)
-                                .addChildAsBits(Tags.TAG_CTX_1, events)
-                                .build().toHex())),
-                response -> {
-                    Asn1Node root = parseResponseAndCheckSimpleError(response,
-                            EuiccCardErrorException.OPERATION_LIST_NOTIFICATIONS);
-                    List<Asn1Node> nodes = root.getChild(Tags.TAG_CTX_COMP_0).getChildren();
-                    EuiccNotification[] notifications = new EuiccNotification[nodes.size()];
-                    for (int i = 0; i < notifications.length; ++i) {
-                        notifications[i] = createNotification(nodes.get(i));
-                    }
-                    return notifications;
-                },
-                callback, handler);
-    }
-
-    /**
-     * Retrieves contents of all notification of the given {@code events}.
-     *
-     * @param events Bits of the event types ({@link EuiccNotification.Event}) to list.
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void retrieveNotificationList(@EuiccNotification.Event int events,
-            AsyncResultCallback<EuiccNotification[]> callback, Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(
-                                Asn1Node.newBuilder(Tags.TAG_RETRIEVE_NOTIFICATIONS_LIST)
-                                        .addChild(Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0)
-                                                .addChildAsBits(Tags.TAG_CTX_1, events))
-                                        .build().toHex())),
-                response -> {
-                    Asn1Node root = parseResponse(response);
-                    if (root.hasChild(Tags.TAG_CTX_1)) {
-                        // SGP.22 v2.0 RetrieveNotificationsListResponse
-                        int error = root.getChild(Tags.TAG_CTX_1).asInteger();
-                        switch (error) {
-                            case CODE_NO_RESULT_AVAILABLE:
-                                return new EuiccNotification[0];
-                            default:
-                                throw new EuiccCardErrorException(
-                                        EuiccCardErrorException.OPERATION_RETRIEVE_NOTIFICATION,
-                                        error);
-                        }
-                    }
-                    List<Asn1Node> nodes = root.getChild(Tags.TAG_CTX_COMP_0).getChildren();
-                    EuiccNotification[] notifications = new EuiccNotification[nodes.size()];
-                    for (int i = 0; i < notifications.length; ++i) {
-                        notifications[i] = createNotification(nodes.get(i));
-                    }
-                    return notifications;
-                },
-                callback, handler);
-    }
-
-    /**
-     * Retrieves the content of a notification of the given {@code seqNumber}.
-     *
-     * @param seqNumber The sequence number of the notification.
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void retrieveNotification(int seqNumber, AsyncResultCallback<EuiccNotification> callback,
-            Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(
-                                Asn1Node.newBuilder(Tags.TAG_RETRIEVE_NOTIFICATIONS_LIST)
-                                        .addChild(Asn1Node.newBuilder(Tags.TAG_CTX_COMP_0)
-                                                .addChildAsInteger(Tags.TAG_CTX_0, seqNumber))
-                                        .build().toHex())),
-                response -> {
-                    Asn1Node root = parseResponseAndCheckSimpleError(response,
-                            EuiccCardErrorException.OPERATION_RETRIEVE_NOTIFICATION);
-                    List<Asn1Node> nodes = root.getChild(Tags.TAG_CTX_COMP_0).getChildren();
-                    if (nodes.size() > 0) {
-                        return createNotification(nodes.get(0));
-                    }
-                    return null;
-                },
-                callback, handler);
-    }
-
-    /**
-     * Removes a notification from eUICC.
-     *
-     * @param seqNumber The sequence number of the notification.
-     * @param callback The callback to get the result.
-     * @param handler The handler to run the callback.
-     * @since 2.0.0 [GSMA SGP.22]
-     */
-    public void removeNotificationFromList(int seqNumber, AsyncResultCallback<Void> callback,
-            Handler handler) {
-        sendApdu(
-                newRequestProvider((RequestBuilder requestBuilder) ->
-                        requestBuilder.addStoreData(
-                                Asn1Node.newBuilder(Tags.TAG_REMOVE_NOTIFICATION_FROM_LIST)
-                                        .addChildAsInteger(Tags.TAG_CTX_0, seqNumber)
-                                        .build().toHex())),
-                response -> {
-                    // SGP.22 v2.0 NotificationSentResponse
-                    int result = parseSimpleResult(response);
-                    if (result != CODE_OK && result != CODE_NOTHING_TO_DELETE) {
-                        throw new EuiccCardErrorException(
-                                EuiccCardErrorException.OPERATION_REMOVE_NOTIFICATION_FROM_LIST,
-                                result);
-                    }
-                    return null;
-                },
-                callback, handler);
-    }
-
-    /**
-     * Sets a device capability version as the child of the given device capability ASN1 node
-     * builder.
-     *
-     * @param devCapBuilder The ASN1 node builder to modify.
-     * @param devCapItem The device capability and its supported version in pair.
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public void addDeviceCapability(Asn1Node.Builder devCapBuilder, String devCapItem) {
-        String[] split = devCapItem.split(",");
-        if (split.length != 2) {
-            loge("Invalid device capability item: " + Arrays.toString(split));
-            return;
-        }
-
-        String devCap = split[0].trim();
-        Integer version;
-        try {
-            version = Integer.parseInt(split[1].trim());
-        } catch (NumberFormatException e) {
-            loge("Invalid device capability version number.", e);
-            return;
-        }
-
-        byte[] versionBytes = new byte[] { version.byteValue(), 0, 0 };
-        switch (devCap) {
-            case DEV_CAP_GSM:
-                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_0, versionBytes);
-                break;
-            case DEV_CAP_UTRAN:
-                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_1, versionBytes);
-                break;
-            case DEV_CAP_CDMA_1X:
-                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_2, versionBytes);
-                break;
-            case DEV_CAP_HRPD:
-                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_3, versionBytes);
-                break;
-            case DEV_CAP_EHRPD:
-                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_4, versionBytes);
-                break;
-            case DEV_CAP_EUTRAN:
-                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_5, versionBytes);
-                break;
-            case DEV_CAP_NFC:
-                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_6, versionBytes);
-                break;
-            case DEV_CAP_CRL:
-                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_7, versionBytes);
-                break;
-            case DEV_CAP_NREPC:
-                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_8, versionBytes);
-                break;
-            case DEV_CAP_NR5GC:
-                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_9, versionBytes);
-                break;
-            case DEV_CAP_EUTRAN5GC:
-                devCapBuilder.addChildAsBytes(Tags.TAG_CTX_10, versionBytes);
-                break;
-            default:
-                loge("Invalid device capability name: " + devCap);
-                break;
-        }
-    }
-
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    protected byte[] getDeviceId() {
-        Phone phone = PhoneFactory.getPhone(getPhoneId());
-        if (phone == null) {
-            return new byte[8];
-        }
-        return getDeviceId(phone.getDeviceId(), mSpecVersion);
-    }
-
-    /**
-     * Different versions of SGP.22 specify different encodings of the device's IMEI, so we handle
-     * those differences here.
-     *
-     * @param imei The IMEI of the device. Assumed to be 15 decimal digits.
-     * @param specVersion The SGP.22 version which we're encoding the IMEI for.
-     * @return A byte string representing the given IMEI according to the specified SGP.22 version.
-     */
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    public static byte[] getDeviceId(String imei, EuiccSpecVersion specVersion) {
-        byte[] imeiBytes = new byte[8];
-        // The IMEI's encoding is version-dependent.
-        if (specVersion.compareTo(SGP22_V_2_1) >= 0) {
-            /*
-             * In SGP.22 v2.1, a clarification was added to clause 4.2 that requires the nibbles of
-             * the last byte to be swapped from normal TBCD encoding (so put back in normal order):
-             *
-             * The IMEI (including the check digit) SHALL be represented as a string of 8 octets
-             * that is coded as a Telephony Binary Coded Decimal String as defined in 3GPP TS 29.002
-             * [63], except that the last octet contains the check digit (in high nibble) and an 'F'
-             * filler (in low nibble). It SHOULD be present if the Device contains a non-removable
-             * eUICC.
-             *
-             * 3GPP TS 29.002 clause 17.7.8 in turn says this:
-             *
-             * TBCD-STRING ::= OCTET STRING
-             * This type (Telephony Binary Coded Decimal String) is used to represent several digits
-             * from 0 through 9, *, #, a, b, c, two digits per octet, each digit encoded 0000 to
-             * 1001 (0 to 9), 1010 (*), 1011 (#), 1100 (a), 1101 (b) or 1110 (c); 1111 used as
-             * filler when there is an odd number of digits.
-             * Bits 8765 of octet n encoding digit 2n
-             * Bits 4321 of octet n encoding digit 2(n-1) + 1
-             */
-            // Since the IMEI is always just decimal digits, we can still use BCD encoding (which
-            // correctly swaps digit ordering within bytes), but we have to manually pad a 0xF value
-            // instead of 0.
-            imei += 'F';
-            IccUtils.bcdToBytes(imei, imeiBytes);
-            // And now the funky last byte flip (this is not normal TBCD, the GSMA added it on top
-            // just for the IMEI for some reason). Bitwise operations promote to int first, so we
-            // have to do some extra masking.
-            byte last = imeiBytes[7];
-            imeiBytes[7] = (byte) ((last & 0xFF) << 4 | ((last & 0xFF) >>> 4));
-        } else {
-            /*
-             * Prior to SGP.22 v2.1, clause 4.2 reads as follows:
-             *
-             * The IMEI (including the check digit) SHALL be represented as a string of 8 octets
-             * that is BCD coded as defined in 3GPP TS 23.003 [35]. It SHOULD be present if the
-             * Device contains a non-removable eUICC.
-             *
-             * It appears that 3GPP TS 23.003 doesn't define anything about BCD encoding, it just
-             * defines what IMEI and a few other telephony identifiers are. We default to normal BCD
-             * encoding since the spec is unclear here.
-             */
-            IccUtils.bcdToBytes(imei, imeiBytes);
-        }
-        return imeiBytes;
-    }
-
-    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
-    protected Resources getResources()  {
-        return Resources.getSystem();
-    }
-
-    private RequestProvider newRequestProvider(ApduRequestBuilder builder) {
-        return (selectResponse, requestBuilder) -> {
-            EuiccSpecVersion ver = getOrExtractSpecVersion(selectResponse);
-            if (ver == null) {
-                throw new EuiccCardException("Cannot get eUICC spec version.");
-            }
-            try {
-                if (ver.compareTo(SGP22_V_2_0) < 0) {
-                    throw new EuiccCardException("eUICC spec version is unsupported: " + ver);
-                }
-                builder.build(requestBuilder);
-            } catch (InvalidAsn1DataException | TagNotFoundException e) {
-                throw new EuiccCardException("Cannot parse ASN1 to build request.", e);
-            }
-        };
-    }
-
-    private EuiccSpecVersion getOrExtractSpecVersion(byte[] selectResponse) {
-        // Uses the cached version.
-        if (mSpecVersion != null) {
-            return mSpecVersion;
-        }
-        // Parses and caches the version.
-        EuiccSpecVersion ver = EuiccSpecVersion.fromOpenChannelResponse(selectResponse);
-        if (ver != null) {
-            synchronized (mLock) {
-                if (mSpecVersion == null) {
-                    mSpecVersion = ver;
-                }
-            }
-        }
-        return ver;
-    }
-
-    /**
-     * A wrapper on {@link ApduSender#send(RequestProvider, ApduSenderResultCallback, Handler)} to
-     * leverage lambda to simplify the sending APDU code.EuiccCardErrorException.
-     *
-     * @param requestBuilder Builds the request of APDU commands.
-     * @param responseHandler Converts the APDU response from bytes to expected result.
-     * @param <T> Type of the originally expected result.
-     */
-    private <T> void sendApdu(RequestProvider requestBuilder,
-            ApduResponseHandler<T> responseHandler, AsyncResultCallback<T> callback,
-            Handler handler) {
-        sendApdu(requestBuilder, responseHandler,
-                (e) -> callback.onException(new EuiccCardException("Cannot send APDU.", e)),
-                null, callback, handler);
-    }
-
-    private <T> void sendApdu(RequestProvider requestBuilder,
-            ApduResponseHandler<T> responseHandler,
-            ApduIntermediateResultHandler intermediateResultHandler,
-            AsyncResultCallback<T> callback, Handler handler) {
-        sendApdu(requestBuilder, responseHandler,
-                (e) -> callback.onException(new EuiccCardException("Cannot send APDU.", e)),
-                intermediateResultHandler, callback, handler);
-    }
-
-    /**
-     * This is a workaround solution to the bug that a SIM refresh may interrupt the modem to return
-     * the reset of responses of the original APDU command. This applies to disable profile, switch
-     * profile, and reset eUICC memory.
-     *
-     * <p>TODO: Use
-     * {@link #sendApdu(RequestProvider, ApduResponseHandler, AsyncResultCallback, Handler)} when
-     * this workaround is not needed.
-     */
-    private void sendApduWithSimResetErrorWorkaround(
-            RequestProvider requestBuilder, ApduResponseHandler<Void> responseHandler,
-            AsyncResultCallback<Void> callback, Handler handler) {
-        sendApdu(requestBuilder, responseHandler, (e) -> {
-            if (e instanceof ApduException
-                    && ((ApduException) e).getApduStatus() == APDU_ERROR_SIM_REFRESH) {
-                logi("Sim is refreshed after disabling profile, no response got.");
-                callback.onResult(null);
-            } else {
-                callback.onException(new EuiccCardException("Cannot send APDU.", e));
-            }
-        }, null, callback, handler);
-    }
-
-    private <T> void sendApdu(RequestProvider requestBuilder,
-            ApduResponseHandler<T> responseHandler,
-            ApduExceptionHandler exceptionHandler,
-            @Nullable ApduIntermediateResultHandler intermediateResultHandler,
-            AsyncResultCallback<T> callback,
-            Handler handler) {
-        mApduSender.send(requestBuilder, new ApduSenderResultCallback() {
-            @Override
-            public void onResult(byte[] response) {
-                try {
-                    callback.onResult(responseHandler.handleResult(response));
-                } catch (EuiccCardException e) {
-                    callback.onException(e);
-                } catch (InvalidAsn1DataException | TagNotFoundException e) {
-                    callback.onException(new EuiccCardException(
-                            "Cannot parse response: " + IccUtils.bytesToHexString(response), e));
-                }
-            }
-
-            @Override
-            public boolean shouldContinueOnIntermediateResult(IccIoResult result) {
-                if (intermediateResultHandler == null) {
-                    return true;
-                }
-                return intermediateResultHandler.shouldContinue(result);
-            }
-
-            @Override
-            public void onException(Throwable e) {
-                exceptionHandler.handleException(e);
-            }
-        }, handler);
-    }
-
-    private static void buildProfile(Asn1Node profileNode, EuiccProfileInfo.Builder profileBuilder)
-            throws TagNotFoundException, InvalidAsn1DataException {
-        if (profileNode.hasChild(Tags.TAG_NICKNAME)) {
-            profileBuilder.setNickname(profileNode.getChild(Tags.TAG_NICKNAME).asString());
-        }
-
-        if (profileNode.hasChild(Tags.TAG_SERVICE_PROVIDER_NAME)) {
-            profileBuilder.setServiceProviderName(
-                    profileNode.getChild(Tags.TAG_SERVICE_PROVIDER_NAME).asString());
-        }
-
-        if (profileNode.hasChild(Tags.TAG_PROFILE_NAME)) {
-            profileBuilder.setProfileName(
-                    profileNode.getChild(Tags.TAG_PROFILE_NAME).asString());
-        }
-
-        if (profileNode.hasChild(Tags.TAG_OPERATOR_ID)) {
-            profileBuilder.setCarrierIdentifier(
-                    buildCarrierIdentifier(profileNode.getChild(Tags.TAG_OPERATOR_ID)));
-        }
-
-        if (profileNode.hasChild(Tags.TAG_PROFILE_STATE)) {
-            // In case of MEP capable eUICC, the profileState value returned SHALL only be Enabled
-            // if the Profile is in the Enabled state on the same eSIM Port as where this
-            // getProfilesInfo command was sent. So should check for enabledOnEsimPort(TAG_PORT)
-            // tag and verify its value is a valid port (means port value is >=0) or not.
-            if (profileNode.hasChild(Tags.TAG_PORT)
-                    && profileNode.getChild(Tags.TAG_PORT).asInteger() >= 0) {
-                profileBuilder.setState(EuiccProfileInfo.PROFILE_STATE_ENABLED);
-            } else {
-                // noinspection WrongConstant
-                profileBuilder.setState(profileNode.getChild(Tags.TAG_PROFILE_STATE).asInteger());
-            }
-        } else {
-            profileBuilder.setState(EuiccProfileInfo.PROFILE_STATE_DISABLED);
-        }
-
-        if (profileNode.hasChild(Tags.TAG_PROFILE_CLASS)) {
-            // noinspection WrongConstant
-            profileBuilder.setProfileClass(
-                    profileNode.getChild(Tags.TAG_PROFILE_CLASS).asInteger());
-        } else {
-            profileBuilder.setProfileClass(EuiccProfileInfo.PROFILE_CLASS_OPERATIONAL);
-        }
-
-        if (profileNode.hasChild(Tags.TAG_PROFILE_POLICY_RULE)) {
-            // noinspection WrongConstant
-            profileBuilder.setPolicyRules(
-                    profileNode.getChild(Tags.TAG_PROFILE_POLICY_RULE).asBits());
-        }
-
-        if (profileNode.hasChild(Tags.TAG_CARRIER_PRIVILEGE_RULES)) {
-            List<Asn1Node> refArDoNodes = profileNode.getChild(Tags.TAG_CARRIER_PRIVILEGE_RULES)
-                    .getChildren(Tags.TAG_REF_AR_DO);
-            UiccAccessRule[] rules = buildUiccAccessRule(refArDoNodes);
-            List<UiccAccessRule> rulesList = null;
-            if (rules != null) {
-                rulesList = Arrays.asList(rules);
-            }
-            profileBuilder.setUiccAccessRule(rulesList);
-        }
-    }
-
-    private static CarrierIdentifier buildCarrierIdentifier(Asn1Node node)
-            throws InvalidAsn1DataException, TagNotFoundException {
-        String gid1 = null;
-        if (node.hasChild(Tags.TAG_CTX_1)) {
-            gid1 = IccUtils.bytesToHexString(node.getChild(Tags.TAG_CTX_1).asBytes());
-        }
-        String gid2 = null;
-        if (node.hasChild(Tags.TAG_CTX_2)) {
-            gid2 = IccUtils.bytesToHexString(node.getChild(Tags.TAG_CTX_2).asBytes());
-        }
-        return new CarrierIdentifier(node.getChild(Tags.TAG_CTX_0).asBytes(), gid1, gid2);
-    }
-
-    @Nullable
-    private static UiccAccessRule[] buildUiccAccessRule(List<Asn1Node> nodes)
-            throws InvalidAsn1DataException, TagNotFoundException {
-        if (nodes.isEmpty()) {
-            return null;
-        }
-        int count = nodes.size();
-        UiccAccessRule[] rules = new UiccAccessRule[count];
-        for (int i = 0; i < count; i++) {
-            Asn1Node node = nodes.get(i);
-            Asn1Node refDoNode = node.getChild(Tags.TAG_REF_DO);
-            byte[] signature = refDoNode.getChild(Tags.TAG_DEVICE_APP_ID_REF_DO).asBytes();
-
-            String packageName = null;
-            if (refDoNode.hasChild(Tags.TAG_PKG_REF_DO)) {
-                packageName = refDoNode.getChild(Tags.TAG_PKG_REF_DO).asString();
-            }
-            long accessType = 0;
-            if (node.hasChild(Tags.TAG_AR_DO, Tags.TAG_PERM_AR_DO)) {
-                Asn1Node permArDoNode = node.getChild(Tags.TAG_AR_DO, Tags.TAG_PERM_AR_DO);
-                accessType = permArDoNode.asRawLong();
-            }
-            rules[i] = new UiccAccessRule(signature, packageName, accessType);
-        }
-        return rules;
-    }
-
-    /**
-     * Creates an instance from the ASN.1 data.
-     *
-     * @param node This should be either {@code NotificationMetadata} or {@code PendingNotification}
-     *     defined by SGP.22 v2.0.
-     * @throws TagNotFoundException If no notification tag is found in the bytes.
-     * @throws InvalidAsn1DataException If no valid data is found in the bytes.
-     */
-    private static EuiccNotification createNotification(Asn1Node node)
-            throws TagNotFoundException, InvalidAsn1DataException {
-        Asn1Node metadataNode;
-        if (node.getTag() == Tags.TAG_NOTIFICATION_METADATA) {
-            metadataNode = node;
-        } else if (node.getTag() == Tags.TAG_PROFILE_INSTALLATION_RESULT) {
-            metadataNode = node.getChild(Tags.TAG_PROFILE_INSTALLATION_RESULT_DATA,
-                    Tags.TAG_NOTIFICATION_METADATA);
-        } else {
-            // Other signed notification
-            metadataNode = node.getChild(Tags.TAG_NOTIFICATION_METADATA);
-        }
-        // noinspection WrongConstant
-        return new EuiccNotification(metadataNode.getChild(Tags.TAG_SEQ).asInteger(),
-                metadataNode.getChild(Tags.TAG_TARGET_ADDR).asString(),
-                metadataNode.getChild(Tags.TAG_EVENT).asBits(),
-                node.getTag() == Tags.TAG_NOTIFICATION_METADATA ? null : node.toBytes());
-    }
-
-    /** Returns the first CONTEXT [0] as an integer. */
-    private static int parseSimpleResult(byte[] response)
-            throws EuiccCardException, TagNotFoundException, InvalidAsn1DataException {
-        return parseResponse(response).getChild(Tags.TAG_CTX_0).asInteger();
-    }
-
-    private static Asn1Node parseResponse(byte[] response)
-            throws EuiccCardException, InvalidAsn1DataException {
-        Asn1Decoder decoder = new Asn1Decoder(response);
-        if (!decoder.hasNextNode()) {
-            throw new EuiccCardException("Empty response", null);
-        }
-        return decoder.nextNode();
-    }
-
-    /**
-     * Parses the bytes into an ASN1 node and check if there is an error code represented at the
-     * context 1 tag. If there is an error code, an {@link EuiccCardErrorException} will be thrown
-     * with the given operation code.
-     */
-    private static Asn1Node parseResponseAndCheckSimpleError(byte[] response,
-            @EuiccCardErrorException.OperationCode int opCode)
-            throws EuiccCardException, InvalidAsn1DataException, TagNotFoundException {
-        Asn1Node root = parseResponse(response);
-        if (root.hasChild(Tags.TAG_CTX_1)) {
-            throw new EuiccCardErrorException(opCode, root.getChild(Tags.TAG_CTX_1).asInteger());
-        }
-        return root;
-    }
-
-    /** Strip all the trailing 'F' characters of an iccId. */
-    private static String stripTrailingFs(byte[] iccId) {
-        return IccUtils.stripTrailingFs(IccUtils.bchToString(iccId, 0, iccId.length));
-    }
-
-    /** Pad an iccId with trailing 'F' characters until the length is 20. */
-    private static String padTrailingFs(String iccId) {
-        if (!TextUtils.isEmpty(iccId) && iccId.length() < ICCID_LENGTH) {
-            iccId += new String(new char[20 - iccId.length()]).replace('\0', 'F');
-        }
-        return iccId;
-    }
-
-    private static void loge(String message) {
-        Rlog.e(LOG_TAG, message);
-    }
-
-    private static void loge(String message, Throwable tr) {
-        Rlog.e(LOG_TAG, message, tr);
-    }
-
-    private static void logi(String message) {
-        Rlog.i(LOG_TAG, message);
-    }
-
-    private static void logd(String message) {
-        if (DBG) {
-            Rlog.d(LOG_TAG, message);
-        }
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
-        super.dump(fd, pw, args);
-        pw.println("EuiccPort:");
-        pw.println(" mEid=" + mEid);
-        pw.println(" mIsSupportsMultipleEnabledProfiles=" + mIsSupportsMultipleEnabledProfiles);
-    }
-}
diff --git a/src/java/com/android/internal/telephony/uicc/euicc/Tags.java b/src/java/com/android/internal/telephony/uicc/euicc/Tags.java
index befc7f9..1eab199 100644
--- a/src/java/com/android/internal/telephony/uicc/euicc/Tags.java
+++ b/src/java/com/android/internal/telephony/uicc/euicc/Tags.java
@@ -84,7 +84,6 @@
     static final int TAG_PROFILE_NAME = 0x92;
     static final int TAG_OPERATOR_ID = 0xB7;
     static final int TAG_CARRIER_PRIVILEGE_RULES = 0xBF76;
-    static final int TAG_PORT = 0x9F24;
 
     // Tags from the RefArDo data standard - https://source.android.com/devices/tech/config/uicc
     static final int TAG_REF_AR_DO = 0xE2;
@@ -109,22 +108,5 @@
             (byte) (TAG_CARRIER_PRIVILEGE_RULES % 256),
     };
 
-    // TAG list for Euicc Profile with 9F24 tag
-    static final byte[] EUICC_PROFILE_MEP_TAGS = new byte[] {
-            TAG_ICCID,
-            (byte) TAG_NICKNAME,
-            (byte) TAG_SERVICE_PROVIDER_NAME,
-            (byte) TAG_PROFILE_NAME,
-            (byte) TAG_OPERATOR_ID,
-            (byte) (TAG_PROFILE_STATE / 256),
-            (byte) (TAG_PROFILE_STATE % 256),
-            (byte) TAG_PROFILE_CLASS,
-            (byte) TAG_PROFILE_POLICY_RULE,
-            (byte) (TAG_CARRIER_PRIVILEGE_RULES / 256),
-            (byte) (TAG_CARRIER_PRIVILEGE_RULES % 256),
-            (byte) (TAG_PORT / 256),
-            (byte) (TAG_PORT % 256),
-    };
-
     private Tags() {}
 }
diff --git a/testing/Android.bp b/testing/Android.bp
index 3c100d8..a5f9d7d 100644
--- a/testing/Android.bp
+++ b/testing/Android.bp
@@ -7,15 +7,12 @@
 
     srcs: ["**/*.java"],
 
-    libs: [
-        "telephony-common",
-    ],
-
     static_libs: [
         "androidx.annotation_annotation",
         "guava",
         "junit",
         "mockito-target-minus-junit4",
+        "telephony-common",
         "truth-prebuilt",
     ],
 
diff --git a/tests/telephonytests/Android.bp b/tests/telephonytests/Android.bp
index f197101..a4861df 100644
--- a/tests/telephonytests/Android.bp
+++ b/tests/telephonytests/Android.bp
@@ -1,22 +1,18 @@
 package {
     // See: http://go/android-license-faq
-    default_applicable_licenses: [
-        "frameworks_opt_telephony_tests_telephonytests_license",
-        "Android-Apache-2.0",
-    ],
-}
-
-license {
-    name: "frameworks_opt_telephony_tests_telephonytests_license",
-    package_name: "Android Telephone Tests",
-    license_kinds: ["SPDX-license-identifier-BSD"],
-    license_text: ["LICENSE_BSD"],
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "frameworks_opt_telephony_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    //   SPDX-license-identifier-BSD
+    default_applicable_licenses: ["frameworks_opt_telephony_license"],
 }
 
 android_test {
     name: "FrameworksTelephonyTests",
     // For access hidden connectivity methods in tests
     defaults: ["framework-connectivity-test-defaults"],
+
     srcs: ["**/*.java"],
 
     libs: [
@@ -25,22 +21,20 @@
         "android.test.runner",
         "ims-common",
         "unsupportedappusage",
-        "telephony-common",
     ],
 
     static_libs: [
         "androidx.test.rules",
         "frameworks-base-testutils",
         "guava",
-        "libphonenumber-nogeocoder",
         "mockito-target-minus-junit4",
         "net-tests-utils",
         "platform-test-annotations",
         "services.core",
         "services.net",
+        "telephony-common",
         "truth-prebuilt",
         "testables",
-        "platform-compat-test-rules"
     ],
 
     jarjar_rules: ":jarjar-rules-telephony-tests",
diff --git a/tests/telephonytests/AndroidManifest.xml b/tests/telephonytests/AndroidManifest.xml
index c0a582f..dc36777 100644
--- a/tests/telephonytests/AndroidManifest.xml
+++ b/tests/telephonytests/AndroidManifest.xml
@@ -17,9 +17,7 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.android.frameworks.telephonytests">
 
-    <application android:name="com.android.internal.telephony.TestApplication"
-        android:testOnly="true"
-        android:largeHeap="true">
+    <application android:name="com.android.internal.telephony.TestApplication">
         <uses-library android:name="android.test.runner"/>
         <activity android:label="TelephonyTest"
              android:name="TelephonyTest"
diff --git a/tests/telephonytests/AndroidTest.xml b/tests/telephonytests/AndroidTest.xml
index 474754e..5aa8922 100644
--- a/tests/telephonytests/AndroidTest.xml
+++ b/tests/telephonytests/AndroidTest.xml
@@ -16,7 +16,6 @@
 <configuration description="Runs Frameworks Telephony Tests.">
     <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
         <option name="test-file-name" value="FrameworksTelephonyTests.apk" />
-        <option name="install-arg" value="-t" />
     </target_preparer>
 
     <option name="test-suite-tag" value="apct" />
diff --git a/tests/telephonytests/LICENSE_BSD b/tests/telephonytests/LICENSE_BSD
deleted file mode 100644
index 820d40c..0000000
--- a/tests/telephonytests/LICENSE_BSD
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright (c) 2016, The Linux Foundation. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-    * Neither the name of The Linux Foundation nor the names of its
-      contributors may be used to endorse or promote products derived
-      from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
-WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
-ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
-OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
-IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsConfigImplTest.java b/tests/telephonytests/src/android/telephony/ims/ImsConfigImplTest.java
index 4b00ae9..ccf494b 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsConfigImplTest.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsConfigImplTest.java
@@ -48,10 +48,6 @@
         // for testing caching
         private boolean mIsGetConfigCalled = false;
 
-        ImsConfigImpl() {
-            super(Runnable::run);
-        }
-
         @Override
         public int setConfig(int item, int value) {
             latestIntConfig = new Pair<>(item, value);
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsMmTelManagerTests.java b/tests/telephonytests/src/android/telephony/ims/ImsMmTelManagerTests.java
index 337e296..ac151bb 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsMmTelManagerTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsMmTelManagerTests.java
@@ -19,7 +19,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import android.telephony.AccessNetworkConstants;
@@ -35,11 +34,12 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 public class ImsMmTelManagerTests extends TelephonyTest {
-    // Mocked classes
-    ITelephony mMockTelephonyInterface;
-    BinderCacheManager<ITelephony> mBinderCache;
+
+    @Mock ITelephony mMockTelephonyInterface;
+    @Mock BinderCacheManager<ITelephony> mBinderCache;
 
     public class LocalCallback extends ImsMmTelManager.RegistrationCallback {
         int mRegResult = -1;
@@ -53,8 +53,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp("ImsMmTelManagerTests");
-        mMockTelephonyInterface = mock(ITelephony.class);
-        mBinderCache = mock(BinderCacheManager.class);
         doReturn(mMockTelephonyInterface).when(mBinderCache).getBinder();
     }
 
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java b/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
index af80bd7..ce375f3 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsRegistrationTests.java
@@ -55,7 +55,7 @@
     @Before
     public void setup() throws RemoteException {
         MockitoAnnotations.initMocks(this);
-        mRegistration = new ImsRegistrationImplBase(Runnable::run);
+        mRegistration = new ImsRegistrationImplBase();
         mRegBinder = mRegistration.getBinder();
         mRegBinder.addRegistrationCallback(mCallback);
     }
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsServiceTest.java b/tests/telephonytests/src/android/telephony/ims/ImsServiceTest.java
index cb3ca89..79395a1 100644
--- a/tests/telephonytests/src/android/telephony/ims/ImsServiceTest.java
+++ b/tests/telephonytests/src/android/telephony/ims/ImsServiceTest.java
@@ -17,16 +17,12 @@
 package android.telephony.ims;
 
 import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
 
-import static org.junit.Assert.assertNotNull;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -40,6 +36,7 @@
 import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.stub.ImsFeatureConfiguration;
 import android.test.suitebuilder.annotation.SmallTest;
+import android.util.SparseArray;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -58,12 +55,8 @@
 
     private static final int TEST_SLOT_0 = 0;
     private static final int TEST_SLOT_1 = 1;
-    private static final int TEST_SUB_2 = 2;
-    private static final int TEST_SUB_3 = 3;
 
-    private TestImsServiceCompat mTestImsServiceCompat;
     private TestImsService mTestImsService;
-    private IImsServiceController mTestImsServiceCompatBinder;
     private IImsServiceController mTestImsServiceBinder;
 
     private Context mMockContext;
@@ -76,11 +69,6 @@
         mTestCallback = mock(IImsFeatureStatusCallback.class);
         mImsFeatureStatusCallbackBinder = mock(IBinder.class);
         when(mTestCallback.asBinder()).thenReturn(mImsFeatureStatusCallbackBinder);
-        // Create an ImsService that uses slotId and not subId to test compatibility.
-        mTestImsServiceCompat = new TestImsServiceCompat(mMockContext);
-        mTestImsServiceCompatBinder = (IImsServiceController) mTestImsServiceCompat.onBind(
-                new Intent(ImsService.SERVICE_INTERFACE));
-
         mTestImsService = new TestImsService(mMockContext);
         mTestImsServiceBinder = (IImsServiceController) mTestImsService.onBind(
                 new Intent(ImsService.SERVICE_INTERFACE));
@@ -90,135 +78,26 @@
     public void tearDown() throws Exception {
         mMockContext = null;
         mTestCallback = null;
-        mTestImsServiceCompat = null;
-        mTestImsServiceCompatBinder = null;
         mTestImsService = null;
         mTestImsServiceBinder = null;
     }
 
     @Test
     @SmallTest
-    public void testCreateMMTelFeatureCompat() throws RemoteException {
-        IImsMmTelFeature f = mTestImsServiceCompatBinder.createMmTelFeature(TEST_SLOT_0,
-                TEST_SUB_2);
-        mTestImsServiceCompatBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL,
-                mTestCallback);
-        mTestImsServiceCompat.mTestMmTelFeature.sendSetFeatureState(ImsFeature.STATE_READY);
-
-        ImsFeature featureToVerify = mTestImsServiceCompat.getImsFeature(TEST_SLOT_0,
-                ImsFeature.FEATURE_MMTEL);
-        MmTelFeature testMMTelFeature = null;
-        if (featureToVerify instanceof MmTelFeature) {
-            testMMTelFeature = (MmTelFeature) featureToVerify;
-        } else {
-            fail();
-        }
-        assertTrue(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
-        assertEquals(mTestImsServiceCompat.mSpyMmTelFeature, testMMTelFeature);
-        // Verify that upon creating a feature, we assign the callback and get the set feature state
-        // when querying it.
-        verify(mTestImsServiceCompat.mSpyMmTelFeature)
-                .addImsFeatureStatusCallback(eq(mTestCallback));
-        assertEquals(ImsFeature.STATE_READY, f.getFeatureState());
-    }
-
-    @Test
-    @SmallTest
-    public void testNotCreateMMTelFeatureCompat() throws RemoteException {
-        IImsMmTelFeature f = mTestImsServiceCompatBinder.createMmTelFeature(TEST_SLOT_0,
-                TEST_SUB_2);
-        mTestImsServiceCompatBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL,
-                mTestCallback);
-        mTestImsServiceCompat.mTestMmTelFeature.sendSetFeatureState(ImsFeature.STATE_READY);
-
-        ImsFeature featureToVerify = mTestImsServiceCompat.getImsFeature(TEST_SLOT_0,
-                ImsFeature.FEATURE_MMTEL);
-        MmTelFeature testMMTelFeature = null;
-        if (featureToVerify instanceof MmTelFeature) {
-            testMMTelFeature = (MmTelFeature) featureToVerify;
-        } else {
-            fail();
-        }
-        assertTrue(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
-        assertEquals(mTestImsServiceCompat.mSpyMmTelFeature, testMMTelFeature);
-        // Verify that upon creating a feature, we assign the callback and get the set feature state
-        // when querying it.
-        verify(mTestImsServiceCompat.mSpyMmTelFeature)
-                .addImsFeatureStatusCallback(eq(mTestCallback));
-        assertEquals(ImsFeature.STATE_READY, f.getFeatureState());
-        // Ensures feature is not created if already have one.
-        IImsMmTelFeature f2 = mTestImsServiceCompatBinder.createMmTelFeature(TEST_SLOT_0,
-                TEST_SUB_3);
-        mTestImsServiceCompatBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL,
-                mTestCallback);
-        assertEquals(mTestImsServiceCompat.createMmtelfeatureCount, 1);
-        verify(mTestImsServiceCompat.mSpyMmTelFeature, times(2))
-                .addImsFeatureStatusCallback(eq(mTestCallback));
-    }
-
-    @Test
-    @SmallTest
-    public void testRemoveMMTelFeatureCompat() throws RemoteException {
-        mTestImsServiceCompatBinder.createMmTelFeature(TEST_SLOT_0, TEST_SUB_2);
-        mTestImsServiceCompatBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL,
-                mTestCallback);
-        assertTrue(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
-
-        mTestImsServiceCompatBinder.removeFeatureStatusCallback(TEST_SLOT_0,
-                ImsFeature.FEATURE_MMTEL, mTestCallback);
-        mTestImsServiceCompatBinder.removeImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, false);
-
-        verify(mTestImsServiceCompat.mSpyMmTelFeature).onFeatureRemoved();
-        verify(mTestImsServiceCompat.mSpyMmTelFeature).removeImsFeatureStatusCallback(
-                mTestCallback);
-        assertNull(mTestImsServiceCompat.getImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL));
-        assertFalse(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
-    }
-
-    @Test
-    @SmallTest
-    public void testNotRemoveMMTelFeatureCompat() throws RemoteException {
-        mTestImsServiceCompatBinder.createMmTelFeature(TEST_SLOT_0, TEST_SUB_2);
-        mTestImsServiceCompatBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL,
-                mTestCallback);
-        assertTrue(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
-
-        mTestImsServiceCompatBinder.removeFeatureStatusCallback(TEST_SLOT_0,
-                ImsFeature.FEATURE_MMTEL, mTestCallback);
-        mTestImsServiceCompatBinder.removeImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, true);
-        // make sure the feature is not removed because it is created with slot ID so is not
-        // affected by sub ID changing
-        verify(mTestImsServiceCompat.mSpyMmTelFeature, never()).onFeatureRemoved();
-        verify(mTestImsServiceCompat.mSpyMmTelFeature).removeImsFeatureStatusCallback(
-                mTestCallback);
-        assertNotNull(mTestImsServiceCompat.getImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL));
-        assertTrue(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
-    }
-
-    @Test
-    @SmallTest
     public void testCreateMMTelFeature() throws RemoteException {
-        IImsMmTelFeature f = mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, TEST_SUB_2);
+        IImsMmTelFeature f = mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0);
         mTestImsServiceBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL,
                 mTestCallback);
         mTestImsService.mTestMmTelFeature.sendSetFeatureState(ImsFeature.STATE_READY);
 
-        ImsFeature featureToVerify = mTestImsService.getImsFeature(TEST_SLOT_0,
-                ImsFeature.FEATURE_MMTEL);
+        SparseArray<ImsFeature> features = mTestImsService.getFeatures(TEST_SLOT_0);
+        ImsFeature featureToVerify = features.get(ImsFeature.FEATURE_MMTEL);
         MmTelFeature testMMTelFeature = null;
         if (featureToVerify instanceof MmTelFeature) {
             testMMTelFeature = (MmTelFeature) featureToVerify;
         } else {
             fail();
         }
-        assertFalse(mTestImsServiceCompat.isImsFeatureCreatedForSlot(TEST_SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
         assertEquals(mTestImsService.mSpyMmTelFeature, testMMTelFeature);
         // Verify that upon creating a feature, we assign the callback and get the set feature state
         // when querying it.
@@ -229,23 +108,24 @@
     @Test
     @SmallTest
     public void testRemoveMMTelFeature() throws RemoteException {
-        mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, TEST_SUB_2);
+        mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0);
         mTestImsServiceBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL,
                 mTestCallback);
 
         mTestImsServiceBinder.removeFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL,
                 mTestCallback);
-        mTestImsServiceBinder.removeImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL, true);
+        mTestImsServiceBinder.removeImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL);
 
         verify(mTestImsService.mSpyMmTelFeature).onFeatureRemoved();
         verify(mTestImsService.mSpyMmTelFeature).removeImsFeatureStatusCallback(mTestCallback);
-        assertNull(mTestImsService.getImsFeature(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL));
+        SparseArray<ImsFeature> features = mTestImsService.getFeatures(TEST_SLOT_0);
+        assertNull(features.get(ImsFeature.FEATURE_MMTEL));
     }
 
     @Test
     @SmallTest
     public void testCallMethodOnCreatedFeature() throws RemoteException {
-        IImsMmTelFeature f = mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0, TEST_SUB_2);
+        IImsMmTelFeature f = mTestImsServiceBinder.createMmTelFeature(TEST_SLOT_0);
         mTestImsServiceBinder.addFeatureStatusCallback(TEST_SLOT_0, ImsFeature.FEATURE_MMTEL,
                 mTestCallback);
 
@@ -277,7 +157,8 @@
     @Test
     @SmallTest
     public void testCapsSanitized() throws RemoteException {
-        long validCaps = ImsService.CAPABILITY_SIP_DELEGATE_CREATION;
+        long validCaps =
+                ImsService.CAPABILITY_SIP_DELEGATE_CREATION;
         // emergency over MMTEL should not be set here, but rather internally in Telephony.
         long invalidCaps = 0xDEADBEEF00000000L | ImsService.CAPABILITY_EMERGENCY_OVER_MMTEL;
         invalidCaps |= validCaps;
diff --git a/tests/telephonytests/src/android/telephony/ims/ImsStateCallbackTest.java b/tests/telephonytests/src/android/telephony/ims/ImsStateCallbackTest.java
deleted file mode 100644
index 9a9713d..0000000
--- a/tests/telephonytests/src/android/telephony/ims/ImsStateCallbackTest.java
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-import static android.telephony.ims.feature.ImsFeature.FEATURE_MMTEL;
-import static android.telephony.ims.feature.ImsFeature.FEATURE_RCS;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.telephony.BinderCacheManager;
-import android.telephony.ims.aidl.IImsRcsController;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.internal.telephony.IImsStateCallback;
-import com.android.internal.telephony.ITelephony;
-import com.android.internal.telephony.TelephonyTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-public class ImsStateCallbackTest extends TelephonyTest {
-    private static final int ON_ERROR = Integer.MAX_VALUE;
-    private static final int ON_AVAILABLE = 0;
-
-    private static final int SUB_ID_ONE = 1;
-
-    // Mocked classes
-    ITelephony mMockTelephonyInterface;
-    BinderCacheManager<ITelephony> mBinderCache;
-    BinderCacheManager<IImsRcsController> mRcsBinderCache;
-
-    public class LocalCallback extends ImsStateCallback {
-        int mRegResult = -1;
-
-        @Override
-        public void onUnavailable(int reason) {
-            mRegResult = reason;
-        }
-
-        @Override
-        public void onAvailable() {
-            mRegResult = ON_AVAILABLE;
-        }
-
-        @Override
-        public void onError() {
-            mRegResult = ON_ERROR;
-        }
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp("ImsStateCallbackTests");
-        mMockTelephonyInterface = mock(ITelephony.class);
-        mBinderCache = mock(BinderCacheManager.class);
-        mRcsBinderCache = mock(BinderCacheManager.class);
-        doReturn(mMockTelephonyInterface).when(mBinderCache)
-                .listenOnBinder(any(), any(Runnable.class));
-        doReturn(mMockTelephonyInterface).when(mBinderCache)
-                .removeRunnable(any(ImsStateCallback.class));
-        doReturn(mMockTelephonyInterface).when(mBinderCache).getBinder();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /**
-     * Ensure that the values of ITelephony#(un)registerImsStateCallback's parameters
-     * for ImsMmTelManager are correct.
-     */
-    @SmallTest
-    @Test
-    public void testMmTelRegisterAndUnregisterImsStateCallbackValues() throws Exception {
-        LocalCallback cb = new LocalCallback();
-
-        ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(SUB_ID_ONE);
-
-        replaceInstance(ImsMmTelManager.class, "mBinderCache", mmTelManager, mBinderCache);
-
-        mmTelManager.registerImsStateCallback(Runnable::run, cb);
-        verify(mBinderCache).listenOnBinder(any(), any(Runnable.class));
-        verify(mMockTelephonyInterface).registerImsStateCallback(
-                eq(SUB_ID_ONE), eq(FEATURE_MMTEL), any(IImsStateCallback.class), any());
-
-        mmTelManager.unregisterImsStateCallback(cb);
-        verify(mMockTelephonyInterface).unregisterImsStateCallback(any(IImsStateCallback.class));
-    }
-
-    /**
-     * Ensure that the values of ITelephony#(un)registerImsStateCallback's parameters
-     * for ImsRcsManager are correct.
-     */
-    @SmallTest
-    @Test
-    public void testRcsRegisterAndUnregisterImsStateCallbackValues() throws Exception {
-        LocalCallback cb = new LocalCallback();
-
-        ImsRcsManager rcsManager =
-                new ImsRcsManager(mContext, SUB_ID_ONE, mRcsBinderCache, mBinderCache);
-
-        replaceInstance(ImsRcsManager.class, "mTelephonyBinderCache", rcsManager, mBinderCache);
-
-        rcsManager.registerImsStateCallback(Runnable::run, cb);
-        verify(mBinderCache).listenOnBinder(any(), any(Runnable.class));
-        verify(mMockTelephonyInterface).registerImsStateCallback(
-                eq(SUB_ID_ONE), eq(FEATURE_RCS), any(IImsStateCallback.class), any());
-
-        rcsManager.unregisterImsStateCallback(cb);
-        verify(mMockTelephonyInterface).unregisterImsStateCallback(any(IImsStateCallback.class));
-    }
-
-    /**
-     * Ensure that the values of ITelephony#(un)registerImsStateCallback's parameters
-     * for ImsRcsManager are correct.
-     */
-    @SmallTest
-    @Test
-    public void testSipDelegateRegisterAndUnregisterImsStateCallbackValues() throws Exception {
-        LocalCallback cb = new LocalCallback();
-
-        SipDelegateManager sipManager =
-                new SipDelegateManager(mContext, SUB_ID_ONE, mRcsBinderCache, mBinderCache);
-
-        replaceInstance(
-                SipDelegateManager.class, "mTelephonyBinderCache", sipManager, mBinderCache);
-
-        sipManager.registerImsStateCallback(Runnable::run, cb);
-        verify(mBinderCache).listenOnBinder(any(), any(Runnable.class));
-        verify(mMockTelephonyInterface).registerImsStateCallback(
-                eq(SUB_ID_ONE), eq(FEATURE_RCS), any(IImsStateCallback.class), any());
-
-        sipManager.unregisterImsStateCallback(cb);
-        verify(mMockTelephonyInterface).unregisterImsStateCallback(any(IImsStateCallback.class));
-    }
-
-    /**
-     * Ensure that onUnavailable, onAvailable, and onErr are called.
-     */
-    @SmallTest
-    @Test
-    public void testImsStateCallbacks() throws Exception {
-        LocalCallback cb = new LocalCallback();
-
-        ImsMmTelManager mmTelManager = ImsMmTelManager.createForSubscriptionId(SUB_ID_ONE);
-
-        replaceInstance(ImsMmTelManager.class, "mBinderCache", mmTelManager, mBinderCache);
-
-        // Capture the Runnable that was registered.
-        ArgumentCaptor<Runnable> runnableCaptor =
-                ArgumentCaptor.forClass(Runnable.class);
-
-        // Capture the IImsStateCallback that was registered.
-        ArgumentCaptor<IImsStateCallback> callbackCaptor =
-                ArgumentCaptor.forClass(IImsStateCallback.class);
-
-        mmTelManager.registerImsStateCallback(Runnable::run, cb);
-        verify(mBinderCache).listenOnBinder(any(), runnableCaptor.capture());
-
-        verify(mMockTelephonyInterface).registerImsStateCallback(
-                eq(SUB_ID_ONE), eq(FEATURE_MMTEL), callbackCaptor.capture(), any());
-
-        IImsStateCallback cbBinder = callbackCaptor.getValue();
-
-        // onUnavailable
-        cbBinder.onUnavailable(ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED);
-        assertEquals(ImsStateCallback.REASON_IMS_SERVICE_DISCONNECTED, cb.mRegResult);
-
-        // onAvailable
-        cbBinder.onAvailable();
-        assertEquals(ON_AVAILABLE, cb.mRegResult);
-
-        Runnable runnable = runnableCaptor.getValue();
-        // onError
-        runnable.run();
-        assertEquals(ON_ERROR, cb.mRegResult);
-    }
-}
diff --git a/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java b/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
index 5af871c..a067604 100644
--- a/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
+++ b/tests/telephonytests/src/android/telephony/ims/MmTelFeatureTests.java
@@ -124,10 +124,9 @@
     }
 
     @After
-    public void tearDown() throws Exception {
+    public void tearDown() {
         mFeature = null;
         mFeatureBinder = null;
-        super.tearDown();
     }
 
     @SmallTest
diff --git a/tests/telephonytests/src/android/telephony/ims/RcsFeatureTest.java b/tests/telephonytests/src/android/telephony/ims/RcsFeatureTest.java
deleted file mode 100644
index fa88d71..0000000
--- a/tests/telephonytests/src/android/telephony/ims/RcsFeatureTest.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
-
-import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
-import android.telephony.ims.aidl.IImsRcsFeature;
-import android.telephony.ims.feature.RcsFeature;
-import android.telephony.ims.stub.CapabilityExchangeEventListener;
-import android.telephony.ims.stub.RcsCapabilityExchangeImplBase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import androidx.annotation.NonNull;
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.internal.telephony.ims.ImsTestBase;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-
-@RunWith(AndroidJUnit4.class)
-public class RcsFeatureTest  extends ImsTestBase {
-
-    private class TestRcsFeature extends RcsFeature {
-
-        public CapabilityExchangeEventListener eventListener;
-        public int eventListenerCreateCount = 0;
-        public int eventListenerDestroyCount = 0;
-
-        TestRcsFeature() {
-            super(Runnable::run);
-        }
-
-        @NonNull
-        @Override
-        public RcsCapabilityExchangeImplBase createCapabilityExchangeImpl(
-                @NonNull CapabilityExchangeEventListener listener) {
-            eventListener = listener;
-            eventListenerCreateCount++;
-            return mMockCapExchange;
-        }
-
-        @Override
-        public void destroyCapabilityExchangeImpl(
-                @NonNull RcsCapabilityExchangeImplBase capExchangeImpl) {
-            eventListenerDestroyCount++;
-            eventListener = null;
-        }
-    }
-
-    private TestRcsFeature mRcsFeatureUT;
-    private IImsRcsFeature mRcsFeatureBinder;
-
-    @Mock
-    private ICapabilityExchangeEventListener mEventListener;
-    @Mock
-    private RcsCapabilityExchangeImplBase mMockCapExchange;
-
-    @Before
-    public void setup() throws Exception {
-        super.setUp();
-        mRcsFeatureUT = new TestRcsFeature();
-        mRcsFeatureBinder = mRcsFeatureUT.getBinder();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mRcsFeatureUT = null;
-        super.tearDown();
-    }
-
-    @SmallTest
-    @Test
-    public void testCreateDestroyCapabilityExchangeImpl() throws Exception {
-        // Ensure create is only called once when a listener is set
-        mRcsFeatureBinder.setCapabilityExchangeEventListener(mEventListener);
-        assertNotNull(mRcsFeatureUT.eventListener);
-        assertEquals(1, mRcsFeatureUT.eventListenerCreateCount);
-        assertEquals(0, mRcsFeatureUT.eventListenerDestroyCount);
-
-        // Ensure destroying the listener only results in one destroy call.
-        mRcsFeatureBinder.setCapabilityExchangeEventListener(null);
-        assertNull(mRcsFeatureUT.eventListener);
-        assertEquals(1, mRcsFeatureUT.eventListenerCreateCount);
-        assertEquals(1, mRcsFeatureUT.eventListenerDestroyCount);
-
-        // Ensure create is only called once more when a listener is set
-        mRcsFeatureBinder.setCapabilityExchangeEventListener(mEventListener);
-        assertNotNull(mRcsFeatureUT.eventListener);
-        assertEquals(2, mRcsFeatureUT.eventListenerCreateCount);
-        assertEquals(1, mRcsFeatureUT.eventListenerDestroyCount);
-    }
-}
diff --git a/tests/telephonytests/src/android/telephony/ims/TestImsService.java b/tests/telephonytests/src/android/telephony/ims/TestImsService.java
index 99ec9d4..ff4781e 100644
--- a/tests/telephonytests/src/android/telephony/ims/TestImsService.java
+++ b/tests/telephonytests/src/android/telephony/ims/TestImsService.java
@@ -47,12 +47,12 @@
     }
 
     @Override
-    public MmTelFeature createMmTelFeatureForSubscription(int slotId, int subId) {
+    public MmTelFeature createMmTelFeature(int slotId) {
         return mSpyMmTelFeature;
     }
 
     @Override
-    public RcsFeature createRcsFeatureForSubscription(int slotId, int subId) {
+    public RcsFeature createRcsFeature(int slotId) {
         return null;
     }
 
diff --git a/tests/telephonytests/src/android/telephony/ims/TestImsServiceCompat.java b/tests/telephonytests/src/android/telephony/ims/TestImsServiceCompat.java
deleted file mode 100644
index c2755a4..0000000
--- a/tests/telephonytests/src/android/telephony/ims/TestImsServiceCompat.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.telephony.ims;
-
-import static org.mockito.Mockito.spy;
-
-import android.content.Context;
-import android.telephony.ims.feature.MmTelFeature;
-import android.telephony.ims.feature.RcsFeature;
-import android.telephony.ims.stub.ImsFeatureConfiguration;
-
-import org.mockito.MockitoAnnotations;
-
-/**
- * Test ImsService compatibility used by mockito to verify functionality.
- */
-
-public class TestImsServiceCompat extends android.telephony.ims.ImsService {
-
-    public TestMmTelFeature mSpyMmTelFeature;
-    public TestMmTelFeature mTestMmTelFeature;
-
-    public ImsFeatureConfiguration testFeatureConfig;
-
-    public long testCaps;
-    public int createMmtelfeatureCount = 0;
-
-    public TestImsServiceCompat(Context context) {
-        attachBaseContext(context);
-        MockitoAnnotations.initMocks(this);
-        // Must create real MMTelFeature to initialize ImsFeature objects.
-        mTestMmTelFeature = new TestMmTelFeature();
-        mSpyMmTelFeature = spy(mTestMmTelFeature);
-    }
-
-    @Override
-    public MmTelFeature createMmTelFeature(int slotId) {
-        createMmtelfeatureCount++;
-        return mSpyMmTelFeature;
-    }
-
-    @Override
-    public RcsFeature createRcsFeature(int slotId) {
-        return null;
-    }
-
-    @Override
-    public ImsFeatureConfiguration querySupportedImsFeatures() {
-        return testFeatureConfig;
-    }
-
-    @Override
-    public long getImsServiceCapabilities() {
-        return testCaps;
-    }
-}
diff --git a/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java b/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
index 9ee1e30..67b9bad 100644
--- a/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
+++ b/tests/telephonytests/src/android/telephony/ims/TestMmTelFeature.java
@@ -40,10 +40,6 @@
     public CountDownLatch configuredRtpHeaderExtensions = new CountDownLatch(1);
     Set<RtpHeaderExtensionType> receivedExtensions = null;
 
-    public TestMmTelFeature() {
-        super(Runnable::run);
-    }
-
     private final TestImsCallSession mCallSession = new TestImsCallSession();
     private class TestImsCallSession extends ImsCallSessionImplBase {
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/AppSmsManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/AppSmsManagerTest.java
index 7a1dcdb..bae1632 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/AppSmsManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/AppSmsManagerTest.java
@@ -50,13 +50,12 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
+        super.setUp("AppSmsManagerTest");
         mAppSmsManagerUT = new AppSmsManager(mContextFixture.getTestDouble());
     }
 
     @After
     public void tearDown() throws Exception {
-        mAppSmsManagerUT = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CallManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/CallManagerTest.java
index 62b2a45..67587d4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CallManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CallManagerTest.java
@@ -44,23 +44,26 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+
+import java.lang.reflect.Field;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class CallManagerTest extends TelephonyTest {
-    // Mocked classes
+
+    @Mock
     GsmCdmaCall mFgCall;
+    @Mock
     GsmCdmaCall mBgCall;
+    @Mock
     GsmCdmaCall mRingingCall;
+    @Mock
     Phone mSecondPhone;
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mFgCall = mock(GsmCdmaCall.class);
-        mBgCall = mock(GsmCdmaCall.class);
-        mRingingCall = mock(GsmCdmaCall.class);
-        mSecondPhone = mock(Phone.class);
+        super.setUp(this.getClass().getSimpleName());
         restoreInstance(CallManager.class, "INSTANCE", null);
         /* Mock Phone and Call, initially all calls are idle */
         doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getState();
@@ -209,12 +212,23 @@
 
     @Test @SmallTest
     public void testRegisterEvent() throws Exception {
+        Field field = CallManager.class.getDeclaredField("EVENT_CALL_WAITING");
+        field.setAccessible(true);
+        int mEvent = (Integer) field.get(CallManager.getInstance());
         verify(mPhone, times(1)).registerForCallWaiting(isA(Handler.class),
-                eq(CallManager.EVENT_CALL_WAITING), isNull());
+                eq(mEvent), isNull());
+
+        field = CallManager.class.getDeclaredField("EVENT_PRECISE_CALL_STATE_CHANGED");
+        field.setAccessible(true);
+        mEvent = (Integer) field.get(CallManager.getInstance());
         verify(mPhone, times(1)).registerForPreciseCallStateChanged(isA(Handler.class),
-                eq(CallManager.EVENT_PRECISE_CALL_STATE_CHANGED), isA(Object.class));
+                eq(mEvent), isA(Object.class));
+
+        field = CallManager.class.getDeclaredField("EVENT_RINGBACK_TONE");
+        field.setAccessible(true);
+        mEvent = (Integer) field.get(CallManager.getInstance());
         verify(mPhone, times(1)).registerForRingbackTone(isA(Handler.class),
-                eq(CallManager.EVENT_RINGBACK_TONE), isA(Object.class));
+                eq(mEvent), isA(Object.class));
     }
 
     @Test @SmallTest
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
index 7727e79..6371c06 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierActionAgentTest.java
@@ -18,7 +18,6 @@
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -40,6 +39,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -48,9 +48,9 @@
     private FakeContentResolver mFakeContentResolver;
     private static int DATA_CARRIER_ACTION_EVENT = 0;
     private static int RADIO_CARRIER_ACTION_EVENT = 1;
-
-    // Mocked classes
+    @Mock
     private Handler mDataActionHandler;
+    @Mock
     private Handler mRadioActionHandler;
 
     private class FakeContentResolver extends MockContentResolver {
@@ -70,8 +70,6 @@
     public void setUp() throws Exception {
         logd("CarrierActionAgentTest +Setup!");
         super.setUp(getClass().getSimpleName());
-        mDataActionHandler = mock(Handler.class);
-        mRadioActionHandler = mock(Handler.class);
         mFakeContentResolver = new FakeContentResolver();
         doReturn(mFakeContentResolver).when(mContext).getContentResolver();
         mCarrierActionAgentUT = new CarrierActionAgent(mPhone);
@@ -172,8 +170,6 @@
     @After
     public void tearDown() throws Exception {
         Settings.Global.putInt(mFakeContentResolver, Settings.Global.AIRPLANE_MODE_ON, 0);
-        mCarrierActionAgentUT = null;
-        mFakeContentResolver = null;
         super.tearDown();
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
index 583a147..a0e5b33 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierAppUtilsTest.java
@@ -34,12 +34,13 @@
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -59,11 +60,9 @@
     private static final int USER_ID = 12345;
     private static final String CALLING_PACKAGE = "phone";
 
-    // Mocked classes
-    private Context mContext;
-    private PackageManager mPackageManager;
-    private TelephonyManager mTelephonyManager;
-
+    @Mock private Context mContext;
+    @Mock private PackageManager mPackageManager;
+    @Mock private TelephonyManager mTelephonyManager;
     private SettingsMockContentProvider mContentProvider;
     private MockContentResolver mContentResolver;
 
@@ -82,9 +81,7 @@
         System.setProperty("dexmaker.dexcache",
                 InstrumentationRegistry.getTargetContext().getCacheDir().getPath());
         Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
-        mContext = Mockito.mock(Context.class);
-        mPackageManager = Mockito.mock(PackageManager.class);
-        mTelephonyManager = Mockito.mock(TelephonyManager.class);
+        MockitoAnnotations.initMocks(this);
 
         Mockito.when(mContext.createContextAsUser(Mockito.any(UserHandle.class), Mockito.eq(0)))
                 .thenReturn(mContext);
@@ -102,12 +99,6 @@
         Mockito.when(mContext.getContentResolver()).thenReturn(mContentResolver);
     }
 
-    @After
-    public void tearDown() {
-        mContentProvider = null;
-        mContentResolver = null;
-    }
-
     /** No apps configured - should do nothing. */
     @Test @SmallTest
     public void testDisableCarrierAppsUntilPrivileged_EmptyList() {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierDisplayNameResolverTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierDisplayNameResolverTest.java
index 2ccfe0c..ff18a07 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierDisplayNameResolverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierDisplayNameResolverTest.java
@@ -64,11 +64,11 @@
 
     private CarrierDisplayNameResolver mCdnr;
 
-    private ServiceState mSS = new ServiceState();
+    private final ServiceState mSS = new ServiceState();
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(this.getClass().getSimpleName());
+        super.setUp("CDNRTest");
 
         mCdnr = new CarrierDisplayNameResolver(mPhone);
 
@@ -102,9 +102,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mCdnr = null;
-        mConfig = null;
-        mSS = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java
index 0b7da6f..4cd5d68 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierKeyDownloadMgrTest.java
@@ -45,7 +45,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
+import org.mockito.Matchers;
+import org.mockito.MockitoAnnotations;
 
 import java.security.PublicKey;
 import java.text.SimpleDateFormat;
@@ -61,31 +62,21 @@
 
     private CarrierKeyDownloadManager mCarrierKeyDM;
 
-    private final String mURL = "http://www.google.com";
+    private String mURL = "http://www.google.com";
 
     private static final String CERT = "-----BEGIN CERTIFICATE-----\r\nMIIFjzCCBHegAwIBAgIUPxj3SLif82Ky1RlUy8p2EWJCh8MwDQYJKoZIhvcNAQELBQAwgY0xCzAJBgNVBAYTAk5MMRIwEAYDVQQHEwlBbXN0ZXJkYW0xJTAjBgNVBAoTHFZlcml6b24gRW50ZXJwcmlzZSBTb2x1dGlvbnMxEzARBgNVBAsTCkN5YmVydHJ1c3QxLjAsBgNVBAMTJVZlcml6b24gUHVibGljIFN1cmVTZXJ2ZXIgQ0EgRzE0LVNIQTIwHhcNMTcwODE0MTc0MzM4WhcNMTkwODE0MTc0MzM4WjCBmTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFjAUBgNVBAcTDUJhc2tpbmcgUmlkZ2UxIjAgBgNVBAoTGVZlcml6b24gRGF0YSBTZXJ2aWNlcyBMTEMxHzAdBgNVBAsTFk5ldHdvcmsgU3lzdGVtIFN1cHBvcnQxGDAWBgNVBAMTD3ZpMWx2Lmltc3ZtLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALUQKWTHi4Hjpd1LQwJ87RXa0Rs3rVonvVevliqdUH5BikjhAzvIqwPSXeRQqkaRTFIyp0NKcNqGdjAaHRo43gdHeWSH331sS6CMZDg988gZznskzCqJJo6ii5FuLC8qe2YDsHxT+CefXev2rn6Bj1ei2X74uZsy5KlkBRZfFHtPdK6/EK5TpzrvcXfDyOK1rn8FTno1bQOTAhL39GPcLhdrXV7AN+lu+EBpdCqlTdcoDxsqavi/91MwUIVEzxJmycKloT6OWfU44r7+L5SYYgc88NTaGL/BvCFwHRIa1ZgYSGeAPes45792MGG7tfr/ttAGp9UEwTv2zWTxzWnRP/UCAwEAAaOCAdcwggHTMAwGA1UdEwEB/wQCMAAwTAYDVR0gBEUwQzBBBgkrBgEEAbE+ATIwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly9zZWN1cmUub21uaXJvb3QuY29tL3JlcG9zaXRvcnkwgakGCCsGAQUFBwEBBIGcMIGZMC0GCCsGAQUFBzABhiFodHRwOi8vdnBzc2cxNDIub2NzcC5vbW5pcm9vdC5jb20wMwYIKwYBBQUHMAKGJ2h0dHA6Ly9jYWNlcnQub21uaXJvb3QuY29tL3Zwc3NnMTQyLmNydDAzBggrBgEFBQcwAoYnaHR0cDovL2NhY2VydC5vbW5pcm9vdC5jb20vdnBzc2cxNDIuZGVyMBoGA1UdEQQTMBGCD3ZpMWx2Lmltc3ZtLmNvbTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMB8GA1UdIwQYMBaAFOQtu5EBZSYftHo/oxUlpM6MRDM7MD4GA1UdHwQ3MDUwM6AxoC+GLWh0dHA6Ly92cHNzZzE0Mi5jcmwub21uaXJvb3QuY29tL3Zwc3NnMTQyLmNybDAdBgNVHQ4EFgQUv5SaSyNM/yXw1v0N9TNpjsFCaPcwDQYJKoZIhvcNAQELBQADggEBACNJusTULj1KyV4RwiskKfp4wI9Hsz3ESbZS/ijF9D57BQ0UwkELU9r6rEAhsYLUvMq4sDhDbYIdupgP4MBzFnjkKult7VQm5W3nCcuHgXYFAJ9Y1a4OZAo/4hrHj70W9TsQ1ioSMjUT4F8bDUYZI0kcyH8e/+2DaTsLUpHw3L+Keu8PsJVBLnvcKJjWrZD/Bgd6JuaTX2G84i0rY0GJuO9CxLNJa6n61Mz5cqLYIuwKgiVgTA2n71YITyFICOFPFX1vSx35AWvD6aVYblxtC8mpCdF2h4s1iyrpXeji2GCJLwsNVtTtNQ4zWX3Gnq683wzkYZeyOHUyftIgAQZ+HsY=\r\n-----END CERTIFICATE-----";
     private static final long CERT_EXPIRATION = 1565804618000L; //milliseconds since the epoch
-    private final String mJsonStr = "{ \"carrier-keys\": [ { \"certificate\": \"" + CERT
-            + "\", \"key-type\": \"WLAN\", \"key-identifier\": \"key1=value\", "
-            + "\"expiration-date\": 1502577746000 }, { \"certificate\": \""
-            + CERT
-            + "\", \"key-type\": \"WLAN\", \"key-identifier\": \"key1=value\", "
-            + "\"expiration-date\": 1502577746000 }]}";
+    private String mJsonStr = "{ \"carrier-keys\": [ { \"certificate\": \"" + CERT + "\", \"key-type\": \"WLAN\", \"key-identifier\": \"key1=value\", \"expiration-date\": 1502577746000 }, { \"certificate\": \"" + CERT + "\", \"key-type\": \"WLAN\", \"key-identifier\": \"key1=value\", \"expiration-date\": 1502577746000 }]}";
 
-    private final String mJsonStr1 = "{ \"carrier-keys\": [ { \"public-key\": \"" + CERT
-            + "\", \"key-type\": \"WLAN\", \"key-identifier\": \"key1=value\", "
-            + "\"expiration-date\": 1502577746000 }, { \"public-key\": \""
-            + CERT
-            + "\", \"key-type\": \"WLAN\", \"key-identifier\": \"key1=value\", "
-            + "\"expiration-date\": 1502577746000 }]}";
+    private String mJsonStr1 = "{ \"carrier-keys\": [ { \"public-key\": \"" + CERT + "\", \"key-type\": \"WLAN\", \"key-identifier\": \"key1=value\", \"expiration-date\": 1502577746000 }, { \"public-key\": \"" + CERT + "\", \"key-type\": \"WLAN\", \"key-identifier\": \"key1=value\", \"expiration-date\": 1502577746000 }]}";
 
-    private final String mJsonStr3GppSpec =
-            "{ \"carrier-keys\": [ { \"key-identifier\": \"key1=value\", "
-                    + "\"public-key\": \"" + CERT + "\"}]}";
+    private String mJsonStr3GppSpec = "{ \"carrier-keys\": [ { \"key-identifier\": \"key1=value\", "
+            + "\"public-key\": \"" + CERT + "\"}]}";
 
     @Before
     public void setUp() throws Exception {
         logd("CarrierActionAgentTest +Setup!");
+        MockitoAnnotations.initMocks(this);
         super.setUp(getClass().getSimpleName());
         mCarrierKeyDM = new CarrierKeyDownloadManager(mPhone);
         processAllMessages();
@@ -94,7 +85,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mCarrierKeyDM = null;
         super.tearDown();
     }
 
@@ -106,7 +96,7 @@
     public void testExpirationDate1Day() {
         java.security.PublicKey publicKey = null;
         mCarrierKeyDM.mKeyAvailability = 3;
-        SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd");
+        SimpleDateFormat dt = new SimpleDateFormat("yyyy-mm-dd");
         Calendar cal = new GregorianCalendar();
         cal.add(Calendar.DATE, 6);
         Date date = cal.getTime();
@@ -114,11 +104,11 @@
         expectedCal.add(Calendar.DATE, 1);
         String dateExpected = dt.format(expectedCal.getTime());
         ImsiEncryptionInfo imsiEncryptionInfo = new ImsiEncryptionInfo("mcc", "mnc", 1,
-                "keyIdentifier", publicKey, date, 1);
+                "keyIdentifier", publicKey, date);
         when(mPhone.getCarrierInfoForImsiEncryption(anyInt(), anyBoolean()))
                 .thenReturn(imsiEncryptionInfo);
         Date expirationDate = new Date(mCarrierKeyDM.getExpirationDate());
-        assertEquals(dt.format(expirationDate), dateExpected);
+        assertTrue(dt.format(expirationDate).equals(dateExpected));
     }
 
     /**
@@ -130,6 +120,7 @@
     public void testExpirationDate7Day() {
         java.security.PublicKey publicKey = null;
         mCarrierKeyDM.mKeyAvailability = 3;
+        SimpleDateFormat dt = new SimpleDateFormat("yyyy-mm-dd");
         Calendar cal = new GregorianCalendar();
         cal.add(Calendar.DATE, 30);
         Date date = cal.getTime();
@@ -140,7 +131,7 @@
         Date minExpirationDate = minExpirationCal.getTime();
         Date maxExpirationDate = maxExpirationCal.getTime();
         ImsiEncryptionInfo imsiEncryptionInfo = new ImsiEncryptionInfo("mcc", "mnc", 1,
-                "keyIdentifier", publicKey, date, 1);
+                "keyIdentifier", publicKey, date);
         when(mPhone.getCarrierInfoForImsiEncryption(anyInt(), anyBoolean()))
                 .thenReturn(imsiEncryptionInfo);
         Date expirationDate = new Date(mCarrierKeyDM.getExpirationDate());
@@ -157,16 +148,16 @@
     public void testParseJson() {
         Pair<PublicKey, Long> keyInfo = null;
         try {
-            keyInfo = CarrierKeyDownloadManager.getKeyInformation(CERT.getBytes());
+            keyInfo = mCarrierKeyDM.getKeyInformation(CERT.getBytes());
         } catch (Exception e) {
             fail(LOG_TAG + "exception creating public key");
         }
         ImsiEncryptionInfo imsiEncryptionInfo = new ImsiEncryptionInfo("310", "270", 2,
-                "key1=value", keyInfo.first, new Date(keyInfo.second), 1);
+                "key1=value", keyInfo.first, new Date(keyInfo.second));
         String mccMnc = "310270";
-        mCarrierKeyDM.parseJsonAndPersistKey(mJsonStr, mccMnc, 1);
+        mCarrierKeyDM.parseJsonAndPersistKey(mJsonStr, mccMnc);
         verify(mPhone, times(2)).setCarrierInfoForImsiEncryption(
-                (ArgumentMatchers.refEq(imsiEncryptionInfo)));
+                (Matchers.refEq(imsiEncryptionInfo)));
     }
 
     /**
@@ -178,42 +169,16 @@
     public void testParseJsonPublicKey() {
         Pair<PublicKey, Long> keyInfo = null;
         try {
-            keyInfo = CarrierKeyDownloadManager.getKeyInformation(CERT.getBytes());
+            keyInfo = mCarrierKeyDM.getKeyInformation(CERT.getBytes());
         } catch (Exception e) {
             fail(LOG_TAG + "exception creating public key");
         }
-        PublicKey publicKey = keyInfo.first;
         ImsiEncryptionInfo imsiEncryptionInfo = new ImsiEncryptionInfo("310", "270", 2,
-                "key1=value", publicKey, new Date(keyInfo.second), 1);
+                "key1=value", keyInfo.first, new Date(keyInfo.second));
         String mccMnc = "310270";
-        mCarrierKeyDM.parseJsonAndPersistKey(mJsonStr1, mccMnc, 1);
+        mCarrierKeyDM.parseJsonAndPersistKey(mJsonStr1, mccMnc);
         verify(mPhone, times(2)).setCarrierInfoForImsiEncryption(
-                (ArgumentMatchers.refEq(imsiEncryptionInfo)));
-    }
-
-    public void testParseJsonPublicKey(String mcc, String mnc, int carrierId) {
-        Pair<PublicKey, Long> keyInfo = null;
-        try {
-            keyInfo = CarrierKeyDownloadManager.getKeyInformation(CERT.getBytes());
-        } catch (Exception e) {
-            fail(LOG_TAG + "exception creating public key");
-        }
-        ImsiEncryptionInfo imsiEncryptionInfo = new ImsiEncryptionInfo(mcc, mnc, 2,
-                "key1=value", keyInfo.first, new Date(keyInfo.second), carrierId);
-        String mccMnc = mcc + mnc;
-        mCarrierKeyDM.parseJsonAndPersistKey(mJsonStr1, mccMnc, carrierId);
-        verify(mPhone, times(2)).setCarrierInfoForImsiEncryption(
-                (ArgumentMatchers.refEq(imsiEncryptionInfo)));
-    }
-
-    @Test
-    public void testParseJsonPublicKeyOfMNO() {
-        testParseJsonPublicKey("311", "480", 1839);
-    }
-
-    @Test
-    public void testParseJsonPublicKeyOfMVNO() {
-        testParseJsonPublicKey("311", "480", 2146);
+                (Matchers.refEq(imsiEncryptionInfo)));
     }
 
     /**
@@ -225,7 +190,7 @@
     public void testParseBadJsonFail() {
         String mccMnc = "310290";
         String badJsonStr = "{badJsonString}";
-        mCarrierKeyDM.parseJsonAndPersistKey(badJsonStr, mccMnc, 1);
+        mCarrierKeyDM.parseJsonAndPersistKey(badJsonStr, mccMnc);
         verify(mPhone, times(0)).setCarrierInfoForImsiEncryption(any());
     }
 
@@ -238,13 +203,11 @@
     public void testIsValidDownload() {
         String currentMccMnc = "310260";
         long currentDownloadId = 1;
-        int carrierId = 1;
         // mock downloadId to match
         mCarrierKeyDM.mMccMncForDownload = currentMccMnc;
         mCarrierKeyDM.mDownloadId = currentDownloadId;
-        mCarrierKeyDM.mCarrierId = carrierId;
 
-        assertTrue(mCarrierKeyDM.isValidDownload(currentMccMnc, currentDownloadId, carrierId));
+        assertTrue(mCarrierKeyDM.isValidDownload(currentMccMnc, currentDownloadId));
     }
 
     /**
@@ -256,23 +219,16 @@
     public void testIsValidDownloadFail() {
         String currentMccMnc = "310260";
         long currentDownloadId = 1;
-        int carrierId = 1;
 
         // mock downloadId to match, mccmnc so it doesn't match
         mCarrierKeyDM.mMccMncForDownload = "310290";
         mCarrierKeyDM.mDownloadId = currentDownloadId;
-        mCarrierKeyDM.mCarrierId = carrierId;
-        assertFalse(mCarrierKeyDM.isValidDownload(currentMccMnc, currentDownloadId, carrierId));
+        assertFalse(mCarrierKeyDM.isValidDownload(currentMccMnc, currentDownloadId));
 
         // pass in mccmnc to match, and mock shared pref downloadId so it doesn't match
         currentMccMnc = "310290";
         mCarrierKeyDM.mDownloadId = currentDownloadId + 1;
-        assertFalse(mCarrierKeyDM.isValidDownload(currentMccMnc, currentDownloadId, carrierId));
-
-        // mccmnc and downloadID matches but carrierId don't matches
-        mCarrierKeyDM.mDownloadId = currentDownloadId;
-        mCarrierKeyDM.mCarrierId = carrierId + 1;
-        assertFalse(mCarrierKeyDM.isValidDownload(currentMccMnc, currentDownloadId, carrierId));
+        assertFalse(mCarrierKeyDM.isValidDownload(currentMccMnc, currentDownloadId));
     }
 
     /**
@@ -304,21 +260,19 @@
         long downloadId = 1;
         mCarrierKeyDM.mMccMncForDownload = mccMnc;
         mCarrierKeyDM.mDownloadId = downloadId;
-        mCarrierKeyDM.mCarrierId = 1;
 
-        SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd");
+        SimpleDateFormat dt = new SimpleDateFormat("yyyy-mm-dd");
         Calendar expectedCal = new GregorianCalendar();
         expectedCal.add(Calendar.DATE, 1);
         String dateExpected = dt.format(expectedCal.getTime());
 
         when(mTelephonyManager.getSimOperator(anyInt())).thenReturn("310260");
-        when(mTelephonyManager.getSimCarrierId()).thenReturn(1);
         Intent mIntent = new Intent(DownloadManager.ACTION_DOWNLOAD_COMPLETE);
         mIntent.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, downloadId);
         mContext.sendBroadcast(mIntent);
         processAllMessages();
         Date expirationDate = new Date(mCarrierKeyDM.getExpirationDate());
-        assertEquals(dt.format(expirationDate), dateExpected);
+        assertTrue(dt.format(expirationDate).equals(dateExpected));
     }
 
     /**
@@ -336,13 +290,11 @@
         bundle.putString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING, mURL);
 
         when(mTelephonyManager.getSimOperator(anyInt())).thenReturn("310260");
-        when(mTelephonyManager.getSimCarrierId()).thenReturn(1);
         Intent mIntent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
         mIntent.putExtra(PhoneConstants.PHONE_KEY, 0);
         mContext.sendBroadcast(mIntent);
         processAllMessages();
         assertEquals("310260", mCarrierKeyDM.mMccMncForDownload);
-        assertEquals(1, mCarrierKeyDM.mCarrierId);
     }
 
     /**
@@ -365,7 +317,7 @@
         processAllMessages();
         assertNull(mCarrierKeyDM.mMccMncForDownload);
 
-        verify(mPhone).deleteCarrierInfoForImsiEncryption(0);
+        verify(mPhone).deleteCarrierInfoForImsiEncryption();
     }
 
     /**
@@ -383,7 +335,6 @@
         bundle.putString(CarrierConfigManager.IMSI_KEY_DOWNLOAD_URL_STRING, mURL);
 
         when(mTelephonyManager.getSimOperator(anyInt())).thenReturn("310260");
-        when(mTelephonyManager.getSimCarrierId()).thenReturn(1);
         Intent mIntent = new Intent("com.android.internal.telephony.carrier_key_download_alarm");
         mIntent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, slotIndex);
         mContext.sendBroadcast(mIntent);
@@ -405,12 +356,11 @@
         }
         ImsiEncryptionInfo imsiEncryptionInfo = new ImsiEncryptionInfo("310", "270",
                 TelephonyManager.KEY_TYPE_WLAN, "key1=value", keyInfo.first,
-                new Date(CERT_EXPIRATION), 1);
+                new Date(CERT_EXPIRATION));
         String mccMnc = "310270";
-        int carrierId = 1;
-        mCarrierKeyDM.parseJsonAndPersistKey(mJsonStr3GppSpec, mccMnc, carrierId);
+        mCarrierKeyDM.parseJsonAndPersistKey(mJsonStr3GppSpec, mccMnc);
         verify(mPhone).setCarrierInfoForImsiEncryption(
-                (ArgumentMatchers.refEq(imsiEncryptionInfo)));
+                (Matchers.refEq(imsiEncryptionInfo)));
     }
 
     /**
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java
index 221b2b5..aa5d726 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierPrivilegesTrackerTest.java
@@ -16,42 +16,27 @@
 
 package com.android.internal.telephony;
 
+import static android.content.pm.PackageManager.GET_SIGNING_CERTIFICATES;
 import static android.os.UserHandle.SYSTEM;
 import static android.telephony.CarrierConfigManager.EXTRA_SLOT_INDEX;
 import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX;
 import static android.telephony.CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY;
 import static android.telephony.CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL;
 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
-import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
-import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
 import static android.telephony.TelephonyManager.EXTRA_SIM_STATE;
-import static android.telephony.TelephonyManager.SIM_STATE_ABSENT;
 import static android.telephony.TelephonyManager.SIM_STATE_LOADED;
 import static android.telephony.TelephonyManager.SIM_STATE_NOT_READY;
-import static android.telephony.TelephonyManager.SIM_STATE_READY;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.fail;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.annotation.Nullable;
 import android.content.Intent;
-import android.content.pm.ActivityInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
-import android.content.pm.ProviderInfo;
-import android.content.pm.ResolveInfo;
-import android.content.pm.ServiceInfo;
 import android.content.pm.Signature;
 import android.content.pm.UserInfo;
 import android.net.Uri;
@@ -59,34 +44,26 @@
 import android.os.Handler;
 import android.os.Message;
 import android.os.PersistableBundle;
-import android.os.Process;
-import android.service.carrier.CarrierService;
 import android.telephony.CarrierConfigManager;
 import android.telephony.TelephonyManager;
 import android.telephony.UiccAccessRule;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 import android.util.ArraySet;
-import android.util.Pair;
 
 import com.android.internal.telephony.uicc.IccUtils;
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.InOrder;
 import org.mockito.Mock;
 
 import java.security.MessageDigest;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
-import java.util.concurrent.TimeUnit;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -104,13 +81,6 @@
 
     private static final String PACKAGE_1 = "android.test.package1";
     private static final String PACKAGE_2 = "android.test.package2";
-    private static final String PACKAGE_3 = "android.test.package3";
-    private static final String PACKAGE_4 = "android.test.package4";
-    private static final String PACKAGE_5 = "android.test.package5";
-    private static final String PACKAGE_6 = "android.test.package6";
-    private static final String PACKAGE_7 = "android.test.package7";
-    private static final String PACKAGE_8 = "android.test.package8";
-    private static final Set<String> PRIVILEGED_PACKAGES = Set.of(PACKAGE_1, PACKAGE_2);
 
     private static final String CERT_1 = "11223344";
     private static final String CERT_2 = "AABBCCDD";
@@ -120,14 +90,12 @@
 
     private static final int UID_1 = 10000001;
     private static final int UID_2 = 10000002;
-    private static final int UID_3 = 10000003;
     private static final int[] PRIVILEGED_UIDS = {UID_1, UID_2};
-    private static final Set<Integer> PRIVILEGED_UIDS_SET = Set.of(UID_1, UID_2);
 
     private static final int PM_FLAGS =
-            PackageManager.GET_SIGNING_CERTIFICATES
+            PackageManager.MATCH_DISABLED_COMPONENTS
                     | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
-                    | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS;
+                    | PackageManager.GET_SIGNING_CERTIFICATES;
 
     @Mock private Signature mSignature;
 
@@ -154,9 +122,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mHandler = null;
-        mCarrierPrivilegesTracker = null;
-        mCarrierConfigs =  null;
         super.tearDown();
     }
 
@@ -200,10 +165,10 @@
             pkg.signatures = new Signature[] {new Signature(pkgCertInfo.cert)};
 
             when(mPackageManager.getPackageInfo(
-                    eq(pkgCertInfo.pkgName), eq(PM_FLAGS)))
+                            eq(pkgCertInfo.pkgName), eq(GET_SIGNING_CERTIFICATES)))
                     .thenReturn(pkg);
             when(mPackageManager.getPackageUidAsUser(
-                    eq(pkgCertInfo.pkgName), eq(pkgCertInfo.userInfo.id)))
+                            eq(pkgCertInfo.pkgName), eq(pkgCertInfo.userInfo.id)))
                     .thenReturn(pkgCertInfo.uid);
             installedPackages.add(pkg);
         }
@@ -238,8 +203,7 @@
                 carrierConfigRuleString(getHash(CERT_1)), carrierConfigRuleString(getHash(CERT_2)));
         setupInstalledPackages(
                 new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
-                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2),
-                new PackageCertInfo(PACKAGE_3, CERT_3, USER_1, UID_3));
+                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
         mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
     }
 
@@ -247,8 +211,7 @@
         setupSimLoadedRules(ruleWithHashOnly(getHash(CERT_1)), ruleWithHashOnly(getHash(CERT_2)));
         setupInstalledPackages(
                 new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
-                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2),
-                new PackageCertInfo(PACKAGE_3, CERT_3, USER_1, UID_3));
+                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
         mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
     }
 
@@ -275,63 +238,13 @@
         }
     }
 
-    private void verifyCurrentState(Set<String> expectedPackageNames, int[] expectedUids) {
-        assertEquals(
-                expectedPackageNames, mCarrierPrivilegesTracker.getPackagesWithCarrierPrivileges());
-        for (String packageName : expectedPackageNames) {
-            assertEquals(
-                    CARRIER_PRIVILEGE_STATUS_HAS_ACCESS,
-                    mCarrierPrivilegesTracker.getCarrierPrivilegeStatusForPackage(packageName));
-        }
-        for (int uid : expectedUids) {
-            assertEquals(
-                    CARRIER_PRIVILEGE_STATUS_HAS_ACCESS,
-                    mCarrierPrivilegesTracker.getCarrierPrivilegeStatusForUid(uid));
-        }
-    }
-
-    private void verifyRegistrantUpdates(@Nullable int[] expectedUids, int expectedUidUpdates) {
+    private void verifyPrivilegedUids(@Nullable int[] expectedUids, int expectedUidUpdates) {
         assertArrayEquals(expectedUids, mHandler.privilegedUids);
         assertEquals(expectedUidUpdates, mHandler.numUidUpdates);
     }
 
-    private void verifyCarrierPrivilegesChangedUpdates(
-            List<Pair<Set<String>, Set<Integer>>> expectedUpdates) {
-        if (expectedUpdates.isEmpty()) {
-            verify(mTelephonyRegistryManager, never())
-                    .notifyCarrierPrivilegesChanged(anyInt(), any(), any());
-        } else {
-            InOrder inOrder = inOrder(mTelephonyRegistryManager);
-            for (Pair<Set<String>, Set<Integer>> expectedUpdate : expectedUpdates) {
-                // By looking at TelephonyRegistryManager, we can see the full flow as it evolves.
-                inOrder.verify(mTelephonyRegistryManager)
-                        .notifyCarrierPrivilegesChanged(
-                                eq(PHONE_ID),
-                                eq(expectedUpdate.first),
-                                eq(expectedUpdate.second));
-            }
-        }
-    }
-
-    private void verifyCarrierServicesChangedUpdates(List<Pair<String, Integer>> expectedUpdates) {
-        if (expectedUpdates.isEmpty()) {
-            verify(mTelephonyRegistryManager, never())
-                    .notifyCarrierPrivilegesChanged(anyInt(), any(), any());
-        } else {
-            InOrder inOrder = inOrder(mTelephonyRegistryManager);
-            for (Pair<String, Integer> expectedUpdate : expectedUpdates) {
-                // By looking at TelephonyRegistryManager, we can see the full flow as
-                // it evolves.
-                inOrder.verify(mTelephonyRegistryManager)
-                        .notifyCarrierServiceChanged(
-                                eq(PHONE_ID), eq(expectedUpdate.first), eq(expectedUpdate.second));
-            }
-        }
-    }
-
-    @Test
-    public void testRegisterListener() throws Exception {
-        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
+    private void verifyRegisterListener(int[] expectedUids, int expectedUidUpdates)
+            throws Exception {
         // mHandler registered in createCarrierPrivilegesTracker(), so reset it
         mHandler = new CarrierPrivilegesTrackerTestHandler();
 
@@ -339,44 +252,34 @@
                 mHandler, REGISTRANT_WHAT, null);
         mTestableLooper.processAllMessages();
 
-        // No updates triggered, but the registrant gets an empty update.
-        verifyCurrentState(Set.of(), new int[0]);
-        verifyRegistrantUpdates(new int[0] /* expectedUids */, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(List.of());
+        verifyPrivilegedUids(expectedUids, expectedUidUpdates);
+    }
+
+    @Test
+    public void testRegisterListener() throws Exception {
+        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
+
+        verifyRegisterListener(new int[0] /* expectedUids */, 1 /* expectedUidUpdates */);
     }
 
     @Test
     public void testUnregisterListener() throws Exception {
         // Start with privileges. Verify no updates received after clearing UIDs.
         setupCarrierPrivilegesTrackerWithCarrierConfigUids();
-        // mHandler registered in createCarrierPrivilegesTracker(), so reset it
-        mHandler = new CarrierPrivilegesTrackerTestHandler();
 
-        mCarrierPrivilegesTracker.registerCarrierPrivilegesListener(
-                mHandler, REGISTRANT_WHAT, null);
-        mTestableLooper.processAllMessages();
-
-        verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(PRIVILEGED_UIDS /* expectedUids */, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
+        verifyRegisterListener(PRIVILEGED_UIDS, 1 /* expectedUidUpdates */);
         mHandler.reset();
-        reset(mTelephonyRegistryManager);
 
         mCarrierPrivilegesTracker.unregisterCarrierPrivilegesListener(mHandler);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(null /* expectedUids */, 0 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(List.of());
+        verifyPrivilegedUids(null /* expectedUids */, 0 /* expectedUidUpdates */);
 
         // Clear UIDs
         sendCarrierConfigChangedIntent(INVALID_SUBSCRIPTION_ID, PHONE_ID);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(Set.of(), new int[0]);
-        verifyRegistrantUpdates(null /* expectedUids */, 0 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(List.of(new Pair<>(Set.of(), Set.of())));
+        verifyPrivilegedUids(null /* expectedUids */, 0 /* expectedUidUpdates */);
     }
 
     @Test
@@ -392,10 +295,7 @@
         sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(PRIVILEGED_UIDS, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
+        verifyPrivilegedUids(PRIVILEGED_UIDS, 1 /* expectedUidUpdates */);
     }
 
     @Test
@@ -406,10 +306,7 @@
         sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID_INCORRECT);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(null /* expectedUids */, 0 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
+        verifyPrivilegedUids(null /* expectedUids */, 0 /* expectedUidUpdates */);
     }
 
     @Test
@@ -420,12 +317,7 @@
         sendCarrierConfigChangedIntent(INVALID_SUBSCRIPTION_ID, PHONE_ID);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(Set.of(), new int[0]);
-        verifyRegistrantUpdates(new int[0] /* expectedUids */, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(
-                        new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET),
-                        new Pair<>(Set.of(), Set.of())));
+        verifyPrivilegedUids(new int[0] /* expectedUids */, 1 /* expectedUidUpdates */);
     }
 
     @Test
@@ -439,9 +331,7 @@
         sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(Set.of(), new int[0]);
-        verifyRegistrantUpdates(new int[0] /* expectedUids */, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(List.of(new Pair<>(Set.of(), Set.of())));
+        verifyPrivilegedUids(new int[0] /* expectedUids */, 1 /* expectedUidUpdates */);
     }
 
     @Test
@@ -459,10 +349,7 @@
         sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(Set.of(PACKAGE_1), new int[] {UID_1});
-        verifyRegistrantUpdates(new int[] {UID_1}, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(Set.of(PACKAGE_1), Set.of(UID_1))));
+        verifyPrivilegedUids(new int[] {UID_1} /* expectedUids */, 1 /* expectedUidUpdates */);
 
         // Give package 2 privileges again.
         setupCarrierConfigRules(
@@ -472,10 +359,7 @@
         sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(PRIVILEGED_UIDS, 2 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
+        verifyPrivilegedUids(PRIVILEGED_UIDS /* expectedUids */, 2 /* expectedUidUpdates */);
     }
 
     @Test
@@ -491,10 +375,7 @@
         sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(PRIVILEGED_UIDS, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
+        verifyPrivilegedUids(PRIVILEGED_UIDS, 1 /* expectedUidUpdates */);
     }
 
     @Test
@@ -510,10 +391,7 @@
         sendSimApplicationStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(PRIVILEGED_UIDS, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
+        verifyPrivilegedUids(PRIVILEGED_UIDS, 1 /* expectedUidUpdates */);
     }
 
     @Test
@@ -526,12 +404,7 @@
         sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(Set.of(), new int[0]);
-        verifyRegistrantUpdates(new int[0], 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(
-                        new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET),
-                        new Pair<>(Set.of(), Set.of())));
+        verifyPrivilegedUids(new int[0] /* expectedUids */, 1 /* expectedUidUpdates */);
     }
 
     @Test
@@ -544,14 +417,10 @@
         sendSimCardStateChangedIntent(PHONE_ID_INCORRECT, SIM_STATE_LOADED);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(null /* expectedUids */, 0 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
+        verifyPrivilegedUids(null /* expectedUids */, 0 /* expectedUidUpdates */);
     }
 
-    // TODO(b/232273884): turn UT case on when grace period is on
-    @Ignore
+    @Test
     public void testSimStateChangedSimStateNotReady() throws Exception {
         // Start with privileges, verify clearing certs clears UIDs
         setupCarrierPrivilegesTrackerWithSimLoadedUids();
@@ -559,156 +428,7 @@
         sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_NOT_READY);
         mTestableLooper.processAllMessages();
 
-        // Immediately check current state, nothing should change
-        verifyCurrentState(Set.of(PACKAGE_1, PACKAGE_2), new int[]{UID_1, UID_2});
-
-        // Wait for 30 seconds
-        moveTimeForward(TimeUnit.SECONDS.toMillis(30));
-        mTestableLooper.processAllMessages();
-
-        // Check again, the carrier privileges should be emptied
-        verifyCurrentState(Set.of(), new int[0]);
-        verifyRegistrantUpdates(new int[0], 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(
-                        new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET),
-                        new Pair<>(Set.of(), Set.of())));
-    }
-
-    // TODO(b/232273884): turn UT case on when grace period is on
-    @Ignore
-    public void testSimStateChangedSimStateAbsentThenLoadedWithSameRules() throws Exception {
-        // Start with privileges
-        setupCarrierPrivilegesTrackerWithSimLoadedUids();
-        // CPT initialization process may trigger notification, remove the interfere here
-        reset(mTelephonyRegistryManager);
-
-        // SIM is removed
-        sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_ABSENT);
-        mTestableLooper.processAllMessages();
-
-
-        // Wait for 20 seconds and the same SIM is inserted
-        moveTimeForward(TimeUnit.SECONDS.toMillis(20));
-        sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
-        mTestableLooper.processAllMessages();
-        // Wait for another 20 seconds
-        moveTimeForward(TimeUnit.SECONDS.toMillis(20));
-
-        // verify all carrier privileges should remain, no CP change notified
-        verifyCurrentState(Set.of(PACKAGE_1, PACKAGE_2), new int[]{UID_1, UID_2});
-        verifyRegistrantUpdates(null /* expectedUidUpdates */, 0 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(List.of());
-    }
-
-    @Test
-    public void testSimStateChangedSimStateAbsentForever() throws Exception {
-        // Start with privileges
-        setupCarrierPrivilegesTrackerWithSimLoadedUids();
-        // CPT initialization process may trigger notification, remove the interfere here
-        reset(mTelephonyRegistryManager);
-
-        // SIM is removed
-        sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_ABSENT);
-        mTestableLooper.processAllMessages();
-
-        // Wait for 30 seconds
-        moveTimeForward(TimeUnit.SECONDS.toMillis(30));
-        mTestableLooper.processAllMessages();
-
-        // verify the carrier privileges should be emptied
-        verifyCurrentState(Set.of(), new int[0]);
-        verifyRegistrantUpdates(new int[0], 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(Set.of(), Set.of())));
-    }
-
-    @Test
-    public void testSimStateChangedSimStateNotReadyForever() throws Exception {
-        // Start with privileges
-        setupCarrierPrivilegesTrackerWithSimLoadedUids();
-        // CPT initialization process may trigger notification, remove the interfere here
-        reset(mTelephonyRegistryManager);
-
-        // eSIM profile disabled and leave in state SIM_STATE_NOT_READY
-        sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_NOT_READY);
-        mTestableLooper.processAllMessages();
-
-        // Wait for 30 seconds
-        moveTimeForward(TimeUnit.SECONDS.toMillis(30));
-        mTestableLooper.processAllMessages();
-
-        // verify the carrier privileges should be emptied
-        verifyCurrentState(Set.of(), new int[0]);
-        verifyRegistrantUpdates(new int[0], 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(Set.of(), Set.of())));
-    }
-
-    // TODO(b/232273884): turn UT case on when grace period is on
-    @Ignore
-    public void testSimStateChangedSimStateAbsentThenLoadedWithUpdatedRules() throws Exception {
-        // Start with privileges
-        setupCarrierPrivilegesTrackerWithSimLoadedUids();
-        reset(mTelephonyRegistryManager);
-
-        // SIM is removed
-        sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_ABSENT);
-        mTestableLooper.processAllMessages();
-
-
-        // Wait for 20 seconds and a different SIM is inserted
-        moveTimeForward(TimeUnit.SECONDS.toMillis(20));
-        setupSimLoadedRules(ruleWithHashOnly(getHash(CERT_1)));
-        sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
-        mTestableLooper.processAllMessages();
-        // Wait for another 20 seconds
-        moveTimeForward(TimeUnit.SECONDS.toMillis(20));
-
-        // Carrier privileges should be updated and CP change should be notified
-        verifyCurrentState(Set.of(PACKAGE_1), new int[] {UID_1});
-        verifyRegistrantUpdates(new int[] {UID_1}, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(Set.of(PACKAGE_1), Set.of(UID_1))));
-    }
-
-    @Test
-    public void testSimStateChangedSimStateReadyThenLoaded() throws Exception {
-        // Start with privileges (from carrier config)
-        setupCarrierPrivilegesTrackerWithCarrierConfigUids();
-
-        ResolveInfo pkg1ResolveInfo = new ResolveInfoBuilder().setActivity(PACKAGE_1).build();
-        ResolveInfo pkg2ResolveInfo = new ResolveInfoBuilder().setActivity(PACKAGE_2).build();
-        when(mPackageManager.queryBroadcastReceivers(any(), anyInt())).thenReturn(
-                List.of(pkg1ResolveInfo, pkg2ResolveInfo));
-
-        // SIM is READY
-        sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_READY);
-        mTestableLooper.processAllMessages();
-
-        assertEquals(Collections.emptyList(),
-                mCarrierPrivilegesTracker.getCarrierPackageNamesForIntent(
-                        new Intent(CarrierService.CARRIER_SERVICE_INTERFACE)));
-        assertEquals(CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED,
-                mCarrierPrivilegesTracker.getCarrierPrivilegeStatusForUid(UID_1));
-        assertEquals(Collections.EMPTY_SET,
-                mCarrierPrivilegesTracker.getPackagesWithCarrierPrivileges());
-        assertEquals(CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED,
-                mCarrierPrivilegesTracker.getCarrierPrivilegeStatusForPackage(PACKAGE_1));
-
-        // SIM is LOADED
-        sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
-        mTestableLooper.processAllMessages();
-
-        assertEquals(List.of(PACKAGE_1, PACKAGE_2),
-                mCarrierPrivilegesTracker.getCarrierPackageNamesForIntent(
-                        new Intent(CarrierService.CARRIER_SERVICE_INTERFACE)));
-        assertEquals(CARRIER_PRIVILEGE_STATUS_HAS_ACCESS,
-                mCarrierPrivilegesTracker.getCarrierPrivilegeStatusForUid(UID_1));
-        assertEquals(PRIVILEGED_PACKAGES,
-                mCarrierPrivilegesTracker.getPackagesWithCarrierPrivileges());
-        assertEquals(CARRIER_PRIVILEGE_STATUS_HAS_ACCESS,
-                mCarrierPrivilegesTracker.getCarrierPrivilegeStatusForPackage(PACKAGE_1));
+        verifyPrivilegedUids(new int[0] /* expectedUids */, 1 /* expectedUidUpdates */);
     }
 
     @Test
@@ -726,10 +446,7 @@
         sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(Set.of(PACKAGE_1), new int[] {UID_1});
-        verifyRegistrantUpdates(new int[] {UID_1}, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(Set.of(PACKAGE_1), Set.of(UID_1))));
+        verifyPrivilegedUids(new int[] {UID_1} /* expectedUids */, 1 /* expectedUidUpdates */);
 
         // Give package 2 privileges again.
         setupSimLoadedRules(
@@ -740,10 +457,7 @@
         sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(PRIVILEGED_UIDS, 2 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
+        verifyPrivilegedUids(PRIVILEGED_UIDS /* expectedUids */, 2 /* expectedUidUpdates */);
     }
 
     @Test
@@ -757,10 +471,7 @@
         sendPackageChangedIntent(Intent.ACTION_PACKAGE_ADDED, PACKAGE_1);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(Set.of(PACKAGE_1), new int[] {UID_1});
-        verifyRegistrantUpdates(new int[] {UID_1}, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(Set.of(PACKAGE_1), Set.of(UID_1))));
+        verifyPrivilegedUids(new int[] {UID_1}, 1 /* expectedUidUpdates */);
     }
 
     @Test
@@ -777,10 +488,7 @@
         sendPackageChangedIntent(Intent.ACTION_PACKAGE_ADDED, PACKAGE_1);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(Set.of(PACKAGE_1), PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(PRIVILEGED_UIDS, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(Set.of(PACKAGE_1), PRIVILEGED_UIDS_SET)));
+        verifyPrivilegedUids(PRIVILEGED_UIDS, 1 /* expectedUidUpdates */);
     }
 
     @Test
@@ -798,10 +506,7 @@
         sendPackageChangedIntent(Intent.ACTION_PACKAGE_REPLACED, PACKAGE_1);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(Set.of(PACKAGE_1), PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(PRIVILEGED_UIDS, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(Set.of(PACKAGE_1), PRIVILEGED_UIDS_SET)));
+        verifyPrivilegedUids(PRIVILEGED_UIDS, 1 /* expectedUidUpdates */);
     }
 
     @Test
@@ -817,16 +522,13 @@
         // Update PACKAGE_1 to have no signatures
         PackageInfo pkg = new PackageInfo();
         pkg.packageName = PACKAGE_1;
-        when(mPackageManager.getPackageInfo(eq(PACKAGE_1), eq(PM_FLAGS)))
+        when(mPackageManager.getPackageInfo(eq(PACKAGE_1), eq(GET_SIGNING_CERTIFICATES)))
                 .thenReturn(pkg);
 
         sendPackageChangedIntent(Intent.ACTION_PACKAGE_ADDED, PACKAGE_1);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(Set.of(PACKAGE_2), new int[] {UID_2});
-        verifyRegistrantUpdates(new int[] {UID_2}, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(Set.of(PACKAGE_2), Set.of(UID_2))));
+        verifyPrivilegedUids(new int[] {UID_2} /* expectedUids */, 1 /* expectedUidUpdates */);
     }
 
     @Test
@@ -847,10 +549,7 @@
         sendPackageChangedIntent(Intent.ACTION_PACKAGE_ADDED, PACKAGE_1);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(Set.of(PACKAGE_2), new int[] {UID_2});
-        verifyRegistrantUpdates(new int[] {UID_2}, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(Set.of(PACKAGE_2), Set.of(UID_2))));
+        verifyPrivilegedUids(new int[] {UID_2} /* expectedUids */, 1 /* expectedUidUpdates */);
     }
 
     @Test
@@ -866,10 +565,7 @@
         sendPackageChangedIntent(Intent.ACTION_PACKAGE_REMOVED, PACKAGE_1);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(Set.of(PACKAGE_2), new int[] {UID_2});
-        verifyRegistrantUpdates(new int[] {UID_2}, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(Set.of(PACKAGE_2), Set.of(UID_2))));
+        verifyPrivilegedUids(new int[] {UID_2} /* expectedUids */, 1 /* expectedUidUpdates */);
     }
 
     @Test
@@ -881,253 +577,7 @@
         sendPackageChangedIntent(Intent.ACTION_PACKAGE_REMOVED, PACKAGE_1);
         mTestableLooper.processAllMessages();
 
-        verifyCurrentState(Set.of(), new int[0]);
-        verifyRegistrantUpdates(null /* expectedUidUpdates */, 0 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(List.of());
-    }
-
-    @Test
-    public void testPackageDisabledAndThenEnabled() throws Exception {
-        // Start with certs and packages installed
-        setupCarrierConfigRules(carrierConfigRuleString(getHash(CERT_1)));
-        setupInstalledPackages(
-                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
-                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
-        when(mPackageManager.getPackageUid(eq(PACKAGE_1), anyInt())).thenReturn(UID_1);
-        when(mPackageManager.getPackageUid(eq(PACKAGE_2), anyInt())).thenReturn(UID_2);
-        ResolveInfo resolveInfoPkg1 = new ResolveInfoBuilder().setService(PACKAGE_1).build();
-        doReturn(List.of(resolveInfoPkg1))
-                .when(mPackageManager)
-                .queryIntentServices(any(), anyInt());
-        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
-
-        // Package_1 is disabled
-        when(mPackageManager.getApplicationEnabledSetting(eq(PACKAGE_1))).thenReturn(
-                PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
-        doReturn(List.of()).when(
-                mPackageManager).queryIntentServices(any(), anyInt());
-        sendPackageChangedIntent(Intent.ACTION_PACKAGE_CHANGED, PACKAGE_1);
-        mTestableLooper.processAllMessages();
-
-        verifyCurrentState(Set.of(), new int[0]);
-        verifyCarrierPrivilegesChangedUpdates(List.of(new Pair<>(Set.of(), Set.of())));
-        verifyCarrierServicesChangedUpdates(List.of(new Pair<>(null, -1)));
-
-        // Package_1 is re-enabled
-        when(mPackageManager.getApplicationEnabledSetting(eq(PACKAGE_1))).thenReturn(
-                PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
-        doReturn(List.of(resolveInfoPkg1)).when(
-                mPackageManager).queryIntentServices(any(), anyInt());
-        sendPackageChangedIntent(Intent.ACTION_PACKAGE_CHANGED, PACKAGE_1);
-        mTestableLooper.processAllMessages();
-
-        verifyCurrentState(Set.of(PACKAGE_1), new int[] {UID_1});
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(Set.of(PACKAGE_1), Set.of(UID_1))));
-        verifyCarrierServicesChangedUpdates(List.of(new Pair<>(PACKAGE_1, UID_1)));
-    }
-
-    @Test
-    public void testSetCarrierTestOverrideWithEmptyRule() throws Exception {
-        // Start with PACKAGE_1 & PACKAGE_2 installed and have privileges from CarrierConfig
-        setupCarrierPrivilegesTrackerWithCarrierConfigUids();
-
-        // Set test override with EMPTY rule
-        mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules("");
-        mTestableLooper.processAllMessages();
-
-        // Expect no package will have privilege at last
-        verifyCurrentState(Set.of(), new int[0]);
-        verifyRegistrantUpdates(new int[0], 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(
-                        new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET),
-                        new Pair<>(Set.of(), Set.of())));
-
-        // Set test override with null rule to revoke previous test override
-        mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(null);
-        mTestableLooper.processAllMessages();
-
-        // Expect all privileges from Carrier Config come back
-        verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(PRIVILEGED_UIDS, 2 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
-    }
-
-    @Test
-    public void testSetCarrierTestOverrideWithNonEmptyRule() throws Exception {
-        // Start with PACKAGE_1 & PACKAGE_2 installed and have privileges from UICC
-        setupCarrierPrivilegesTrackerWithSimLoadedUids();
-
-        // Set test override with non-EMPTY rule (PACKAGE_3)
-        mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(getHash(CERT_3));
-        mTestableLooper.processAllMessages();
-
-        // Expect only PACKAGE_3 will have privilege at last
-        verifyCurrentState(Set.of(PACKAGE_3), new int[]{UID_3});
-        verifyRegistrantUpdates(new int[]{UID_3}, 1 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(
-                        new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET),
-                        new Pair<>(Set.of(PACKAGE_3), Set.of(UID_3))));
-
-
-        // Set test override with null rule to revoke previous test override
-        mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(null);
-        mTestableLooper.processAllMessages();
-
-        // Expect all privileges from UICC come back
-        verifyCurrentState(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS);
-        verifyRegistrantUpdates(PRIVILEGED_UIDS, 2 /* expectedUidUpdates */);
-        verifyCarrierPrivilegesChangedUpdates(
-                List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS_SET)));
-    }
-
-    @Test
-    public void testGetCarrierPackageNameForIntent() throws Exception {
-        // Only packages with CERT_1 have carrier privileges
-        setupCarrierConfigRules(carrierConfigRuleString(getHash(CERT_1)));
-        // Setup all odd packages privileged, even packages not
-        setupInstalledPackages(
-                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
-                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2),
-                new PackageCertInfo(PACKAGE_3, CERT_1, USER_1, UID_1),
-                new PackageCertInfo(PACKAGE_4, CERT_2, USER_1, UID_2),
-                new PackageCertInfo(PACKAGE_5, CERT_1, USER_1, UID_1),
-                new PackageCertInfo(PACKAGE_6, CERT_2, USER_1, UID_2),
-                new PackageCertInfo(PACKAGE_7, CERT_1, USER_1, UID_1),
-                new PackageCertInfo(PACKAGE_8, CERT_2, USER_1, UID_2));
-
-        ResolveInfo privilegeBroadcast = new ResolveInfoBuilder().setActivity(PACKAGE_1).build();
-        ResolveInfo noPrivilegeBroadcast = new ResolveInfoBuilder().setActivity(PACKAGE_2).build();
-        when(mPackageManager.queryBroadcastReceivers(any(), anyInt())).thenReturn(
-                List.of(privilegeBroadcast, noPrivilegeBroadcast));
-
-        ResolveInfo privilegeActivity = new ResolveInfoBuilder().setActivity(PACKAGE_3).build();
-        ResolveInfo noPrivilegeActivity = new ResolveInfoBuilder().setActivity(PACKAGE_4).build();
-        when(mPackageManager.queryIntentActivities(any(), anyInt())).thenReturn(
-                List.of(privilegeActivity, noPrivilegeActivity));
-
-        ResolveInfo privilegeService = new ResolveInfoBuilder().setService(PACKAGE_5).build();
-        ResolveInfo noPrivilegeService = new ResolveInfoBuilder().setService(PACKAGE_6).build();
-        // Use doReturn instead of when/thenReturn which has NPE with unknown reason
-        doReturn(List.of(privilegeService, noPrivilegeService)).when(
-                mPackageManager).queryIntentServices(any(), anyInt());
-
-        ResolveInfo privilegeProvider = new ResolveInfoBuilder().setProvider(PACKAGE_7).build();
-        ResolveInfo noPrivilegeProvider = new ResolveInfoBuilder().setProvider(PACKAGE_8).build();
-        when(mPackageManager.queryIntentContentProviders(any(), anyInt())).thenReturn(
-                List.of(privilegeProvider, noPrivilegeProvider));
-
-        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
-        Intent intent = new Intent(CarrierService.CARRIER_SERVICE_INTERFACE);
-        List<String> carrierPackageNames =
-                mCarrierPrivilegesTracker.getCarrierPackageNamesForIntent(intent);
-        mTestableLooper.processAllMessages();
-
-        // Order of the result packages doesn't matter. Comparing the Set instead of the List
-        assertEquals(Set.of(PACKAGE_1, PACKAGE_3, PACKAGE_5, PACKAGE_7),
-                new HashSet<>(carrierPackageNames));
-    }
-
-    @Test
-    public void testGetCarrierService_haveCarrierServiceWithCarrierPrivileges() throws Exception {
-        // Only packages with CERT_1 have carrier privileges
-        setupCarrierConfigRules(carrierConfigRuleString(getHash(CERT_1)));
-        // Setup all odd packages privileged, even packages not
-        setupInstalledPackages(
-                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
-                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2),
-                new PackageCertInfo(PACKAGE_3, CERT_1, USER_1, UID_1));
-        // Two declared CarrierService, only PACKAGE_1 has carrier privileges
-        ResolveInfo privilegeService = new ResolveInfoBuilder().setService(PACKAGE_1).build();
-        ResolveInfo noPrivilegeService = new ResolveInfoBuilder().setService(PACKAGE_2).build();
-        // Use doReturn instead of when/thenReturn which has NPE with unknown reason
-        doReturn(List.of(privilegeService, noPrivilegeService)).when(
-                mPackageManager).queryIntentServices(any(), anyInt());
-        when(mPackageManager.getPackageUid(eq(PACKAGE_1), anyInt())).thenReturn(UID_1);
-        when(mPackageManager.getPackageUid(eq(PACKAGE_2), anyInt())).thenReturn(UID_2);
-        when(mPackageManager.getPackageUid(eq(PACKAGE_3), anyInt())).thenReturn(UID_1);
-
-        // Get CS package name for the first time
-        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
-        String carrierServicePackageName = mCarrierPrivilegesTracker.getCarrierServicePackageName();
-        int carrierServiceUid = mCarrierPrivilegesTracker.getCarrierServicePackageUid();
-        mTestableLooper.processAllMessages();
-
-        // Package manager should be queried from
-        verify(mPackageManager).queryIntentServices(any(), anyInt());
-        assertEquals(PACKAGE_1, carrierServicePackageName);
-        assertEquals(UID_1, carrierServiceUid);
-
-
-        reset(mPackageManager);
-        // Get CS again
-        carrierServicePackageName = mCarrierPrivilegesTracker.getCarrierServicePackageName();
-        carrierServiceUid = mCarrierPrivilegesTracker.getCarrierServicePackageUid();
-        mTestableLooper.processAllMessages();
-
-        // It should return the same result, but didn't query package manager
-        verify(mPackageManager, never()).queryIntentServices(any(), anyInt());
-        assertEquals(PACKAGE_1, carrierServicePackageName);
-        assertEquals(UID_1, carrierServiceUid);
-
-    }
-
-    @Test
-    public void testGetCarrierService_haveCarrierServiceWithNoCarrierPrivileges() throws Exception {
-        // Only packages with CERT_1 have carrier privileges
-        setupCarrierConfigRules(carrierConfigRuleString(getHash(CERT_1)));
-        // Setup all odd packages privileged, even packages not
-        setupInstalledPackages(
-                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
-                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2),
-                new PackageCertInfo(PACKAGE_3, CERT_1, USER_1, UID_1));
-        // One declared CarrierService which has no carrier privileges
-        ResolveInfo noPrivilegeService = new ResolveInfoBuilder().setService(PACKAGE_2).build();
-        // Use doReturn instead of when/thenReturn which has NPE with unknown reason
-        doReturn(List.of(noPrivilegeService)).when(
-                mPackageManager).queryIntentServices(any(), anyInt());
-        when(mPackageManager.getPackageUid(eq(PACKAGE_1), anyInt())).thenReturn(UID_1);
-        when(mPackageManager.getPackageUid(eq(PACKAGE_2), anyInt())).thenReturn(UID_2);
-        when(mPackageManager.getPackageUid(eq(PACKAGE_3), anyInt())).thenReturn(UID_1);
-
-        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
-        String carrierServicePackageName = mCarrierPrivilegesTracker.getCarrierServicePackageName();
-        int carrierServiceUid = mCarrierPrivilegesTracker.getCarrierServicePackageUid();
-        mTestableLooper.processAllMessages();
-
-        verify(mPackageManager).queryIntentServices(any(), anyInt());
-        assertNull(carrierServicePackageName);
-        assertEquals(Process.INVALID_UID, carrierServiceUid);
-    }
-
-    @Test
-    public void testGetCarrierService_haveNoCarrierService() throws Exception {
-        // Only packages with CERT_1 have carrier privileges
-        setupCarrierConfigRules(carrierConfigRuleString(getHash(CERT_1)));
-        // Setup all odd packages privileged, even packages not
-        setupInstalledPackages(
-                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
-                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2),
-                new PackageCertInfo(PACKAGE_3, CERT_1, USER_1, UID_1));
-        // No CarrierService declared at all
-        // Use doReturn instead of when/thenReturn which has NPE with unknown reason
-        doReturn(List.of()).when(
-                mPackageManager).queryIntentServices(any(), anyInt());
-        when(mPackageManager.getPackageUid(eq(PACKAGE_1), anyInt())).thenReturn(UID_1);
-        when(mPackageManager.getPackageUid(eq(PACKAGE_2), anyInt())).thenReturn(UID_2);
-        when(mPackageManager.getPackageUid(eq(PACKAGE_3), anyInt())).thenReturn(UID_1);
-
-        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
-        String carrierServicePackageName = mCarrierPrivilegesTracker.getCarrierServicePackageName();
-        int carrierServiceUid = mCarrierPrivilegesTracker.getCarrierServicePackageUid();
-        mTestableLooper.processAllMessages();
-
-        assertNull(carrierServicePackageName);
-        assertEquals(Process.INVALID_UID, carrierServiceUid);
-        verify(mPackageManager).queryIntentServices(any(), anyInt());
+        verifyPrivilegedUids(null /* expectedUids */, 0 /* expectedUidUpdates */);
     }
 
     private void sendCarrierConfigChangedIntent(int subId, int phoneId) {
@@ -1175,39 +625,4 @@
             this.uid = uid;
         }
     }
-
-    /**
-     * Utility class to build {@link ResolveInfo} for testing.
-     */
-    private static final class ResolveInfoBuilder {
-        private ActivityInfo mActivityInfo;
-        private ServiceInfo mServiceInfo;
-        private ProviderInfo mProviderInfo;
-
-        public ResolveInfoBuilder setActivity(String packageName) {
-            mActivityInfo = new ActivityInfo();
-            mActivityInfo.packageName = packageName;
-            return this;
-        }
-
-        public ResolveInfoBuilder setService(String packageName) {
-            mServiceInfo = new ServiceInfo();
-            mServiceInfo.packageName = packageName;
-            return this;
-        }
-
-        public ResolveInfoBuilder setProvider(String packageName) {
-            mProviderInfo = new ProviderInfo();
-            mProviderInfo.packageName = packageName;
-            return this;
-        }
-
-        public ResolveInfo build() {
-            ResolveInfo resolveInfo = new ResolveInfo();
-            resolveInfo.activityInfo = mActivityInfo;
-            resolveInfo.serviceInfo = mServiceInfo;
-            resolveInfo.providerInfo = mProviderInfo;
-            return resolveInfo;
-        }
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceBindHelperTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceBindHelperTest.java
index 8ce11ae..a35f64b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceBindHelperTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceBindHelperTest.java
@@ -18,15 +18,10 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
 
 import android.os.Message;
-import android.telephony.TelephonyManager.CarrierPrivilegesCallback;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -35,14 +30,10 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class CarrierServiceBindHelperTest extends TelephonyTest {
-    private static final int PHONE_ID_0 = 0;
-    private static final int PHONE_ID_1 = 1;
-
     CarrierServiceBindHelper mCarrierServiceBindHelper;
     @Before
     public void setUp() throws Exception {
@@ -52,7 +43,7 @@
 
     @After
     public void tearDown() throws Exception {
-        mCarrierServiceBindHelper = null;
+        // Restore system properties.
         super.tearDown();
     }
 
@@ -99,38 +90,4 @@
                         CarrierServiceBindHelper.EVENT_PERFORM_IMMEDIATE_UNBIND,
                         new Integer(0)));
     }
-
-    @Test
-    public void testCarrierPrivilegesCallbackRegistration() {
-        // Device starts with DSDS mode
-        doReturn(2).when(mTelephonyManager).getActiveModemCount();
-        mCarrierServiceBindHelper = new CarrierServiceBindHelper(mContext);
-        processAllMessages();
-
-        // Verify that CarrierPrivilegesCallbacks are registered on both phones.
-        // Capture the callbacks for further verification
-        ArgumentCaptor<CarrierPrivilegesCallback> phone0CallbackCaptor = ArgumentCaptor.forClass(
-                CarrierPrivilegesCallback.class);
-        verify(mTelephonyManager).registerCarrierPrivilegesCallback(eq(PHONE_ID_0), any(),
-                phone0CallbackCaptor.capture());
-        CarrierPrivilegesCallback phone0Callback = phone0CallbackCaptor.getAllValues().get(0);
-        assertNotNull(phone0Callback);
-
-        ArgumentCaptor<CarrierPrivilegesCallback> phone1CallbackCaptor = ArgumentCaptor.forClass(
-                CarrierPrivilegesCallback.class);
-        verify(mTelephonyManager).registerCarrierPrivilegesCallback(eq(PHONE_ID_1), any(),
-                phone1CallbackCaptor.capture());
-        CarrierPrivilegesCallback phone1Callback = phone1CallbackCaptor.getAllValues().get(0);
-        assertNotNull(phone1Callback);
-
-        // Switch back to single SIM.
-        doReturn(1).when(mTelephonyManager).getActiveModemCount();
-        PhoneConfigurationManager.notifyMultiSimConfigChange(1);
-        processAllMessages();
-
-        // Verify the callback for phone1 had been unregistered while phone0 didn't.
-        verify(mTelephonyManager).unregisterCarrierPrivilegesCallback(eq(phone1Callback));
-        verify(mTelephonyManager, never()).unregisterCarrierPrivilegesCallback(eq(phone0Callback));
-    }
-    // TODO (b/232461097): Add UT cases to cover more scenarios (user unlock, SIM state change...)
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceStateTrackerTest.java
index 07cf0b9..c3eac09 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierServiceStateTrackerTest.java
@@ -90,10 +90,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mCarrierSST = null;
-        mSpyCarrierSST = null;
-        mBundle = null;
-        mNotificationManager = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierServicesSmsFilterTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierServicesSmsFilterTest.java
index 00adc39..88481dc 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierServicesSmsFilterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierServicesSmsFilterTest.java
@@ -23,13 +23,14 @@
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.os.Looper;
 import android.os.RemoteException;
@@ -39,9 +40,13 @@
 import android.service.carrier.MessagePdu;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.internal.telephony.LocalLog;
+import com.android.internal.telephony.uicc.UiccCard;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
@@ -57,19 +62,18 @@
     private static final String SYSTEM_APP_PACKAGE_NAME = "com.android.system";
 
     private CarrierServicesSmsFilter mCarrierServicesSmsFilterUT;
-
-    // Mocked classes
+    @Mock
     private CarrierServicesSmsFilter.CarrierServicesSmsFilterCallbackInterface mFilterCallback;
+    @Mock
+    private UiccCard mUiccCard;
+    @Mock
     private ICarrierMessagingService.Stub mICarrierAppMessagingService;
+    @Mock
     private ICarrierMessagingService.Stub mISystemCarrierMessagingService;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mFilterCallback = mock(
-                CarrierServicesSmsFilter.CarrierServicesSmsFilterCallbackInterface.class);
-        mICarrierAppMessagingService = mock(ICarrierMessagingService.Stub.class);
-        mISystemCarrierMessagingService = mock(ICarrierMessagingService.Stub.class);
         if (Looper.myLooper() == null) {
             Looper.prepare();
         }
@@ -80,7 +84,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mCarrierServicesSmsFilterUT = null;
         super.tearDown();
     }
 
@@ -175,10 +178,11 @@
     }
 
     private void mockUiccWithCarrierApp() {
+        when(mUiccController.getUiccCard(mPhone.getPhoneId())).thenReturn(mUiccCard);
         List<String> carrierPackages = new ArrayList<>();
         carrierPackages.add(CARRIER_APP_PACKAGE_NAME);
-        when(mCarrierPrivilegesTracker.getCarrierPackageNamesForIntent(any()))
-                .thenReturn(carrierPackages);
+        when(mUiccCard.getCarrierPackageNamesForIntent(
+                any(PackageManager.class), any(Intent.class))).thenReturn(carrierPackages);
     }
 
     private void mockSystemApp() {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CarrierSignalAgentTest.java b/tests/telephonytests/src/com/android/internal/telephony/CarrierSignalAgentTest.java
index e070b06..85aafcf 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CarrierSignalAgentTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CarrierSignalAgentTest.java
@@ -30,7 +30,6 @@
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.argThat;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -56,6 +55,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -104,14 +104,13 @@
                 TelephonyManager.EXTRA_DEFAULT_NETWORK_AVAILABLE, true);
     }
 
-    // Mocked classes
+    @Mock
     ResolveInfo mResolveInfo;
 
     @Before
     public void setUp() throws Exception {
         logd("CarrierSignalAgentTest +Setup!");
         super.setUp(getClass().getSimpleName());
-        mResolveInfo = mock(ResolveInfo.class);
         mBundle = mContextFixture.getCarrierConfigBundle();
         mCarrierSignalAgentUT = new CarrierSignalAgent(mPhone);
 
@@ -135,8 +134,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mCarrierSignalAgentUT = null;
-        mBundle = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityLteTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityLteTest.java
index 3eb8d21..d3b3e59 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellIdentityLteTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellIdentityLteTest.java
@@ -263,7 +263,7 @@
                 new android.hardware.radio.V1_5.CellIdentityLte();
         cid.bands = Arrays.stream(BANDS).boxed().collect(Collectors.toCollection(ArrayList::new));
 
-        CellIdentityLte cellIdentityLte = RILUtils.convertHalCellIdentityLte(cid);
+        CellIdentityLte cellIdentityLte = new CellIdentityLte(cid);
         assertTrue(Arrays.equals(cellIdentityLte.getBands(), BANDS));
 
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthNrTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthNrTest.java
index 8dc028e..a294471 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthNrTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellSignalStrengthNrTest.java
@@ -20,12 +20,9 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 
 import android.hardware.radio.V1_6.NrSignalStrength;
 import android.os.Parcel;
-import android.os.PersistableBundle;
-import android.telephony.CarrierConfigManager;
 import android.telephony.CellInfo;
 import android.telephony.CellSignalStrength;
 import android.telephony.CellSignalStrengthNr;
@@ -37,6 +34,7 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -59,13 +57,12 @@
     private static final int SSRSRQ = -13;
     private static final int SSSINR = 32;
 
-    // Mocked classes
+    @Mock
     ServiceState mSS;
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mSS = mock(ServiceState.class);
+        super.setUp(this.getClass().getSimpleName());
     }
 
     @After
@@ -111,7 +108,7 @@
         nrSignalStrength.base.ssSinr = SSSINR;
 
         // THEN the get method should return the correct value
-        CellSignalStrengthNr css = RILUtils.convertHalNrSignalStrength(nrSignalStrength);
+        CellSignalStrengthNr css = new CellSignalStrengthNr(nrSignalStrength);
         assertThat(css.getCsiRsrp()).isEqualTo(CSIRSRP);
         assertThat(css.getCsiRsrq()).isEqualTo(CSIRSRQ);
         assertThat(css.getCsiSinr()).isEqualTo(CSISINR);
@@ -137,7 +134,7 @@
         nrSignalStrength.base.ssSinr = CellInfo.UNAVAILABLE;
 
         // THEN the get method should return unavailable value
-        CellSignalStrengthNr css = RILUtils.convertHalNrSignalStrength(nrSignalStrength);
+        CellSignalStrengthNr css = new CellSignalStrengthNr(nrSignalStrength);
         assertThat(css.getCsiRsrp()).isEqualTo(CellInfo.UNAVAILABLE);
         assertThat(css.getCsiRsrq()).isEqualTo(CellInfo.UNAVAILABLE);
         assertThat(css.getCsiSinr()).isEqualTo(CellInfo.UNAVAILABLE);
@@ -257,41 +254,4 @@
         css.updateLevel(null, mSS);
         assertEquals(1 /* MODERATE */, css.getLevel());
     }
-
-    @Test
-    public void testSignalLevel_ThresholdBoundaries() {
-        int[] ssRsrpThresholds = {
-                -110, /* SIGNAL_STRENGTH_POOR */
-                -90,  /* SIGNAL_STRENGTH_MODERATE */
-                -80,  /* SIGNAL_STRENGTH_GOOD */
-                -65,  /* SIGNAL_STRENGTH_GREAT */
-        };
-        PersistableBundle bundle = new PersistableBundle();
-        bundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
-                CellSignalStrengthNr.USE_SSRSRP);
-        bundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY,
-                ssRsrpThresholds);
-
-        CellSignalStrengthNr css;
-
-        css = new CellSignalStrengthNr(CSIRSRP, CSIRSRQ, CSISINR, ssRsrpThresholds[0], SSRSRQ,
-                SSSINR);
-        css.updateLevel(bundle, null);
-        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_POOR, css.getLevel());
-
-        css = new CellSignalStrengthNr(CSIRSRP, CSIRSRQ, CSISINR, ssRsrpThresholds[1], SSRSRQ,
-                SSSINR);
-        css.updateLevel(bundle, null);
-        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_MODERATE, css.getLevel());
-
-        css = new CellSignalStrengthNr(CSIRSRP, CSIRSRQ, CSISINR, ssRsrpThresholds[2], SSRSRQ,
-                SSSINR);
-        css.updateLevel(bundle, null);
-        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_GOOD, css.getLevel());
-
-        css = new CellSignalStrengthNr(CSIRSRP, CSIRSRQ, CSISINR, ssRsrpThresholds[3], SSRSRQ,
-                SSSINR);
-        css.updateLevel(bundle, null);
-        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_GREAT, css.getLevel());
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
index 8cd5dc3..1b187ef 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkServiceTest.java
@@ -16,11 +16,9 @@
 
 package com.android.internal.telephony;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
@@ -28,9 +26,6 @@
 import android.content.pm.ServiceInfo;
 import android.os.RemoteException;
 import android.telephony.AccessNetworkConstants;
-import android.telephony.CellIdentityGsm;
-import android.telephony.CellIdentityLte;
-import android.telephony.CellIdentityWcdma;
 import android.telephony.INetworkService;
 import android.telephony.INetworkServiceCallback;
 import android.telephony.LteVopsSupportInfo;
@@ -40,16 +35,15 @@
 import android.telephony.NrVopsSupportInfo;
 import android.telephony.ServiceState;
 import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
 import android.telephony.VopsSupportInfo;
 import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.R;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -58,7 +52,7 @@
 public class CellularNetworkServiceTest extends TelephonyTest {
     CellularNetworkService mCellularNetworkService;
 
-    // Mocked classes
+    @Mock
     private INetworkServiceCallback mCallback;
 
     private void addNetworkService() {
@@ -79,9 +73,9 @@
 
     @Before
     public void setUp() throws Exception {
+
         logd("CellularNetworkServiceTest +Setup!");
-        super.setUp(this.getClass().getSimpleName());
-        mCallback = mock(INetworkServiceCallback.class);
+        super.setUp("CellularNetworkServiceTest");
 
         mContextFixture.putResource(R.string.config_wwan_network_service_package,
                 "com.android.phone");
@@ -99,7 +93,6 @@
     public void tearDown() throws Exception {
         if (mCellularNetworkService != null) {
             mCellularNetworkService.onDestroy();
-            mCellularNetworkService = null;
         }
         super.tearDown();
     }
@@ -188,7 +181,7 @@
     public void testGetNetworkRegistrationInfoV1_5() {
         // common parameters
         int regState = NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
-        final int radioTech = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
+        int radioTech = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
         int reasonForDenial = 0;
 
         // voice services
@@ -217,11 +210,8 @@
                 new android.hardware.radio.V1_5.RegStateResult();
 
         regResult.regState = regState;
-        regResult.reasonForDenial = reasonForDenial;
-
         regResult.rat = radioTech;
-        regResult.cellIdentity = new android.hardware.radio.V1_5.CellIdentity();
-        regResult.cellIdentity.lte(new android.hardware.radio.V1_5.CellIdentityLte());
+        regResult.reasonForDenial = reasonForDenial;
 
         android.hardware.radio.V1_5.RegStateResult.AccessTechnologySpecificInfo
                 .EutranRegistrationInfo eutranInfo = new android.hardware.radio.V1_5
@@ -249,8 +239,7 @@
         NetworkRegistrationInfo expectedState = new NetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 regState, ServiceState.rilRadioTechnologyToNetworkType(radioTech), reasonForDenial,
-                false, availableVoiceServices,
-                RILUtils.convertHalCellIdentity(regResult.cellIdentity), "", false, 0, 0, 0);
+                false, availableVoiceServices, null, "", false, 0, 0, 0);
 
         try {
             verify(mCallback, timeout(1000).times(1)).onRequestNetworkRegistrationInfoComplete(
@@ -269,9 +258,8 @@
         expectedState = new NetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 regState, ServiceState.rilRadioTechnologyToNetworkType(radioTech), reasonForDenial,
-                false, availableDataServices,
-                RILUtils.convertHalCellIdentity(regResult.cellIdentity),
-                "", maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, vops);
+                false, availableDataServices, null, "", maxDataCalls, isDcNrRestricted,
+                isNrAvailable, isEndcAvailable, vops);
 
         try {
             verify(mCallback, timeout(1000).times(1)).onRequestNetworkRegistrationInfoComplete(
@@ -286,7 +274,7 @@
     public void testGetNetworkRegistrationInfoV1_6WithLte() {
         // common parameters
         int regState = NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
-        final int radioTech = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
+        int radioTech = ServiceState.RIL_RADIO_TECHNOLOGY_LTE;
         int reasonForDenial = 0;
 
         // voice services
@@ -315,11 +303,8 @@
                 new android.hardware.radio.V1_6.RegStateResult();
 
         regResult.regState = regState;
-        regResult.reasonForDenial = reasonForDenial;
-
         regResult.rat = radioTech;
-        regResult.cellIdentity = new android.hardware.radio.V1_5.CellIdentity();
-        regResult.cellIdentity.lte(new android.hardware.radio.V1_5.CellIdentityLte());
+        regResult.reasonForDenial = reasonForDenial;
 
         android.hardware.radio.V1_5.RegStateResult.AccessTechnologySpecificInfo
                 .EutranRegistrationInfo eutranInfo = new android.hardware.radio.V1_5
@@ -347,8 +332,7 @@
         NetworkRegistrationInfo expectedState = new NetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 regState, ServiceState.rilRadioTechnologyToNetworkType(radioTech), reasonForDenial,
-                false, availableVoiceServices,
-                RILUtils.convertHalCellIdentity(regResult.cellIdentity), "", false, 0, 0, 0);
+                false, availableVoiceServices, null, "", false, 0, 0, 0);
 
         try {
             verify(mCallback, timeout(1000).times(1)).onRequestNetworkRegistrationInfoComplete(
@@ -367,9 +351,8 @@
         expectedState = new NetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 regState, ServiceState.rilRadioTechnologyToNetworkType(radioTech), reasonForDenial,
-                false, availableDataServices,
-                RILUtils.convertHalCellIdentity(regResult.cellIdentity),
-                "", maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable, vops);
+                false, availableDataServices, null, "", maxDataCalls, isDcNrRestricted,
+                isNrAvailable, isEndcAvailable, vops);
 
         try {
             verify(mCallback, timeout(1000).times(1)).onRequestNetworkRegistrationInfoComplete(
@@ -385,7 +368,7 @@
     public void testGetNetworkRegistrationInfoV1_6WithNr() {
         // common parameters
         int regState = NetworkRegistrationInfo.REGISTRATION_STATE_HOME;
-        final int radioTech = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
+        int radioTech = ServiceState.RIL_RADIO_TECHNOLOGY_NR;
         int reasonForDenial = 0;
 
         // voice services
@@ -410,11 +393,8 @@
                 new android.hardware.radio.V1_6.RegStateResult();
 
         regResult.regState = regState;
-        regResult.reasonForDenial = reasonForDenial;
-
         regResult.rat = radioTech;
-        regResult.cellIdentity = new android.hardware.radio.V1_5.CellIdentity();
-        regResult.cellIdentity.nr(new android.hardware.radio.V1_5.CellIdentityNr());
+        regResult.reasonForDenial = reasonForDenial;
 
         regResult.accessTechnologySpecificInfo.ngranNrVopsInfo(new android.hardware.radio.V1_6
                 .NrVopsInfo());
@@ -438,8 +418,7 @@
         NetworkRegistrationInfo expectedState = new NetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 regState, ServiceState.rilRadioTechnologyToNetworkType(radioTech), reasonForDenial,
-                false, availableVoiceServices,
-                RILUtils.convertHalCellIdentity(regResult.cellIdentity), "", false, 0, 0, 0);
+                false, availableVoiceServices, null, "", false, 0, 0, 0);
 
         try {
             verify(mCallback, timeout(1000).times(1)).onRequestNetworkRegistrationInfoComplete(
@@ -458,9 +437,7 @@
         expectedState = new NetworkRegistrationInfo(
                 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 regState, ServiceState.rilRadioTechnologyToNetworkType(radioTech), reasonForDenial,
-                false, availableDataServices,
-                RILUtils.convertHalCellIdentity(regResult.cellIdentity),
-                "", maxDataCalls, false, false, false, vops);
+                false, availableDataServices, null, "", maxDataCalls, false, false, false, vops);
 
         try {
             verify(mCallback, timeout(1000).times(1)).onRequestNetworkRegistrationInfoComplete(
@@ -469,45 +446,4 @@
             assertTrue(false);
         }
     }
-
-    @Test
-    @SmallTest
-    public void testNetworkTypeForCellIdentity() {
-        assertEquals(
-                TelephonyManager.NETWORK_TYPE_GSM,
-                CellularNetworkService.getNetworkTypeForCellIdentity(
-                        TelephonyManager.NETWORK_TYPE_HSDPA,
-                        new CellIdentityGsm(),
-                        mPhone.getCarrierId()));
-        assertEquals(
-                TelephonyManager.NETWORK_TYPE_LTE,
-                CellularNetworkService.getNetworkTypeForCellIdentity(
-                        TelephonyManager.NETWORK_TYPE_NR,
-                        new CellIdentityLte(),
-                        mPhone.getCarrierId()));
-        assertEquals(
-                TelephonyManager.NETWORK_TYPE_LTE,
-                CellularNetworkService.getNetworkTypeForCellIdentity(
-                        TelephonyManager.NETWORK_TYPE_IWLAN,
-                        new CellIdentityLte(),
-                        mPhone.getCarrierId()));
-        assertEquals(
-                TelephonyManager.NETWORK_TYPE_LTE,
-                CellularNetworkService.getNetworkTypeForCellIdentity(
-                        TelephonyManager.NETWORK_TYPE_LTE_CA,
-                        new CellIdentityLte(),
-                        mPhone.getCarrierId()));
-        assertEquals(
-                TelephonyManager.NETWORK_TYPE_EDGE,
-                CellularNetworkService.getNetworkTypeForCellIdentity(
-                        TelephonyManager.NETWORK_TYPE_EDGE,
-                        new CellIdentityGsm(),
-                        mPhone.getCarrierId()));
-        assertEquals(
-                TelephonyManager.NETWORK_TYPE_UMTS,
-                CellularNetworkService.getNetworkTypeForCellIdentity(
-                        TelephonyManager.NETWORK_TYPE_UNKNOWN,
-                        new CellIdentityWcdma(),
-                        mPhone.getCarrierId()));
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/CellularNetworkValidatorTest.java b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkValidatorTest.java
similarity index 98%
rename from tests/telephonytests/src/com/android/internal/telephony/data/CellularNetworkValidatorTest.java
rename to tests/telephonytests/src/com/android/internal/telephony/CellularNetworkValidatorTest.java
index 511b2df..2c1e18b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/CellularNetworkValidatorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/CellularNetworkValidatorTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony;
 
 import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
 
@@ -27,7 +27,6 @@
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
@@ -47,12 +46,11 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
-import com.android.internal.telephony.TelephonyTest;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -64,14 +62,12 @@
             new PhoneCapability(1, 1, null, false, new int[0]);
     private final CellIdentityLte mCellIdentityLte1 = new CellIdentityLte(123, 456, 0, 0, 111);
     private final CellIdentityLte mCellIdentityLte2 = new CellIdentityLte(321, 654, 0, 0, 222);
-
-    // Mocked classes
+    @Mock
     CellularNetworkValidator.ValidationCallback mCallback;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mCallback = mock(CellularNetworkValidator.ValidationCallback.class);
 
         doReturn(CAPABILITY_WITH_VALIDATION_SUPPORTED).when(mPhoneConfigurationManager)
                 .getCurrentPhoneCapability();
@@ -84,7 +80,6 @@
     @After
     public void tearDown() throws Exception {
         mValidatorUT.stopValidation();
-        mValidatorUT = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ClientWakelockAccountantTest.java b/tests/telephonytests/src/com/android/internal/telephony/ClientWakelockAccountantTest.java
index fca9cc6..d406996 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ClientWakelockAccountantTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ClientWakelockAccountantTest.java
@@ -33,7 +33,6 @@
 
     @Override
     public void tearDown() throws Exception {
-        mClient = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ClientWakelockTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ClientWakelockTrackerTest.java
index 358ec54..742e3e1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ClientWakelockTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ClientWakelockTrackerTest.java
@@ -31,7 +31,6 @@
     }
 
     public void tearDown() throws Exception {
-        myTracker = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/ConnectionTest.java
index d1e643e..9986cfc 100755
--- a/tests/telephonytests/src/com/android/internal/telephony/ConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ConnectionTest.java
@@ -21,7 +21,6 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 
 import android.os.Handler;
 import android.os.Looper;
@@ -29,6 +28,7 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 
 /**
  * Unit test verifying the methods of the connection class.
@@ -37,7 +37,7 @@
 
     private static final int TEST_PHONE_TYPE = 1;
 
-    // Mocked classes
+    @Mock
     protected Call mCall;
 
     private class TestConnection extends Connection {
@@ -115,7 +115,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mCall = mock(Call.class);
         doReturn(mPhone).when(mCall).getPhone();
         replaceInstance(Handler.class, "mLooper", mCT, Looper.getMainLooper());
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
index b8c10a5..14f5aa1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ContextFixture.java
@@ -37,6 +37,7 @@
 import android.app.usage.UsageStatsManager;
 import android.content.BroadcastReceiver;
 import android.content.ComponentName;
+import android.content.ContentProvider;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
@@ -58,7 +59,6 @@
 import android.location.LocationManager;
 import android.net.ConnectivityManager;
 import android.net.Network;
-import android.net.NetworkPolicyManager;
 import android.net.Uri;
 import android.net.vcn.VcnManager;
 import android.net.wifi.WifiManager;
@@ -67,20 +67,19 @@
 import android.os.Handler;
 import android.os.IInterface;
 import android.os.PersistableBundle;
-import android.os.PowerManager;
 import android.os.PowerWhitelistManager;
 import android.os.SystemConfigManager;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
+import android.provider.Telephony.ServiceStateTable;
 import android.telecom.TelecomManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
 import android.telephony.TelephonyRegistryManager;
 import android.telephony.euicc.EuiccManager;
-import android.telephony.ims.ImsManager;
 import android.test.mock.MockContentProvider;
 import android.test.mock.MockContentResolver;
 import android.test.mock.MockContext;
@@ -116,11 +115,10 @@
     private static final String TAG = "ContextFixture";
     public static final String PERMISSION_ENABLE_ALL = "android.permission.STUB_PERMISSION";
 
-    public static class FakeContentProvider extends MockContentProvider {
+    public class FakeContentProvider extends MockContentProvider {
         private String[] mColumns = {"name", "value"};
         private HashMap<String, String> mKeyValuePairs = new HashMap<String, String>();
         private int mNumKeyValuePairs = 0;
-        private HashMap<String, String> mFlags = new HashMap<>();
 
         @Override
         public int delete(Uri uri, String selection, String[] selectionArgs) {
@@ -156,17 +154,17 @@
         @Override
         public Bundle call(String method, String request, Bundle args) {
             logd("call called, mNumKeyValuePairs: " + mNumKeyValuePairs + " method: " + method +
-                    " request: " + request + ", args=" + args);
-            Bundle bundle = new Bundle();
+                    " request: " + request);
             switch(method) {
                 case Settings.CALL_METHOD_GET_GLOBAL:
                 case Settings.CALL_METHOD_GET_SECURE:
                 case Settings.CALL_METHOD_GET_SYSTEM:
                     if (mKeyValuePairs.containsKey(request)) {
-                        bundle.putCharSequence("value", mKeyValuePairs.get(request));
+                        Bundle b = new Bundle(1);
+                        b.putCharSequence("value", mKeyValuePairs.get(request));
                         logd("returning value pair: " + mKeyValuePairs.get(request) + " for " +
                                 request);
-                        return bundle;
+                        return b;
                     }
                     break;
                 case Settings.CALL_METHOD_PUT_GLOBAL:
@@ -176,20 +174,6 @@
                     mKeyValuePairs.put(request, (String)args.get("value"));
                     mNumKeyValuePairs++;
                     break;
-                case Settings.CALL_METHOD_LIST_CONFIG:
-                    logd("LIST_config: " + mFlags);
-                    Bundle result = new Bundle();
-                    result.putSerializable(Settings.NameValueTable.VALUE, mFlags);
-                    return result;
-                case Settings.CALL_METHOD_SET_ALL_CONFIG:
-                    mFlags = (args != null)
-                            ? (HashMap) args.getSerializable(Settings.CALL_METHOD_FLAGS_KEY)
-                            : new HashMap<>();
-                    bundle.putInt(Settings.KEY_CONFIG_SET_ALL_RETURN,
-                            Settings.SET_ALL_RESULT_SUCCESS);
-                    return bundle;
-                default:
-                    logd("Unsupported method " + method);
             }
             return null;
         }
@@ -302,10 +286,6 @@
                     return mPowerWhitelistManager;
                 case Context.LOCATION_SERVICE:
                     return mLocationManager;
-                case Context.NETWORK_POLICY_SERVICE:
-                    return mNetworkPolicyManager;
-                case Context.TELEPHONY_IMS_SERVICE:
-                    return mImsManager;
                 default:
                     return null;
             }
@@ -341,14 +321,6 @@
                 return Context.KEYGUARD_SERVICE;
             } else if (serviceClass == VcnManager.class) {
                 return Context.VCN_MANAGEMENT_SERVICE;
-            } else if (serviceClass == ImsManager.class) {
-                return Context.TELEPHONY_IMS_SERVICE;
-            } else if (serviceClass == TelephonyRegistryManager.class) {
-                return Context.TELEPHONY_REGISTRY_SERVICE;
-            } else if (serviceClass == NetworkPolicyManager.class) {
-                return Context.NETWORK_POLICY_SERVICE;
-            } else if (serviceClass == PowerManager.class) {
-                return Context.POWER_SERVICE;
             }
             return super.getSystemServiceName(serviceClass);
         }
@@ -420,17 +392,6 @@
             return registerReceiverFakeImpl(receiver, filter);
         }
 
-        @Override
-        public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) {
-            return registerReceiverFakeImpl(receiver, filter);
-        }
-
-        @Override
-        public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
-                String broadcastPermission, Handler scheduler, int flags) {
-            return registerReceiverFakeImpl(receiver, filter);
-        }
-
         private Intent registerReceiverFakeImpl(BroadcastReceiver receiver, IntentFilter filter) {
             Intent result = null;
             synchronized (mBroadcastReceiversByAction) {
@@ -721,16 +682,15 @@
     private final LocationManager mLocationManager = mock(LocationManager.class);
     private final KeyguardManager mKeyguardManager = mock(KeyguardManager.class);
     private final VcnManager mVcnManager = mock(VcnManager.class);
-    private final NetworkPolicyManager mNetworkPolicyManager = mock(NetworkPolicyManager.class);
-    private final ImsManager mImsManager = mock(ImsManager.class);
+
+    private final ContentProvider mContentProvider = spy(new FakeContentProvider());
+
     private final Configuration mConfiguration = new Configuration();
     private final DisplayMetrics mDisplayMetrics = new DisplayMetrics();
     private final SharedPreferences mSharedPreferences = PreferenceManager
             .getDefaultSharedPreferences(TestApplication.getAppContext());
     private final MockContentResolver mContentResolver = new MockContentResolver();
     private final PersistableBundle mBundle = new PersistableBundle();
-    private final Network mNetwork = mock(Network.class);
-    private int mNetworkId = 200;
 
     public ContextFixture() {
         MockitoAnnotations.initMocks(this);
@@ -770,9 +730,10 @@
         }
 
         doReturn(mBundle).when(mCarrierConfigManager).getConfigForSubId(anyInt());
+        //doReturn(mBundle).when(mCarrierConfigManager).getConfig(anyInt());
         doReturn(mBundle).when(mCarrierConfigManager).getConfig();
-        doAnswer(invocation -> mNetworkId++).when(mNetwork).getNetId();
-        doReturn(mNetwork).when(mConnectivityManager).registerNetworkAgent(
+
+        doReturn(mock(Network.class)).when(mConnectivityManager).registerNetworkAgent(
                 any(), any(), any(), any(), any(), any(), anyInt());
 
         doReturn(true).when(mEuiccManager).isEnabled();
@@ -782,6 +743,11 @@
 
         mDisplayMetrics.density = 2.25f;
         doReturn(mDisplayMetrics).when(mResources).getDisplayMetrics();
+        mContentResolver.addProvider(Settings.AUTHORITY, mContentProvider);
+        // Settings caches the provider after first get/set call, this is needed to make sure
+        // Settings is using mContentProvider as the cached provider across all tests.
+        Settings.Global.getInt(mContentResolver, Settings.Global.AIRPLANE_MODE_ON, 0);
+        mContentResolver.addProvider(ServiceStateTable.AUTHORITY, mContentProvider);
         mPermissionTable.add(PERMISSION_ENABLE_ALL);
     }
 
@@ -875,14 +841,6 @@
         }
     }
 
-    public void addCallingOrSelfPermissionToCurrentPermissions(String permission) {
-        synchronized (mPermissionTable) {
-            if (mPermissionTable != null && permission != null) {
-                mPermissionTable.add(permission);
-            }
-        }
-    }
-
     public void removeCallingOrSelfPermission(String permission) {
         synchronized (mPermissionTable) {
             if (mPermissionTable != null && permission != null) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java b/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
index 6a05d4f..c6be1a4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/DefaultPhoneNotifierTest.java
@@ -19,7 +19,6 @@
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -32,10 +31,13 @@
 import android.telephony.TelephonyManager;
 import android.test.suitebuilder.annotation.SmallTest;
 
+import com.android.internal.telephony.PhoneInternalInterface.DataActivityState;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -46,28 +48,25 @@
     private static final int SUB_ID = 0;
 
     private DefaultPhoneNotifier mDefaultPhoneNotifierUT;
-
-    // Mocked classes
+    @Mock
     SignalStrength mSignalStrength;
+    @Mock
     CellInfo mCellInfo;
+    @Mock
     GsmCdmaCall mForeGroundCall;
+    @Mock
     GsmCdmaCall mBackGroundCall;
+    @Mock
     GsmCdmaCall mRingingCall;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mSignalStrength = mock(SignalStrength.class);
-        mCellInfo = mock(CellInfo.class);
-        mForeGroundCall = mock(GsmCdmaCall.class);
-        mBackGroundCall = mock(GsmCdmaCall.class);
-        mRingingCall = mock(GsmCdmaCall.class);
         mDefaultPhoneNotifierUT = new DefaultPhoneNotifier(mContext);
     }
 
     @After
     public void tearDown() throws Exception {
-        mDefaultPhoneNotifierUT = null;
         super.tearDown();
     }
 
@@ -85,13 +84,13 @@
     @Test @SmallTest
     public void testNotifyDataActivity() throws Exception {
         //mock data activity state
-        doReturn(TelephonyManager.DATA_ACTIVITY_NONE).when(mPhone).getDataActivityState();
+        doReturn(DataActivityState.NONE).when(mPhone).getDataActivityState();
         mDefaultPhoneNotifierUT.notifyDataActivity(mPhone);
         verify(mTelephonyRegistryManager).notifyDataActivityChanged(eq(0),
                 eq(TelephonyManager.DATA_ACTIVITY_NONE));
 
         doReturn(1).when(mPhone).getSubId();
-        doReturn(TelephonyManager.DATA_ACTIVITY_IN).when(mPhone).getDataActivityState();
+        doReturn(DataActivityState.DATAIN).when(mPhone).getDataActivityState();
         mDefaultPhoneNotifierUT.notifyDataActivity(mPhone);
         verify(mTelephonyRegistryManager).notifyDataActivityChanged(eq(1),
                 eq(TelephonyManager.DATA_ACTIVITY_IN));
diff --git a/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java b/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java
index 28a37f7..44f3aa5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/DeviceStateMonitorTest.java
@@ -26,7 +26,6 @@
 import static org.mockito.Matchers.eq;
 import static org.mockito.Matchers.nullable;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
@@ -51,6 +50,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -62,7 +62,7 @@
 public class DeviceStateMonitorTest extends TelephonyTest {
     private static final int INDICATION_FILTERS_MINIMUM = IndicationFilter.REGISTRATION_FAILURE;
 
-    // All implemented indication filters set so far
+    // All implemented indiation filters set so far
     // which is a subset of IndicationFilter.ALL
     private static final int INDICATION_FILTERS_ALL =
             IndicationFilter.SIGNAL_STRENGTH
@@ -73,7 +73,9 @@
             | IndicationFilter.REGISTRATION_FAILURE
             | IndicationFilter.BARRING_INFO;
 
-    private static final int INDICATION_FILTERS_WHEN_TETHERING_ON = INDICATION_FILTERS_ALL;
+    // INDICATION_FILTERS_ALL but excludes Indication.SIGNAL_STRENGTH
+    private static final int INDICATION_FILTERS_WHEN_TETHERING_ON =
+            INDICATION_FILTERS_ALL & ~IndicationFilter.SIGNAL_STRENGTH;
     private static final int INDICATION_FILTERS_WHEN_CHARGING = INDICATION_FILTERS_ALL;
     private static final int INDICATION_FILTERS_WHEN_SCREEN_ON = INDICATION_FILTERS_ALL;
 
@@ -91,9 +93,10 @@
     @Retention(RetentionPolicy.SOURCE)
     private @interface StateType {}
 
-    // Keep the same value as corresponding event
+    // Keep the same value as correspoinding event
     // See state2Event() for detail
     private static final int STATE_TYPE_RIL_CONNECTED = 0;
+    // EVENT_UPDATE_NODE_CHANGED is not here, it will be removed in aosp soon
     private static final int STATE_TYPE_SCREEN = 2;
     private static final int STATE_TYPE_POWER_SAVE_MODE = 3;
     private static final int STATE_TYPE_CHARGING = 4;
@@ -101,8 +104,6 @@
     private static final int STATE_TYPE_RADIO_AVAILABLE = 6;
     private static final int STATE_TYPE_WIFI_CONNECTED = 7;
     private static final int STATE_TYPE_ALWAYS_SIGNAL_STRENGTH_REPORTED = 8;
-    private static final int STATE_TYPE_RADIO_ON = 9;
-    private static final int STATE_TYPE_RADIO_OFF_OR_NOT_AVAILABLE = 10;
 
     /** @hide */
     @IntDef(prefix = {"STATE_"}, value = {
@@ -131,11 +132,9 @@
                 STATE_TYPE_CHARGING, STATE_TYPE_SCREEN, STATE_TYPE_TETHERING}
     );
 
-    // Mocked classes
+    @Mock
     UiModeManager mUiModeManager;
-
     private DeviceStateMonitor mDSM;
-
     // Given a stateType, return the event type that can change the state
     private int state2Event(@StateType int stateType) {
         // As long as we keep the same value, we can directly return the stateType
@@ -162,7 +161,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mUiModeManager = mock(UiModeManager.class);
         mContextFixture.setSystemService(Context.UI_MODE_SERVICE, mUiModeManager);
         // We don't even need a mock executor, we just need to not throw.
         doReturn(null).when(mContextFixture.getTestDouble()).getMainExecutor();
@@ -171,7 +169,7 @@
         // Initialize with ALL states off
         updateAllStatesToOff();
 
-        // eliminate the accumulated impact on Mockito.verify()
+        // eliminate the accumuted impact on Mockito.verify()
         reset(mSimulatedCommandsVerifier);
     }
 
@@ -237,43 +235,20 @@
     public void testScreenOnOff() {
         // screen was off by default, turn it on now
         updateState(STATE_TYPE_SCREEN, STATE_ON);
+        processAllMessages();
 
         verify(mSimulatedCommandsVerifier).setUnsolResponseFilter(
                 eq(INDICATION_FILTERS_WHEN_SCREEN_ON), nullable(Message.class));
 
         // turn screen off
         updateState(STATE_TYPE_SCREEN, STATE_OFF);
+        processAllMessages();
 
         verify(mSimulatedCommandsVerifier).setUnsolResponseFilter(
                 eq(INDICATION_FILTERS_MINIMUM), nullable(Message.class));
     }
 
     @Test
-    public void testScreenOnOffwithRadioToggle() {
-        // screen was off by default, turn it on now
-        updateState(STATE_TYPE_SCREEN, STATE_ON);
-        // turn off radio
-        updateState(STATE_TYPE_RADIO_OFF_OR_NOT_AVAILABLE, /* stateValue is not used */ 0);
-
-        verify(mSimulatedCommandsVerifier)
-                .sendDeviceState(eq(LOW_DATA_EXPECTED), eq(true), nullable(Message.class));
-        reset(mSimulatedCommandsVerifier);
-
-        // turn screen off and on
-        updateState(STATE_TYPE_SCREEN, STATE_OFF);
-        updateState(STATE_TYPE_SCREEN, STATE_ON);
-
-        verify(mSimulatedCommandsVerifier, never())
-                .sendDeviceState(anyInt(), anyBoolean(), nullable(Message.class));
-
-        // turn on radio
-        updateState(STATE_TYPE_RADIO_ON, /* stateValue is not used */ 0);
-
-        verify(mSimulatedCommandsVerifier)
-                .sendDeviceState(eq(LOW_DATA_EXPECTED), eq(false), nullable(Message.class));
-    }
-
-    @Test
     public void testTethering() {
         // Turn tethering on
         Intent intent = new Intent(TetheringManager.ACTION_TETHER_STATE_CHANGED);
@@ -400,57 +375,4 @@
         updateState(STATE_TYPE_SCREEN, STATE_ON);
         verify(mSimulatedCommandsVerifier).getBarringInfo(nullable(Message.class));
     }
-
-    @Test
-    public void testGetBarringInfowithRadioToggle() {
-        // screen was off by default, turn it on now
-        updateState(STATE_TYPE_SCREEN, STATE_ON);
-
-        verify(mSimulatedCommandsVerifier).getBarringInfo(nullable(Message.class));
-        reset(mSimulatedCommandsVerifier);
-
-        // turn off radio
-        updateState(STATE_TYPE_RADIO_OFF_OR_NOT_AVAILABLE, /* stateValue is not used */ 0);
-
-        verify(mSimulatedCommandsVerifier, never()).getBarringInfo(nullable(Message.class));
-
-        // turn screen off and on
-        updateState(STATE_TYPE_SCREEN, STATE_OFF);
-        updateState(STATE_TYPE_SCREEN, STATE_ON);
-
-        verify(mSimulatedCommandsVerifier, never()).getBarringInfo(nullable(Message.class));
-
-        // turn on radio
-        updateState(STATE_TYPE_RADIO_ON, /* stateValue is not used */ 0);
-
-        verify(mSimulatedCommandsVerifier).getBarringInfo(nullable(Message.class));
-    }
-
-    @Test
-    public void testAlwaysOnSignalStrengthwithRadioToggle() {
-        // Start with the radio off
-        updateState(STATE_TYPE_RADIO_OFF_OR_NOT_AVAILABLE, /* stateValue is not used */ 0);
-        reset(mSimulatedCommandsVerifier);
-        // Toggle always-reported signal strength while the radio is OFF. This should do nothing.
-        // This should have no effect while the radio is off.
-        updateState(STATE_TYPE_ALWAYS_SIGNAL_STRENGTH_REPORTED, STATE_ON);
-        updateState(STATE_TYPE_ALWAYS_SIGNAL_STRENGTH_REPORTED, STATE_OFF);
-        verify(mSimulatedCommandsVerifier, never())
-                .sendDeviceState(anyInt(), anyBoolean(), nullable(Message.class));
-
-        // Turn on the always reported signal strength and then the radio, which should just turn
-        // on this one little thing more than the absolute minimum.
-        updateState(STATE_TYPE_ALWAYS_SIGNAL_STRENGTH_REPORTED, STATE_ON);
-        updateState(STATE_TYPE_RADIO_ON, /* stateValue is not used */ 0);
-        verify(mSimulatedCommandsVerifier).setUnsolResponseFilter(
-                eq(IndicationFilter.SIGNAL_STRENGTH | INDICATION_FILTERS_MINIMUM),
-                        nullable(Message.class));
-
-        // Turn off radio and see that SignalStrength goes off again. Technically, in this
-        // direction, the value becomes a "don't-care", but it's not worth the complexity of having
-        // the value only sync on the rising edge of radio power.
-        updateState(STATE_TYPE_RADIO_OFF_OR_NOT_AVAILABLE, /* stateValue is not used */ 0);
-        verify(mSimulatedCommandsVerifier).setUnsolResponseFilter(
-                eq(INDICATION_FILTERS_MINIMUM), nullable(Message.class));
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ExponentialBackoffTest.java b/tests/telephonytests/src/com/android/internal/telephony/ExponentialBackoffTest.java
index 14e8377..7c303bd 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ExponentialBackoffTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ExponentialBackoffTest.java
@@ -20,7 +20,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -35,6 +34,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 
 @RunWith(AndroidJUnit4.class)
 public class ExponentialBackoffTest extends ImsTestBase {
@@ -45,16 +45,12 @@
 
     private ExponentialBackoff mBackoffUnderTest;
     private Handler mHandler = new Handler(Looper.getMainLooper());
-
-    // Mocked classes
-    private Runnable mRunnable;
-    private ExponentialBackoff.HandlerAdapter mHandlerAdapter;
+    @Mock private Runnable mRunnable;
+    @Mock private ExponentialBackoff.HandlerAdapter mHandlerAdapter;
 
     @Before
     public void setUp() throws Exception {
         super.setUp();
-        mRunnable = mock(Runnable.class);
-        mHandlerAdapter = mock(ExponentialBackoff.HandlerAdapter.class);
         mBackoffUnderTest = new ExponentialBackoff(
                 START_DELAY_MS, MAXIMUM_DELAY_MS, MULTIPLIER, mHandler, mRunnable);
         mBackoffUnderTest.setHandlerAdapter(mHandlerAdapter);
@@ -68,11 +64,8 @@
     }
 
     @After
-    public void tearDown() throws Exception {
+    public void tearDown() {
         mBackoffUnderTest.stop();
-        mBackoffUnderTest = null;
-        mHandler = null;
-        super.tearDown();
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
index 782f78e..f2624af 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/FakeTelephonyProvider.java
@@ -26,7 +26,6 @@
 import android.os.Bundle;
 import android.provider.BaseColumns;
 import android.provider.Telephony;
-import android.telephony.SubscriptionManager;
 import android.test.mock.MockContentProvider;
 import android.util.Log;
 
@@ -118,11 +117,7 @@
                     + Telephony.SimInfo.COLUMN_RCS_CONFIG + " BLOB,"
                     + Telephony.SimInfo.COLUMN_ALLOWED_NETWORK_TYPES_FOR_REASONS + " TEXT,"
                     + Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING + " INTEGER DEFAULT 0,"
-                    + Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS + "TEXT,"
-                    + Telephony.SimInfo.COLUMN_NR_ADVANCED_CALLING_ENABLED + " INTEGER DEFAULT -1,"
-                    + Telephony.SimInfo.COLUMN_PORT_INDEX + " INTEGER DEFAULT -1,"
-                    + Telephony.SimInfo.COLUMN_USAGE_SETTING + " INTEGER DEFAULT "
-                            + SubscriptionManager.USAGE_SETTING_UNKNOWN
+                    + Telephony.SimInfo.COLUMN_D2D_STATUS_SHARING_SELECTED_CONTACTS + "TEXT"
                     + ");";
         }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GbaManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/GbaManagerTest.java
index c658b16..8939977 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GbaManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GbaManagerTest.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.telephony;
 
-import static com.android.internal.telephony.TelephonyStatsLog.GBA_EVENT__FAILED_REASON__FEATURE_NOT_READY;
-
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertTrue;
 import static junit.framework.Assert.fail;
@@ -52,13 +50,13 @@
 import android.testing.TestableLooper;
 import android.util.Log;
 
-import com.android.internal.telephony.metrics.RcsStats;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 /**
  * Unit tests for GbaManager
@@ -77,13 +75,10 @@
     private static final int RELEASE_TIME_60S = 60 * 1000;
     private static final int TEST_SUB_ID = Integer.MAX_VALUE;
 
-    // Mocked classes
-    Context mMockContext;
-    IBinder mMockBinder;
-    IGbaService mMockGbaServiceBinder;
-    IBootstrapAuthenticationCallback mMockCallback;
-    RcsStats mMockRcsStats;
-
+    @Mock Context mMockContext;
+    @Mock IBinder mMockBinder;
+    @Mock IGbaService mMockGbaServiceBinder;
+    @Mock IBootstrapAuthenticationCallback mMockCallback;
     private GbaManager mTestGbaManager;
     private Handler mHandler;
     private TestableLooper mLooper;
@@ -91,17 +86,13 @@
     @Before
     public void setUp() throws Exception {
         log("setUp");
-        mMockContext = mock(Context.class);
-        mMockBinder = mock(IBinder.class);
-        mMockGbaServiceBinder = mock(IGbaService.class);
-        mMockCallback = mock(IBootstrapAuthenticationCallback.class);
-        mMockRcsStats = mock(RcsStats.class);
+        MockitoAnnotations.initMocks(this);
         if (Looper.myLooper() == null) {
             Looper.prepare();
         }
         when(mMockContext.bindService(any(), any(), anyInt())).thenReturn(true);
         when(mMockGbaServiceBinder.asBinder()).thenReturn(mMockBinder);
-        mTestGbaManager = new GbaManager(mMockContext, TEST_SUB_ID, null, 0, mMockRcsStats);
+        mTestGbaManager = new GbaManager(mMockContext, TEST_SUB_ID, null, 0);
         mHandler = mTestGbaManager.getHandler();
         try {
             mLooper = new TestableLooper(mHandler.getLooper());
@@ -115,7 +106,6 @@
         log("tearDown");
         mTestGbaManager.destroy();
         mTestGbaManager = null;
-        mHandler = null;
         mLooper.destroy();
         mLooper = null;
     }
@@ -226,45 +216,6 @@
         assertTrue(!mTestGbaManager.isServiceConnected());
     }
 
-    @Test
-    @SmallTest
-    public void testMetricsGbaEvent() throws Exception {
-        mTestGbaManager.overrideServicePackage(TEST_DEFAULT_SERVICE_NAME.getPackageName());
-        mTestGbaManager.overrideReleaseTime(RELEASE_NEVER);
-
-        mLooper.processAllMessages();
-        bindAndConnectService(TEST_DEFAULT_SERVICE_NAME);
-        GbaAuthRequest request = createDefaultRequest();
-
-        // Failure case
-        mTestGbaManager.bootstrapAuthenticationRequest(request);
-        mLooper.processAllMessages();
-
-        ArgumentCaptor<GbaAuthRequest> captor = ArgumentCaptor.forClass(GbaAuthRequest.class);
-        verify(mMockGbaServiceBinder, times(1)).authenticationRequest(captor.capture());
-
-        GbaAuthRequest capturedRequest = captor.getValue();
-        IBootstrapAuthenticationCallback callback = capturedRequest.getCallback();
-        callback.onAuthenticationFailure(capturedRequest.getToken(),
-                GBA_EVENT__FAILED_REASON__FEATURE_NOT_READY);
-
-        verify(mMockRcsStats).onGbaFailureEvent(anyInt(),
-                eq(GBA_EVENT__FAILED_REASON__FEATURE_NOT_READY));
-
-        // Success case
-        mTestGbaManager.bootstrapAuthenticationRequest(request);
-        mLooper.processAllMessages();
-
-        ArgumentCaptor<GbaAuthRequest> captor2 = ArgumentCaptor.forClass(GbaAuthRequest.class);
-        verify(mMockGbaServiceBinder, times(2)).authenticationRequest(captor2.capture());
-
-        GbaAuthRequest capturedRequest2 = captor2.getValue();
-        IBootstrapAuthenticationCallback callback2 = capturedRequest2.getCallback();
-        callback2.onKeysAvailable(capturedRequest2.getToken(), "".getBytes(), "");
-
-        verify(mMockRcsStats).onGbaSuccessEvent(anyInt());
-    }
-
     private ServiceConnection bindAndConnectService(ComponentName component) {
         ServiceConnection connection = bindService(component);
         IGbaService.Stub serviceStub = mock(IGbaService.Stub.class);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTest.java
index b29976f..15eb59e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTest.java
@@ -24,21 +24,19 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 
 public class GsmCdmaCallTest extends TelephonyTest {
-    // Mocked classes
-    GsmCdmaConnection mConnection1;
-    GsmCdmaConnection mConnection2;
-    DriverCall mDriverCall;
+
+    @Mock GsmCdmaConnection mConnection1;
+    @Mock GsmCdmaConnection mConnection2;
+    @Mock DriverCall mDriverCall;
 
     private GsmCdmaCall mCallUnderTest;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mConnection1 = mock(GsmCdmaConnection.class);
-        mConnection2 = mock(GsmCdmaConnection.class);
-        mDriverCall = mock(DriverCall.class);
         mCallUnderTest = new GsmCdmaCall(mCT);
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
index 33a8e62..3fdcc78 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaCallTrackerTest.java
@@ -23,10 +23,10 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.isA;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
+import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.telephony.DisconnectCause;
@@ -49,6 +49,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -59,16 +60,14 @@
     private String mDialString = PhoneNumberUtils.stripSeparators("+17005554141");
     /* Handler class initiated at the HandlerThread */
     private GsmCdmaCallTracker mCTUT;
-
-    // Mocked classes
-    private GsmCdmaConnection mConnection;
+    @Mock
+    GsmCdmaConnection mConnection;
+    @Mock
     private Handler mHandler;
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mConnection = mock(GsmCdmaConnection.class);
-        mHandler = mock(Handler.class);
+        super.setUp(this.getClass().getSimpleName());
         mSimulatedCommands.setRadioPower(true, null);
         mPhone.mCi = this.mSimulatedCommands;
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaConnectionTest.java
index fe89a8e..a078642 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaConnectionTest.java
@@ -36,6 +36,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -43,15 +44,15 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class GsmCdmaConnectionTest extends TelephonyTest {
+
     private GsmCdmaConnection connection;
 
-    // Mocked classes
+    @Mock
     DriverCall mDC;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mDC = mock(DriverCall.class);
         replaceInstance(Handler.class, "mLooper", mCT, Looper.myLooper());
 
         mCT.mForegroundCall = new GsmCdmaCall(mCT);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
index 9e45cc3..2f98164 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/GsmCdmaPhoneTest.java
@@ -34,13 +34,13 @@
 import static org.mockito.Matchers.nullable;
 import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyInt;
-import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -52,7 +52,6 @@
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
-import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.WorkSource;
 import android.preference.PreferenceManager;
@@ -65,16 +64,15 @@
 import android.telephony.LinkCapacityEstimate;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
-import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
+import android.telephony.data.ApnSetting;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
 import androidx.test.filters.FlakyTest;
 
-import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.test.SimulatedCommands;
 import com.android.internal.telephony.test.SimulatedCommandsVerifier;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus;
@@ -82,7 +80,6 @@
 import com.android.internal.telephony.uicc.IccRecords;
 import com.android.internal.telephony.uicc.IccVmNotSupportedException;
 import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UiccProfile;
 import com.android.internal.telephony.uicc.UiccSlot;
 
@@ -93,6 +90,7 @@
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 import org.mockito.InOrder;
+import org.mockito.Mock;
 import org.mockito.Mockito;
 
 import java.util.ArrayList;
@@ -101,11 +99,11 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class GsmCdmaPhoneTest extends TelephonyTest {
-    private static final String TEST_EMERGENCY_NUMBER = "555";
-
-    // Mocked classes
+    @Mock
     private Handler mTestHandler;
+    @Mock
     private UiccSlot mUiccSlot;
+    @Mock
     private CommandsInterface mMockCi;
 
     //mPhoneUnderTest
@@ -134,10 +132,7 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mTestHandler = Mockito.mock(Handler.class);
-        mUiccSlot = Mockito.mock(UiccSlot.class);
-        mUiccPort = Mockito.mock(UiccPort.class);
-        mMockCi = Mockito.mock(CommandsInterface.class);
+
         doReturn(false).when(mSST).isDeviceShuttingDown();
         doReturn(true).when(mImsManager).isVolteEnabledByPlatform();
 
@@ -173,7 +168,6 @@
     public void testGetServiceState() {
         ServiceState serviceState = new ServiceState();
         mSST.mSS = serviceState;
-        doReturn(serviceState).when(mSST).getServiceState();
         assertEquals(serviceState, mPhoneUT.getServiceState());
     }
 
@@ -244,7 +238,6 @@
         serviceState.setIwlanPreferred(true);
 
         mSST.mSS = serviceState;
-        doReturn(serviceState).when(mSST).getServiceState();
         mPhoneUT.mSST = mSST;
 
         ServiceState mergedServiceState = mPhoneUT.getServiceState();
@@ -327,7 +320,6 @@
         serviceState.setIwlanPreferred(true);
 
         mSST.mSS = serviceState;
-        doReturn(serviceState).when(mSST).getServiceState();
         mPhoneUT.mSST = mSST;
 
         ServiceState mergedServiceState = mPhoneUT.getServiceState();
@@ -423,6 +415,38 @@
 
     @Test
     @SmallTest
+    public void testGetDataConnectionState() {
+        // There are several cases possible. Testing few of them for now.
+        // 1. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn != APN_TYPE_EMERGENCY
+        doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mSST).getCurrentDataConnectionState();
+        assertEquals(PhoneConstants.DataState.DISCONNECTED, mPhoneUT.getDataConnectionState(
+                ApnSetting.TYPE_ALL_STRING));
+
+        // 2. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn = APN_TYPE_EMERGENCY, apn
+        // not connected
+        doReturn(DctConstants.State.IDLE).when(mDcTracker).getState(
+                ApnSetting.TYPE_EMERGENCY_STRING);
+        assertEquals(PhoneConstants.DataState.DISCONNECTED, mPhoneUT.getDataConnectionState(
+                ApnSetting.TYPE_EMERGENCY_STRING));
+
+        // 3. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn = APN_TYPE_EMERGENCY,
+        // APN is connected, callTracker state = idle
+        doReturn(DctConstants.State.CONNECTED).when(mDcTracker).getState(
+                ApnSetting.TYPE_EMERGENCY_STRING);
+        mCT.mState = PhoneConstants.State.IDLE;
+        assertEquals(PhoneConstants.DataState.CONNECTED, mPhoneUT.getDataConnectionState(
+                ApnSetting.TYPE_EMERGENCY_STRING));
+
+        // 3. GSM, getCurrentDataConnectionState != STATE_IN_SERVICE, apn = APN_TYPE_EMERGENCY,
+        // APN enabled and CONNECTED, callTracker state != idle, !isConcurrentVoiceAndDataAllowed
+        mCT.mState = PhoneConstants.State.RINGING;
+        doReturn(false).when(mSST).isConcurrentVoiceAndDataAllowed();
+        assertEquals(PhoneConstants.DataState.SUSPENDED, mPhoneUT.getDataConnectionState(
+                ApnSetting.TYPE_EMERGENCY_STRING));
+    }
+
+    @Test
+    @SmallTest
     public void testHandleInCallMmiCommands() {
         try {
             // Switch to CDMA
@@ -1011,6 +1035,50 @@
         assertNull(phone.getMeid());
     }
 
+    @Test
+    @SmallTest
+    public void testEmergencyCallbackMessages() throws Exception {
+        verify(mSimulatedCommandsVerifier).setEmergencyCallbackMode(eq(mPhoneUT), anyInt(),
+                nullable(Object.class));
+        verify(mSimulatedCommandsVerifier).registerForExitEmergencyCallbackMode(eq(mPhoneUT),
+                anyInt(), nullable(Object.class));
+
+        // verify handling of emergency callback mode
+        mSimulatedCommands.notifyEmergencyCallbackMode();
+        processAllMessages();
+
+        verifyEcbmIntentSent(1 /*times*/, true /*isInEcm*/);
+        assertTrue(mPhoneUT.isInEcm());
+
+        // verify that wakeLock is acquired in ECM
+        assertTrue(mPhoneUT.getWakeLock().isHeld());
+
+        mPhoneUT.setOnEcbModeExitResponse(mTestHandler, EVENT_EMERGENCY_CALLBACK_MODE_EXIT, null);
+        mPhoneUT.registerForEmergencyCallToggle(mTestHandler, EVENT_EMERGENCY_CALL_TOGGLE, null);
+
+        // verify handling of emergency callback mode exit
+        mSimulatedCommands.notifyExitEmergencyCallbackMode();
+        processAllMessages();
+
+        verifyEcbmIntentSent(2 /*times*/, false /*isInEcm*/);
+        assertFalse(mPhoneUT.isInEcm());
+
+        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
+
+        // verify EcmExitRespRegistrant and mEmergencyCallToggledRegistrants are notified
+        verify(mTestHandler, times(2)).sendMessageAtTime(messageArgumentCaptor.capture(),
+                anyLong());
+        List<Message> msgList = messageArgumentCaptor.getAllValues();
+        assertEquals(EVENT_EMERGENCY_CALLBACK_MODE_EXIT, msgList.get(0).what);
+        assertEquals(EVENT_EMERGENCY_CALL_TOGGLE, msgList.get(1).what);
+
+        // verify setInternalDataEnabled
+        verify(mDataEnabledSettings).setInternalDataEnabled(true);
+
+        // verify wakeLock released
+        assertFalse(mPhoneUT.getWakeLock().isHeld());
+    }
+
     private void verifyEcbmIntentSent(int times, boolean isInEcm) throws Exception {
         ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
         verify(mContext, atLeast(times)).sendStickyBroadcastAsUser(intentArgumentCaptor.capture(),
@@ -1045,6 +1113,74 @@
 
     @Test
     @SmallTest
+    public void testModemResetInEmergencyCallbackMessages() {
+        verify(mSimulatedCommandsVerifier).setEmergencyCallbackMode(eq(mPhoneUT), anyInt(),
+                nullable(Object.class));
+        verify(mSimulatedCommandsVerifier).registerForModemReset(eq(mPhoneUT),
+                anyInt(), nullable(Object.class));
+
+        switchToCdma();
+        // verify handling of emergency callback mode
+        mSimulatedCommands.notifyEmergencyCallbackMode();
+        processAllMessages();
+
+        // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
+        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
+        try {
+            verify(mContext, atLeast(1)).sendStickyBroadcastAsUser(intentArgumentCaptor.capture(),
+                    any());
+        } catch (Exception e) {
+            fail("Unexpected exception: " + e.getStackTrace());
+        }
+
+        Intent intent = intentArgumentCaptor.getValue();
+        assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
+        assertEquals(true, intent.getBooleanExtra(
+                TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, false));
+        assertEquals(true, mPhoneUT.isInEcm());
+
+        // verify that wakeLock is acquired in ECM
+        assertEquals(true, mPhoneUT.getWakeLock().isHeld());
+
+        mPhoneUT.setOnEcbModeExitResponse(mTestHandler, EVENT_EMERGENCY_CALLBACK_MODE_EXIT, null);
+        mPhoneUT.registerForEmergencyCallToggle(mTestHandler, EVENT_EMERGENCY_CALL_TOGGLE, null);
+
+        // verify handling of emergency callback mode exit when modem resets
+        mSimulatedCommands.notifyModemReset();
+        processAllMessages();
+
+        // verify ACTION_EMERGENCY_CALLBACK_MODE_CHANGED
+        try {
+            verify(mContext, atLeast(2)).sendStickyBroadcastAsUser(intentArgumentCaptor.capture(),
+                    any());
+        } catch (Exception e) {
+            fail("Unexpected exception: " + e.getStackTrace());
+        }
+
+        intent = intentArgumentCaptor.getValue();
+        assertEquals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED, intent.getAction());
+        assertEquals(false, intent.getBooleanExtra(
+                TelephonyManager.EXTRA_PHONE_IN_ECM_STATE, true));
+        assertEquals(false, mPhoneUT.isInEcm());
+
+        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
+
+        // verify EcmExitRespRegistrant and mEmergencyCallToggledRegistrants are notified
+        verify(mTestHandler, times(2)).sendMessageAtTime(messageArgumentCaptor.capture(),
+                anyLong());
+        List<Message> msgList = messageArgumentCaptor.getAllValues();
+        assertEquals(EVENT_EMERGENCY_CALLBACK_MODE_EXIT, msgList.get(0).what);
+        assertEquals(EVENT_EMERGENCY_CALL_TOGGLE, msgList.get(1).what);
+
+        // verify setInternalDataEnabled
+        verify(mDataEnabledSettings).setInternalDataEnabled(true);
+
+        // verify wakeLock released
+        assertEquals(false, mPhoneUT.getWakeLock().isHeld());
+    }
+
+    @Test
+    @SmallTest
     public void testCallForwardingIndicator() {
         doReturn(IccRecords.CALL_FORWARDING_STATUS_UNKNOWN).when(mSimRecords).
                 getVoiceCallForwardingFlag();
@@ -1103,7 +1239,7 @@
         // If UiccSlot.isStateUnknown is true, we should return a placeholder IccCard with the state
         // set to UNKNOWN
         doReturn(null).when(mUiccController).getUiccProfileForPhone(anyInt());
-        UiccSlot mockSlot = Mockito.mock(UiccSlot.class);
+        UiccSlot mockSlot = mock(UiccSlot.class);
         doReturn(mockSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
         doReturn(true).when(mockSlot).isStateUnknown();
 
@@ -1252,7 +1388,7 @@
         // Have IccId defined. But expected value and current value are the same. So no RIL command
         // should be sent.
         String iccId = "Fake iccId";
-        doReturn(iccId).when(mUiccSlot).getIccId(anyInt());
+        doReturn(iccId).when(mUiccSlot).getIccId();
         Message.obtain(mPhoneUT, EVENT_ICC_CHANGED, null).sendToTarget();
         processAllMessages();
         verify(mSubscriptionController).getSubInfoForIccId(iccId);
@@ -1267,7 +1403,7 @@
         doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
         doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mUiccSlot).getCardState();
         String iccId = "Fake iccId";
-        doReturn(iccId).when(mUiccSlot).getIccId(anyInt());
+        doReturn(iccId).when(mUiccSlot).getIccId();
         Message.obtain(mPhoneUT, EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED,
                 new AsyncResult(null, false, null)).sendToTarget();
         processAllMessages();
@@ -1319,7 +1455,7 @@
         doReturn(mUiccSlot).when(mUiccController).getUiccSlotForPhone(anyInt());
         doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mUiccSlot).getCardState();
         String iccId = "Fake iccId";
-        doReturn(iccId).when(mUiccSlot).getIccId(anyInt());
+        doReturn(iccId).when(mUiccSlot).getIccId();
         Message.obtain(mPhoneUT, EVENT_UICC_APPS_ENABLEMENT_STATUS_CHANGED,
                 new AsyncResult(null, false, null)).sendToTarget();
         processAllMessages();
@@ -1424,9 +1560,6 @@
 
     @Test
     public void testEventCarrierConfigChanged() {
-        doReturn(null).when(mSubscriptionController).getSubscriptionProperty(anyInt(),
-                eq(SubscriptionManager.NR_ADVANCED_CALLING_ENABLED));
-
         mPhoneUT.mCi = mMockCi;
         mPhoneUT.sendMessage(mPhoneUT.obtainMessage(Phone.EVENT_CARRIER_CONFIG_CHANGED));
         processAllMessages();
@@ -1518,212 +1651,4 @@
 
         assertEquals(false, mPhoneUT.isAllowedNetworkTypesLoadedFromDb());
     }
-
-    /**
-     * Verifies that an emergency call placed on a SIM which does NOT explicitly define a number as
-     * an emergency call will still be placed as an emergency call.
-     * @throws CallStateException
-     */
-    @Test
-    public void testEmergencyCallAnySim() throws CallStateException {
-        setupEmergencyCallScenario(false /* USE_ONLY_DIALED_SIM_ECC_LIST */,
-                false /* isEmergencyOnDialedSim */);
-
-        ArgumentCaptor<PhoneInternalInterface.DialArgs> dialArgsArgumentCaptor =
-                ArgumentCaptor.forClass(PhoneInternalInterface.DialArgs.class);
-        mPhoneUT.dial(TEST_EMERGENCY_NUMBER, new ImsPhone.ImsDialArgs.Builder().build());
-
-        // Should have dialed out over IMS and should have specified that it is an emergency call
-        verify(mImsPhone).dial(anyString(), dialArgsArgumentCaptor.capture());
-        PhoneInternalInterface.DialArgs args = dialArgsArgumentCaptor.getValue();
-        assertTrue(args.isEmergency);
-    }
-
-    /**
-     * Tests the scenario where a number is dialed on a sim where it is NOT an emergency number,
-     * but it IS an emergency number based on {@link TelephonyManager#isEmergencyNumber(String)},
-     * and the carrier wants to ONLY use the dialed SIM's ECC list.
-     * @throws CallStateException
-     */
-    @Test
-    public void testNotEmergencyNumberOnDialedSim1() throws CallStateException {
-        setupEmergencyCallScenario(true /* USE_ONLY_DIALED_SIM_ECC_LIST */,
-                false /* isEmergencyOnDialedSim */);
-
-        ArgumentCaptor<PhoneInternalInterface.DialArgs> dialArgsArgumentCaptor =
-                ArgumentCaptor.forClass(PhoneInternalInterface.DialArgs.class);
-        mPhoneUT.dial(TEST_EMERGENCY_NUMBER, new ImsPhone.ImsDialArgs.Builder().build());
-
-        // Should have dialed out over IMS and should have specified that it is NOT an emergency
-        // call
-        verify(mImsPhone).dial(anyString(), dialArgsArgumentCaptor.capture());
-        PhoneInternalInterface.DialArgs args = dialArgsArgumentCaptor.getValue();
-        assertFalse(args.isEmergency);
-    }
-
-    /**
-     * Tests the scenario where a number is dialed on a sim where it is NOT an emergency number,
-     * but it IS an emergency number based on {@link TelephonyManager#isEmergencyNumber(String)},
-     * and the carrier wants to use the global ECC list.
-     * @throws CallStateException
-     */
-    @Test
-    public void testNotEmergencyNumberOnDialedSim2() throws CallStateException {
-        setupEmergencyCallScenario(false /* USE_ONLY_DIALED_SIM_ECC_LIST */,
-                false /* isEmergencyOnDialedSim */);
-
-        ArgumentCaptor<PhoneInternalInterface.DialArgs> dialArgsArgumentCaptor =
-                ArgumentCaptor.forClass(PhoneInternalInterface.DialArgs.class);
-        mPhoneUT.dial(TEST_EMERGENCY_NUMBER, new ImsPhone.ImsDialArgs.Builder().build());
-
-        // Should have dialed out over IMS and should have specified that it is an emergency call
-        verify(mImsPhone).dial(anyString(), dialArgsArgumentCaptor.capture());
-        PhoneInternalInterface.DialArgs args = dialArgsArgumentCaptor.getValue();
-        assertTrue(args.isEmergency);
-    }
-
-    private void setupEmergencyCallScenario(boolean isUsingOnlyDialedSim,
-            boolean isEmergencyPerDialedSim) {
-        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
-        bundle.putBoolean(CarrierConfigManager.KEY_USE_ONLY_DIALED_SIM_ECC_LIST_BOOL,
-                isUsingOnlyDialedSim);
-        bundle.putBoolean(CarrierConfigManager.KEY_CARRIER_USE_IMS_FIRST_FOR_EMERGENCY_BOOL, true);
-        doReturn(true).when(mImsPhone).isImsAvailable();
-        doReturn(true).when(mImsManager).isVolteEnabledByPlatform();
-        doReturn(true).when(mImsManager).isEnhanced4gLteModeSettingEnabledByUser();
-        doReturn(true).when(mImsManager).isNonTtyOrTtyOnVolteEnabled();
-        doReturn(true).when(mImsPhone).isVoiceOverCellularImsEnabled();
-        ServiceState ss = Mockito.mock(ServiceState.class);
-        doReturn(ServiceState.STATE_IN_SERVICE).when(ss).getState();
-        doReturn(ss).when(mImsPhone).getServiceState();
-
-        doReturn(true).when(mTelephonyManager).isEmergencyNumber(anyString());
-        doReturn(isEmergencyPerDialedSim).when(mEmergencyNumberTracker).isEmergencyNumber(
-                anyString(), anyBoolean());
-
-        mPhoneUT.setImsPhone(mImsPhone);
-    }
-
-    @Test
-    public void testSetVoiceServiceStateOverride() throws Exception {
-        // Start with CS voice and IMS both OOS, no override
-        ServiceState csServiceState = new ServiceState();
-        csServiceState.setStateOutOfService();
-        csServiceState.setDataRegState(ServiceState.STATE_IN_SERVICE);
-        doReturn(csServiceState).when(mSST).getServiceState();
-        ServiceState imsServiceState = new ServiceState();
-        imsServiceState.setStateOutOfService();
-        doReturn(imsServiceState).when(mImsPhone).getServiceState();
-        replaceInstance(Phone.class, "mImsPhone", mPhoneUT, mImsPhone);
-
-        assertEquals(ServiceState.STATE_OUT_OF_SERVICE, mPhoneUT.getServiceState().getState());
-
-        // Now set the telecom override
-        mPhoneUT.setVoiceServiceStateOverride(true);
-        verify(mSST).onTelecomVoiceServiceStateOverrideChanged();
-        assertEquals(ServiceState.STATE_IN_SERVICE, mPhoneUT.getServiceState().getState());
-
-        // IMS and telecom voice are treated as equivalent for merging purposes
-        imsServiceState.setVoiceRegState(ServiceState.STATE_IN_SERVICE);
-        assertEquals(ServiceState.STATE_IN_SERVICE, mPhoneUT.getServiceState().getState());
-
-        // Clearing the telecom override still lets IMS override separately
-        mPhoneUT.setVoiceServiceStateOverride(false);
-        verify(mSST, times(2)).onTelecomVoiceServiceStateOverrideChanged();
-        assertEquals(ServiceState.STATE_IN_SERVICE, mPhoneUT.getServiceState().getState());
-
-        // And now removing the IMS IN_SERVICE results in the base OOS showing through
-        imsServiceState.setStateOutOfService();
-        assertEquals(ServiceState.STATE_OUT_OF_SERVICE, mPhoneUT.getServiceState().getState());
-    }
-
-    private void setupUsageSettingResources() {
-        // The most common case, request a voice-centric->data-centric change
-        mContextFixture.putIntResource(
-                com.android.internal.R.integer.config_default_cellular_usage_setting,
-                SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC);
-        mContextFixture.putIntArrayResource(
-                com.android.internal.R.array.config_supported_cellular_usage_settings,
-                new int[]{
-                        SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC,
-                        SubscriptionManager.USAGE_SETTING_DATA_CENTRIC});
-    }
-
-
-    private SubscriptionInfo makeSubscriptionInfo(boolean isOpportunistic, int usageSetting) {
-        return new SubscriptionInfo(
-                 1, "xxxxxxxxx", 1, "Android Test", "Android Test", 0, 0, "8675309", 0,
-                null, "001", "01", "us", true, null, null, 0, isOpportunistic, null, false,
-                1, 1, 0, null, null, true, 0, usageSetting);
-    }
-
-    @Test
-    @SmallTest
-    public void testUsageSettingUpdate_DataCentric() {
-        setupUsageSettingResources();
-        mPhoneUT.mCi = mMockCi;
-
-        final SubscriptionInfo si = makeSubscriptionInfo(
-                false, SubscriptionManager.USAGE_SETTING_DATA_CENTRIC);
-
-        doReturn(si).when(mSubscriptionController).getSubscriptionInfo(anyInt());
-
-        mPhoneUT.updateUsageSetting();
-        processAllMessages();
-
-        verify(mMockCi).getUsageSetting(any());
-        mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_GET_USAGE_SETTING_DONE,
-                new AsyncResult(null,
-                        new int[]{SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC}, null)));
-        processAllMessages();
-        verify(mMockCi).setUsageSetting(any(), eq(SubscriptionManager.USAGE_SETTING_DATA_CENTRIC));
-        mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_SET_USAGE_SETTING_DONE,
-                new AsyncResult(null, null, null)));
-    }
-
-    @Test
-    @SmallTest
-    public void testUsageSettingUpdate_DefaultOpportunistic() {
-        setupUsageSettingResources();
-        mPhoneUT.mCi = mMockCi;
-
-        final SubscriptionInfo si = makeSubscriptionInfo(
-                true, SubscriptionManager.USAGE_SETTING_DEFAULT);
-        doReturn(si).when(mSubscriptionController).getSubscriptionInfo(anyInt());
-
-        mPhoneUT.updateUsageSetting();
-        processAllMessages();
-
-        verify(mMockCi).getUsageSetting(any());
-        mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_GET_USAGE_SETTING_DONE,
-                new AsyncResult(null,
-                        new int[]{SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC}, null)));
-        processAllMessages();
-        verify(mMockCi).setUsageSetting(any(), eq(SubscriptionManager.USAGE_SETTING_DATA_CENTRIC));
-        mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_SET_USAGE_SETTING_DONE,
-                new AsyncResult(null, null, null)));
-    }
-
-    @Test
-    @SmallTest
-    public void testUsageSettingUpdate_DefaultNonOpportunistic() {
-        setupUsageSettingResources();
-        mPhoneUT.mCi = mMockCi;
-
-        final SubscriptionInfo si = makeSubscriptionInfo(
-                false, SubscriptionManager.USAGE_SETTING_DEFAULT);
-
-        assertNotNull(si);
-        doReturn(si).when(mSubscriptionController).getSubscriptionInfo(anyInt());
-
-        mPhoneUT.updateUsageSetting();
-        processAllMessages();
-
-        verify(mMockCi).getUsageSetting(any());
-        mPhoneUT.sendMessage(mPhoneUT.obtainMessage(GsmCdmaPhone.EVENT_GET_USAGE_SETTING_DONE,
-                new AsyncResult(null,
-                        new int[]{SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC}, null)));
-        processAllMessages();
-        verify(mMockCi, never()).setUsageSetting(any(), anyInt());
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/IccLogicalChannelRequestTest.java b/tests/telephonytests/src/com/android/internal/telephony/IccLogicalChannelRequestTest.java
deleted file mode 100644
index e5e6fe1..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/IccLogicalChannelRequestTest.java
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Binder;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.telephony.SubscriptionManager;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import junit.framework.TestCase;
-
-import org.junit.Test;
-
-public class IccLogicalChannelRequestTest extends TestCase {
-
-    private static final int SUB_ID = 0;
-    private static final int SLOT_INDEX = 0;
-    private static final int PORT_INDEX = 0;
-    private static final String CALLING_PKG = "test_app";
-    private static final String AID = "aid";
-    private static final int P2 = 0;
-    private static final int CHANNEL = 1;
-    private static final IBinder BINDER = new Binder();
-
-    @Test
-    @SmallTest
-    public void testDefaultConstructor_shouldReturnDefaultValues() {
-        IccLogicalChannelRequest defaultRequest = new IccLogicalChannelRequest();
-
-        assertThat(defaultRequest.subId).isEqualTo(SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        assertThat(defaultRequest.slotIndex).isEqualTo(SubscriptionManager.INVALID_SIM_SLOT_INDEX);
-        assertThat(defaultRequest.portIndex).isEqualTo(0 /* TelephonyManager.DEFAULT_PORT_INDEX */);
-        assertThat(defaultRequest.callingPackage).isNull();
-        assertThat(defaultRequest.aid).isNull();
-        assertThat(defaultRequest.p2).isEqualTo(0);
-        assertThat(defaultRequest.channel).isEqualTo(-1);
-        assertThat(defaultRequest.binder).isNull();
-    }
-
-    @Test
-    @SmallTest
-    public void testConstructor_withValidParmas_shouldReturnValidValues() {
-        IccLogicalChannelRequest request =
-                createIccLogicalChannelRequest(SUB_ID, SLOT_INDEX, PORT_INDEX, CALLING_PKG, AID, P2,
-                        CHANNEL, BINDER);
-
-        assertThat(request.subId).isEqualTo(SUB_ID);
-        assertThat(request.slotIndex).isEqualTo(SLOT_INDEX);
-        assertThat(request.portIndex).isEqualTo(PORT_INDEX);
-        assertThat(request.callingPackage).isEqualTo(CALLING_PKG);
-        assertThat(request.aid).isEqualTo(AID);
-        assertThat(request.p2).isEqualTo(P2);
-        assertThat(request.channel).isEqualTo(CHANNEL);
-        assertThat(request.binder).isEqualTo(BINDER);
-    }
-
-    @Test
-    @SmallTest
-    public void testEquals_sameInput_shouldReturnTrue() {
-        IccLogicalChannelRequest request1 =
-                createIccLogicalChannelRequest(SUB_ID, SLOT_INDEX, PORT_INDEX, CALLING_PKG, AID, P2,
-                        CHANNEL, BINDER);
-        IccLogicalChannelRequest request2 =
-                createIccLogicalChannelRequest(SUB_ID, SLOT_INDEX, PORT_INDEX, CALLING_PKG, AID, P2,
-                        CHANNEL, BINDER);
-
-        assertThat(request1).isEqualTo(request2);
-    }
-
-    @Test
-    @SmallTest
-    public void testEquals_differentBinder_shouldReturnFalse() {
-        IccLogicalChannelRequest request1 =
-                createIccLogicalChannelRequest(SUB_ID, SLOT_INDEX, PORT_INDEX, CALLING_PKG, AID, P2,
-                        CHANNEL, BINDER);
-        // request2 has same input as request1 but new Binder object
-        IccLogicalChannelRequest request2 =
-                createIccLogicalChannelRequest(SUB_ID, SLOT_INDEX, PORT_INDEX, CALLING_PKG, AID, P2,
-                        CHANNEL, new Binder());
-
-        assertThat(request1.equals(request2)).isFalse();
-    }
-
-    @Test
-    @SmallTest
-    public void testParcel() {
-        IccLogicalChannelRequest oldRequest =
-                createIccLogicalChannelRequest(SUB_ID, SLOT_INDEX, PORT_INDEX, CALLING_PKG, AID, P2,
-                        CHANNEL, BINDER);
-
-        Parcel p = Parcel.obtain();
-        oldRequest.writeToParcel(p, /*flags=*/0);
-        p.setDataPosition(0);
-        IccLogicalChannelRequest newRequest =
-                IccLogicalChannelRequest.CREATOR.createFromParcel(p);
-
-        assertThat(newRequest).isEqualTo(oldRequest);
-    }
-
-    private static IccLogicalChannelRequest createIccLogicalChannelRequest(int subId, int slotIndex,
-            int portIndex, String callingPackage, String aid, int p2, int channel, IBinder binder) {
-        IccLogicalChannelRequest request = new IccLogicalChannelRequest();
-        request.subId = subId;
-        request.slotIndex = slotIndex;
-        request.portIndex = portIndex;
-        request.callingPackage = callingPackage;
-        request.aid = aid;
-        request.p2 = p2;
-        request.channel = channel;
-        request.binder = binder;
-        return request;
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/IccSmsInterfaceManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/IccSmsInterfaceManagerTest.java
index 67d6e5c..93cc4e9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/IccSmsInterfaceManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/IccSmsInterfaceManagerTest.java
@@ -29,7 +29,6 @@
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -38,6 +37,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -48,20 +48,18 @@
     // object under test
     private IccSmsInterfaceManager mIccSmsInterfaceManager;
 
-    // Mocked classes
+    @Mock
     private SmsPermissions mMockSmsPermissions;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mMockSmsPermissions = mock(SmsPermissions.class);
         mIccSmsInterfaceManager = new IccSmsInterfaceManager(mPhone, mContext, mAppOpsManager,
                 mSmsDispatchersController, mMockSmsPermissions);
     }
 
     @After
     public void tearDown() throws Exception {
-        mIccSmsInterfaceManager = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java
index 6251560..d4ac4d5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.telephony;
 
-import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
-
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
@@ -27,7 +25,6 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -47,6 +44,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 import org.mockito.stubbing.Answer;
 
 import java.util.HashMap;
@@ -54,24 +52,18 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class ImsSmsDispatcherTest extends TelephonyTest {
-    // Mocked classes
-    private SmsDispatchersController mSmsDispatchersController;
-    private SMSDispatcher.SmsTracker mSmsTracker;
-    private ImsSmsDispatcher.FeatureConnectorFactory mConnectorFactory;
-    private FeatureConnector<ImsManager> mMockConnector;
-
+    @Mock private SmsDispatchersController mSmsDispatchersController;
+    @Mock private SMSDispatcher.SmsTracker mSmsTracker;
+    @Mock private ImsSmsDispatcher.FeatureConnectorFactory mConnectorFactory;
+    @Mock private FeatureConnector<ImsManager> mMockConnector;
     private FeatureConnector.Listener<ImsManager> mImsManagerListener;
     private HashMap<String, Object> mTrackerData;
     private ImsSmsDispatcher mImsSmsDispatcher;
-    private static final int SUB_0 = 0;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mSmsDispatchersController = mock(SmsDispatchersController.class);
-        mSmsTracker = mock(SMSDispatcher.SmsTracker.class);
-        mConnectorFactory = mock(ImsSmsDispatcher.FeatureConnectorFactory.class);
-        mMockConnector = mock(FeatureConnector.class);
+
         doAnswer((Answer<FeatureConnector<ImsManager>>) invocation -> {
             mImsManagerListener =
                     (FeatureConnector.Listener<ImsManager>) invocation.getArguments()[3];
@@ -82,7 +74,7 @@
         processAllMessages();
         // set the ImsManager instance
         verify(mMockConnector).connect();
-        mImsManagerListener.connectionReady(mImsManager, SUB_0);
+        mImsManagerListener.connectionReady(mImsManager);
         when(mSmsDispatchersController.isIms()).thenReturn(true);
         mTrackerData = new HashMap<>(1);
         when(mSmsTracker.getData()).thenReturn(mTrackerData);
@@ -91,8 +83,6 @@
     @After
     public void tearDown() throws Exception {
         mImsSmsDispatcher = null;
-        mImsManagerListener = null;
-        mTrackerData = null;
         super.tearDown();
     }
 
@@ -160,11 +150,9 @@
         mImsSmsDispatcher.mTrackers.put(token, mSmsTracker);
         when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
 
-        // Retry over IMS
+        // Fallback over GSM
         mImsSmsDispatcher.getSmsListener().onSendSmsResult(token, 0,
                 ImsSmsImplBase.SEND_STATUS_ERROR_RETRY, 0, SmsResponse.NO_ERROR_CODE);
-        waitForMs(SMSDispatcher.SEND_RETRY_DELAY + 200);
-        processAllMessages();
 
         // Make sure retry bit set
         ArgumentCaptor<byte[]> byteCaptor = ArgumentCaptor.forClass(byte[].class);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ImsiEncryptionInfoTest.java b/tests/telephonytests/src/com/android/internal/telephony/ImsiEncryptionInfoTest.java
index 0fcb384..e24dd21 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ImsiEncryptionInfoTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ImsiEncryptionInfoTest.java
@@ -60,8 +60,6 @@
     @After
     public void tearDown() throws Exception {
         mImsiEncryptionInfo = null;
-        mPublicKey = null;
-        mDate = null;
     }
 
     @Before
@@ -69,7 +67,7 @@
 
         mPublicKey = createPublicKey(TEST_CERT);
         mImsiEncryptionInfo = new ImsiEncryptionInfo("310", "270", TelephonyManager.KEY_TYPE_WLAN,
-                "key1=value", mPublicKey, mDate, 1);
+                "key1=value", mPublicKey, mDate);
     }
 
     private static PublicKey createPublicKey(String cert) throws Exception {
@@ -110,6 +108,5 @@
         assertEquals("key1=value", mImsiEncryptionInfo.getKeyIdentifier());
         assertEquals(mPublicKey, mImsiEncryptionInfo.getPublicKey());
         assertEquals(mDate, mImsiEncryptionInfo.getExpirationTime());
-        assertEquals(1, mImsiEncryptionInfo.getCarrierId());
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/InboundSmsTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/InboundSmsTrackerTest.java
index b11b94e..7bc26b7 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/InboundSmsTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/InboundSmsTrackerTest.java
@@ -20,7 +20,6 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import android.database.Cursor;
 import android.database.MatrixCursor;
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -28,7 +27,6 @@
 
 import com.android.internal.util.HexDump;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -57,11 +55,6 @@
                 InboundSmsHandler.SOURCE_NOT_INJECTED);
     }
 
-    @After
-    public void tearDown() {
-        mInboundSmsTracker = null;
-    }
-
     public static MatrixCursor createFakeCursor() {
         MatrixCursor mc = new MatrixCursor(
                 new String[]{"pdu", "seq", "dest", "date", "ref", "cnt", "addr", "id", "msg_body",
@@ -107,10 +100,8 @@
     @Test
     @SmallTest
     public void testInitializationFromDb() {
-        Cursor cursor = createFakeCursor();
         mInboundSmsTracker = new InboundSmsTracker(InstrumentationRegistry.getContext(),
-                cursor, false);
-        cursor.close();
+                createFakeCursor(), false);
         testInitialization();
     }
 }
\ No newline at end of file
diff --git a/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
index 19be558..bab6408 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/LocaleTrackerTest.java
@@ -94,8 +94,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mLocaleTracker = null;
-        mCellInfo = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/MissedIncomingCallSmsFilterTest.java b/tests/telephonytests/src/com/android/internal/telephony/MissedIncomingCallSmsFilterTest.java
index 510103c..d97f7ab 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/MissedIncomingCallSmsFilterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/MissedIncomingCallSmsFilterTest.java
@@ -51,15 +51,15 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
+        super.setUp(MissedIncomingCallSmsFilterTest.class.getSimpleName());
+
         mBundle = mContextFixture.getCarrierConfigBundle();
+
         mFilterUT = new MissedIncomingCallSmsFilter(mPhone);
     }
 
     @After
     public void tearDown() throws Exception {
-        mFilterUT = null;
-        mBundle = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
index bbb4639..56689f4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/MultiSimSettingControllerTest.java
@@ -34,7 +34,6 @@
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -63,6 +62,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -78,49 +78,47 @@
     private static final int SINGLE_SIM = 1;
     private static final int DUAL_SIM = 2;
     private MultiSimSettingController mMultiSimSettingControllerUT;
-    private Phone[] mPhones;
-    private ParcelUuid mGroupUuid1 = new ParcelUuid(UUID.randomUUID());
-
-    // Mocked classes
+    @Mock
     private SubscriptionController mSubControllerMock;
+    @Mock
     private Phone mPhoneMock1;
+    @Mock
     private Phone mPhoneMock2;
+    @Mock
     private DataEnabledSettings mDataEnabledSettingsMock1;
+    @Mock
     private DataEnabledSettings mDataEnabledSettingsMock2;
+    private Phone[] mPhones;
+    @Mock
     private CommandsInterface mMockCi;
 
+    ParcelUuid mGroupUuid1 = new ParcelUuid(UUID.randomUUID());
 
-    private final SubscriptionInfo mSubInfo1 = new SubscriptionInfo(1, "subInfo1 IccId", 0,
-            "T-mobile", "T-mobile", 0, 255, "12345", 0, null, "310", "260",
+    private SubscriptionInfo mSubInfo1 = new SubscriptionInfo(1, "subInfo1 IccId", 0, "T-mobile",
+            "T-mobile", 0, 255, "12345", 0, null, "310", "260",
             "156", false, null, null);
 
-    private final SubscriptionInfo mSubInfo2 = new SubscriptionInfo(2, "subInfo2 IccId", 1,
-            "T-mobile", "T-mobile", 0, 255, "12345", 0, null, "310", "260",
+    private SubscriptionInfo mSubInfo2 = new SubscriptionInfo(2, "subInfo2 IccId", 1, "T-mobile",
+            "T-mobile", 0, 255, "12345", 0, null, "310", "260",
             "156", false, null, null, -1, false, mGroupUuid1.toString(), false,
             TelephonyManager.UNKNOWN_CARRIER_ID, SubscriptionManager.PROFILE_CLASS_DEFAULT,
-            SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null, true, -1);
+            SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null, true);
 
-    private final SubscriptionInfo mSubInfo3 = new SubscriptionInfo(3, "subInfo3 IccId", -1,
-            "T-mobile", "T-mobile", 0, 255, "12345", 0, null, "310", "260",
+    private SubscriptionInfo mSubInfo3 = new SubscriptionInfo(3, "subInfo3 IccId", -1, "T-mobile",
+            "T-mobile", 0, 255, "12345", 0, null, "310", "260",
             "156", false, null, null, -1, false, mGroupUuid1.toString(), false,
             TelephonyManager.UNKNOWN_CARRIER_ID, SubscriptionManager.PROFILE_CLASS_DEFAULT,
-            SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null, true, -1);
+            SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null, true);
 
-    private final SubscriptionInfo mSubInfo4 = new SubscriptionInfo(4, "subInfo4 IccId", -1,
-            "T-mobile", "T-mobile", 0, 255, "12345", 0, null, "310", "260",
+    private SubscriptionInfo mSubInfo4 = new SubscriptionInfo(4, "subInfo4 IccId", -1, "T-mobile",
+            "T-mobile", 0, 255, "12345", 0, null, "310", "260",
             "156", false, null, null, -1, false, mGroupUuid1.toString(), false,
             TelephonyManager.UNKNOWN_CARRIER_ID, SubscriptionManager.PROFILE_CLASS_DEFAULT,
-            SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null, true, -1);
+            SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM, null, null, true);
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mSubControllerMock = mock(SubscriptionController.class);
-        mPhoneMock1 = mock(Phone.class);
-        mPhoneMock2 = mock(Phone.class);
-        mDataEnabledSettingsMock1 = mock(DataEnabledSettings.class);
-        mDataEnabledSettingsMock2 = mock(DataEnabledSettings.class);
-        mMockCi = mock(CommandsInterface.class);
+        super.setUp("SubscriptionControllerTest");
         // Default configuration:
         // DSDS device.
         // Sub 1 is the default sub.
@@ -165,9 +163,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mPhones = null;
-        mGroupUuid1 = null;
-        mMultiSimSettingControllerUT = null;
         super.tearDown();
     }
 
@@ -464,35 +459,6 @@
 
     @Test
     @SmallTest
-    public void testSimpleDsdsInSuW() {
-        // at first boot default is not set
-        doReturn(-1).when(mSubControllerMock).getDefaultDataSubId();
-
-        doReturn(true).when(mPhoneMock1).isUserDataEnabled();
-        doReturn(true).when(mPhoneMock2).isUserDataEnabled();
-        // setting DEVICE_PROVISIONED as 0 to indicate SuW is running.
-        Settings.Global.putInt(mContext.getContentResolver(),
-                Settings.Global.DEVICE_PROVISIONED, 0);
-        // After initialization, sub 2 should have mobile data off.
-        mMultiSimSettingControllerUT.notifyAllSubscriptionLoaded();
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(0, 1);
-        mMultiSimSettingControllerUT.notifyCarrierConfigChanged(1, 2);
-        processAllMessages();
-        verify(mDataEnabledSettingsMock1).setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, false);
-        verify(mDataEnabledSettingsMock2).setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, false);
-
-        // as a result of the above calls, update new values to be returned
-        doReturn(false).when(mPhoneMock1).isUserDataEnabled();
-        doReturn(false).when(mPhoneMock2).isUserDataEnabled();
-
-        // No user selection needed, no intent should be sent.
-        verify(mContext, never()).sendBroadcast(any());
-    }
-
-    @Test
-    @SmallTest
     public void testDsdsGrouping() {
         doReturn(2).when(mSubControllerMock).getDefaultDataSubId();
         doReturn(false).when(mPhoneMock1).isUserDataEnabled();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
index 0230645..be23df8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NetworkTypeControllerTest.java
@@ -21,17 +21,12 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 
-import android.content.Context;
 import android.content.Intent;
 import android.os.AsyncResult;
 import android.os.Handler;
-import android.os.IPowerManager;
-import android.os.IThermalService;
 import android.os.Looper;
 import android.os.PersistableBundle;
-import android.os.PowerManager;
 import android.telephony.CarrierConfigManager;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PcoData;
@@ -41,11 +36,11 @@
 import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
 import com.android.internal.telephony.dataconnection.DataConnection;
+import com.android.internal.telephony.dataconnection.DcController;
 import com.android.internal.util.IState;
 import com.android.internal.util.StateMachine;
 
@@ -53,6 +48,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -65,7 +61,7 @@
     private static final int EVENT_DATA_RAT_CHANGED = 2;
     private static final int EVENT_NR_STATE_CHANGED = 3;
     private static final int EVENT_NR_FREQUENCY_CHANGED = 4;
-    private static final int EVENT_PHYSICAL_LINK_STATUS_CHANGED = 5;
+    private static final int EVENT_PHYSICAL_LINK_STATE_CHANGED = 5;
     private static final int EVENT_PHYSICAL_CHANNEL_CONFIG_NOTIF_CHANGED = 6;
     private static final int EVENT_CARRIER_CONFIG_CHANGED = 7;
     private static final int EVENT_PRIMARY_TIMER_EXPIRED = 8;
@@ -78,9 +74,9 @@
 
     private NetworkTypeController mNetworkTypeController;
     private PersistableBundle mBundle;
-
-    // Mocked classes
+    @Mock
     DataConnection mDataConnection;
+    @Mock
     ApnSetting mApnSetting;
 
     private IState getCurrentState() throws Exception {
@@ -106,8 +102,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mDataConnection = mock(DataConnection.class);
-        mApnSetting = mock(ApnSetting.class);
         mBundle = mContextFixture.getCarrierConfigBundle();
         mBundle.putString(CarrierConfigManager.KEY_5G_ICON_CONFIGURATION_STRING,
                 "connected_mmwave:5G_Plus,connected:5G,not_restricted_rrc_idle:5G,"
@@ -120,7 +114,6 @@
                 mPhone).getCachedAllowedNetworkTypesBitmask();
         doReturn(false).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
                 TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
-        doReturn(new int[] {0}).when(mServiceState).getCellBandwidths();
         mNetworkTypeController = new NetworkTypeController(mPhone, mDisplayInfoController);
         processAllMessages();
     }
@@ -129,7 +122,6 @@
     public void tearDown() throws Exception {
         mNetworkTypeController.getHandler().removeCallbacksAndMessages(null);
         mNetworkTypeController = null;
-        mBundle = null;
         super.tearDown();
     }
 
@@ -286,8 +278,8 @@
         assertEquals("DefaultState", getCurrentState().getName());
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED,
-                new AsyncResult(null, DataCallResponse.LINK_STATUS_DORMANT, null));
+        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATE_CHANGED,
+                new AsyncResult(null, DcController.PHYSICAL_LINK_NOT_ACTIVE, null));
         mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
         processAllMessages();
         assertEquals("not_restricted_rrc_idle", getCurrentState().getName());
@@ -302,7 +294,7 @@
         assertEquals("DefaultState", getCurrentState().getName());
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
-        setPhysicalLinkStatus(false);
+        setPhysicalLinkState(false);
         mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
         mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
         processAllMessages();
@@ -321,8 +313,8 @@
         assertEquals("DefaultState", getCurrentState().getName());
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED,
-                new AsyncResult(null, DataCallResponse.LINK_STATUS_DORMANT, null));
+        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATE_CHANGED,
+                new AsyncResult(null, DcController.PHYSICAL_LINK_NOT_ACTIVE, null));
         mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
 
         processAllMessages();
@@ -335,8 +327,8 @@
         assertEquals("DefaultState", getCurrentState().getName());
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED,
-                new AsyncResult(null, DataCallResponse.LINK_STATUS_ACTIVE, null));
+        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATE_CHANGED,
+                new AsyncResult(null, DcController.PHYSICAL_LINK_ACTIVE, null));
         mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
         processAllMessages();
         assertEquals("not_restricted_rrc_con", getCurrentState().getName());
@@ -353,7 +345,7 @@
         assertEquals("DefaultState", getCurrentState().getName());
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
-        setPhysicalLinkStatus(true);
+        setPhysicalLinkState(true);
         mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
         mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
         processAllMessages();
@@ -373,8 +365,8 @@
         assertEquals("DefaultState", getCurrentState().getName());
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED,
-                new AsyncResult(null, DataCallResponse.LINK_STATUS_ACTIVE, null));
+        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATE_CHANGED,
+                new AsyncResult(null, DcController.PHYSICAL_LINK_ACTIVE, null));
         mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
 
         processAllMessages();
@@ -491,31 +483,6 @@
     }
 
     @Test
-    public void testTransitionToCurrentStateNrConnectedWithPcoLength4AndNoNrAdvancedCapable()
-            throws Exception {
-        assertEquals("DefaultState", getCurrentState().getName());
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
-        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
-        doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
-        mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
-        broadcastCarrierConfigs();
-        int cid = 1;
-        byte[] contents = new byte[]{31, 1, 84, 0};
-        doReturn(mDataConnection).when(mDcTracker).getDataConnectionByContextId(cid);
-        doReturn(mApnSetting).when(mDataConnection).getApnSetting();
-        doReturn(true).when(mApnSetting).canHandleType(ApnSetting.TYPE_DEFAULT);
-        mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
-        broadcastCarrierConfigs();
-
-
-        mNetworkTypeController.sendMessage(EVENT_PCO_DATA_CHANGED,
-                new AsyncResult(null, new PcoData(cid, "", 0xff03, contents), null));
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
-        processAllMessages();
-        assertEquals("connected", getCurrentState().getName());
-    }
-
-    @Test
     public void testTransitionToCurrentStateNrConnectedWithWrongPcoAndNoNrAdvancedCapable()
             throws Exception {
         assertEquals("DefaultState", getCurrentState().getName());
@@ -563,28 +530,6 @@
     }
 
     @Test
-    public void testTransitionToCurrentStateNrConnectedWithNrAdvancedCapableAndPcoLength4()
-            throws Exception {
-        assertEquals("DefaultState", getCurrentState().getName());
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
-        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
-        doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
-        int cid = 1;
-        byte[] contents = new byte[]{31, 1, 84, 1};
-        doReturn(mDataConnection).when(mDcTracker).getDataConnectionByContextId(cid);
-        doReturn(mApnSetting).when(mDataConnection).getApnSetting();
-        doReturn(true).when(mApnSetting).canHandleType(ApnSetting.TYPE_DEFAULT);
-        mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 0xFF03);
-        broadcastCarrierConfigs();
-
-        mNetworkTypeController.sendMessage(EVENT_PCO_DATA_CHANGED,
-                new AsyncResult(null, new PcoData(cid, "", 0xff03, contents), null));
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
-        processAllMessages();
-        assertEquals("connected_mmwave", getCurrentState().getName());
-    }
-
-    @Test
     public void testEventDataRatChanged() throws Exception {
         testTransitionToCurrentStateLegacy();
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
@@ -634,8 +579,8 @@
         testTransitionToCurrentStateNrConnectedMmwave();
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED,
-                new AsyncResult(null, DataCallResponse.LINK_STATUS_ACTIVE, null));
+        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATE_CHANGED,
+                new AsyncResult(null, DcController.PHYSICAL_LINK_ACTIVE, null));
         mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
         mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
         processAllMessages();
@@ -653,7 +598,7 @@
         testTransitionToCurrentStateNrConnectedMmwave();
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
-        setPhysicalLinkStatus(true);
+        setPhysicalLinkState(true);
         mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
         mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
         mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
@@ -677,8 +622,8 @@
         testTransitionToCurrentStateNrConnectedMmwave();
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED,
-                new AsyncResult(null, DataCallResponse.LINK_STATUS_ACTIVE, null));
+        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATE_CHANGED,
+                new AsyncResult(null, DcController.PHYSICAL_LINK_ACTIVE, null));
         mNetworkTypeController.sendMessage(EVENT_NR_FREQUENCY_CHANGED);
         mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
 
@@ -715,8 +660,8 @@
         // Transition to LTE connected state
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED,
-                new AsyncResult(null, DataCallResponse.LINK_STATUS_ACTIVE, null));
+        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATE_CHANGED,
+                new AsyncResult(null, DcController.PHYSICAL_LINK_ACTIVE, null));
         mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
         processAllMessages();
         assertEquals("not_restricted_rrc_con", getCurrentState().getName());
@@ -744,8 +689,8 @@
         // Transition to idle state
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_NOT_RESTRICTED).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED,
-                new AsyncResult(null, DataCallResponse.LINK_STATUS_DORMANT, null));
+        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATE_CHANGED,
+                new AsyncResult(null, DcController.PHYSICAL_LINK_NOT_ACTIVE, null));
         mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
         processAllMessages();
         assertEquals("not_restricted_rrc_idle", getCurrentState().getName());
@@ -763,11 +708,11 @@
     }
 
     @Test
-    public void testEventPhysicalLinkStatusChanged() throws Exception {
+    public void testEventPhysicalLinkStateChanged() throws Exception {
         testTransitionToCurrentStateLteConnected();
         doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED,
-                new AsyncResult(null, DataCallResponse.LINK_STATUS_DORMANT, null));
+        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATE_CHANGED,
+                new AsyncResult(null, DcController.PHYSICAL_LINK_NOT_ACTIVE, null));
 
         processAllMessages();
 
@@ -775,7 +720,7 @@
     }
 
     @Test
-    public void testEventPhysicalLinkStatusChangedSupportPhysicalChannelConfig1_6()
+    public void testEventPhysicalLinkStateChangedSupportPhysicalChannelConfig1_6()
             throws Exception {
         doReturn(true).when(mTelephonyManager).isRadioInterfaceCapabilitySupported(
                 TelephonyManager.CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED);
@@ -783,7 +728,7 @@
         processAllMessages();
         testTransitionToCurrentStateLteConnectedSupportPhysicalChannelConfig1_6();
         doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
-        setPhysicalLinkStatus(false);
+        setPhysicalLinkState(false);
         mNetworkTypeController.sendMessage(EVENT_PHYSICAL_CHANNEL_CONFIG_CHANGED);
 
         processAllMessages();
@@ -792,7 +737,7 @@
     }
 
     @Test
-    public void testEventPhysicalLinkStatusChanged_UsingUserDataForRrcDetection()
+    public void testEventPhysicalLinkStateChanged_UsingUserDataForRrcDetection()
             throws Exception {
         mBundle.putBoolean(
                 CarrierConfigManager.KEY_LTE_ENDC_USING_USER_DATA_FOR_RRC_DETECTION_BOOL, true);
@@ -803,8 +748,8 @@
         processAllMessages();
         testTransitionToCurrentStateLteConnected_usingUserDataForRrcDetection();
         doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
-        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATUS_CHANGED,
-                new AsyncResult(null, DataCallResponse.LINK_STATUS_DORMANT, null));
+        mNetworkTypeController.sendMessage(EVENT_PHYSICAL_LINK_STATE_CHANGED,
+                new AsyncResult(null, DcController.PHYSICAL_LINK_NOT_ACTIVE, null));
 
         processAllMessages();
 
@@ -889,36 +834,6 @@
     }
 
     @Test
-    public void testPrimaryTimerDeviceIdleMode() throws Exception {
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
-        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
-        mBundle.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING,
-                "connected_mmwave,any,10;connected,any,10;not_restricted_rrc_con,any,10");
-        broadcastCarrierConfigs();
-
-        IPowerManager powerManager = mock(IPowerManager.class);
-        PowerManager pm = new PowerManager(mContext, powerManager, mock(IThermalService.class),
-                new Handler(Looper.myLooper()));
-        doReturn(pm).when(mContext).getSystemService(Context.POWER_SERVICE);
-        doReturn(true).when(powerManager).isDeviceIdleMode();
-        mNetworkTypeController.sendMessage(17 /*EVENT_DEVICE_IDLE_MODE_CHANGED*/);
-
-        assertEquals("connected", getCurrentState().getName());
-        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
-                mNetworkTypeController.getOverrideNetworkType());
-
-        // should not trigger timer
-        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
-        processAllMessages();
-
-        assertEquals("legacy", getCurrentState().getName());
-        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
-                mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
-    }
-
-    @Test
     public void testPrimaryTimerReset() throws Exception {
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
@@ -956,36 +871,6 @@
     }
 
     @Test
-    public void testPrimaryTimerReset_theNetworkModeWithoutNr() throws Exception {
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
-        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
-        mBundle.putString(CarrierConfigManager.KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING,
-                "connected_mmwave,any,10;connected,any,10;not_restricted_rrc_con,any,10");
-        broadcastCarrierConfigs();
-
-        assertEquals("connected", getCurrentState().getName());
-        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA,
-                mNetworkTypeController.getOverrideNetworkType());
-
-        // remove NR from preferred network types
-        doReturn(RadioAccessFamily.getRafFromNetworkType(
-                TelephonyManager.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA)).when(
-                mPhone).getCachedAllowedNetworkTypesBitmask();
-
-        // trigger 10 second timer after disconnecting from NR, and then it does the timer reset
-        // since the network mode without the NR capability.
-        doReturn(NetworkRegistrationInfo.NR_STATE_NONE).when(mServiceState).getNrState();
-        mNetworkTypeController.sendMessage(EVENT_NR_STATE_CHANGED);
-        processAllMessages();
-
-        // timer should be reset.
-        assertEquals("legacy", getCurrentState().getName());
-        assertEquals(TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE,
-                mNetworkTypeController.getOverrideNetworkType());
-        assertFalse(mNetworkTypeController.is5GHysteresisActive());
-    }
-
-    @Test
     public void testPrimaryTimerExpireMmwave() throws Exception {
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
@@ -1285,11 +1170,11 @@
         assertFalse(mNetworkTypeController.is5GHysteresisActive());
     }
 
-    private void setPhysicalLinkStatus(Boolean state) {
+    private void setPhysicalLinkState(Boolean state) {
         List<PhysicalChannelConfig> lastPhysicalChannelConfigList = new ArrayList<>();
-        // If PhysicalChannelConfigList is empty, PhysicalLinkStatus is DcController
+        // If PhysicalChannelConfigList is empty, PhysicalLinkState is DcController
         // .PHYSICAL_LINK_NOT_ACTIVE
-        // If PhysicalChannelConfigList is not empty, PhysicalLinkStatus is DcController
+        // If PhysicalChannelConfigList is not empty, PhysicalLinkState is DcController
         // .PHYSICAL_LINK_ACTIVE
 
         if (state) {
@@ -1301,49 +1186,4 @@
         }
         doReturn(lastPhysicalChannelConfigList).when(mSST).getPhysicalChannelConfigList();
     }
-
-    @Test
-    public void testTransitionToCurrentStateNrConnectedWithLowBandwidth() throws Exception {
-        assertEquals("DefaultState", getCurrentState().getName());
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
-        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
-        doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
-        doReturn(new int[] {19999}).when(mServiceState).getCellBandwidths();
-        mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT, 20000);
-        broadcastCarrierConfigs();
-
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
-        processAllMessages();
-        assertEquals("connected", getCurrentState().getName());
-    }
-
-    @Test
-    public void testTransitionToCurrentStateNrConnectedWithHighBandwidth() throws Exception {
-        assertEquals("DefaultState", getCurrentState().getName());
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
-        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
-        doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
-        doReturn(new int[] {20001}).when(mServiceState).getCellBandwidths();
-        mBundle.putInt(CarrierConfigManager.KEY_NR_ADVANCED_THRESHOLD_BANDWIDTH_KHZ_INT, 20000);
-        broadcastCarrierConfigs();
-
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
-        processAllMessages();
-        assertEquals("connected_mmwave", getCurrentState().getName());
-    }
-
-    @Test
-    public void testNrAdvancedDisabledWhileRoaming() throws Exception {
-        assertEquals("DefaultState", getCurrentState().getName());
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
-        doReturn(true).when(mServiceState).getDataRoaming();
-        doReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED).when(mServiceState).getNrState();
-        doReturn(ServiceState.FREQUENCY_RANGE_MMWAVE).when(mServiceState).getNrFrequencyRange();
-        mBundle.putBoolean(CarrierConfigManager.KEY_ENABLE_NR_ADVANCED_WHILE_ROAMING_BOOL, false);
-        broadcastCarrierConfigs();
-
-        mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
-        processAllMessages();
-        assertEquals("connected", getCurrentState().getName());
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NitzDataTest.java b/tests/telephonytests/src/com/android/internal/telephony/NitzDataTest.java
index 2460dba..5f683c0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/NitzDataTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/NitzDataTest.java
@@ -47,21 +47,21 @@
         // tz, dt are in number of quarter-hours
         {
             NitzData nitz = NitzData.parse("15/06/20,01:02:03-1,0");
-            assertEquals(createUnixEpochTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
+            assertEquals(createUtcTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
             assertEquals(TimeUnit.MINUTES.toMillis(-1 * 15), nitz.getLocalOffsetMillis());
             assertEquals(0, nitz.getDstAdjustmentMillis().longValue());
             assertNull(nitz.getEmulatorHostTimeZone());
         }
         {
             NitzData nitz = NitzData.parse("15/06/20,01:02:03+8,1");
-            assertEquals(createUnixEpochTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
+            assertEquals(createUtcTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
             assertEquals(TimeUnit.MINUTES.toMillis(8 * 15), nitz.getLocalOffsetMillis());
             assertEquals(TimeUnit.HOURS.toMillis(1), nitz.getDstAdjustmentMillis().longValue());
             assertNull(nitz.getEmulatorHostTimeZone());
         }
         {
             NitzData nitz = NitzData.parse("15/06/20,01:02:03-8,1");
-            assertEquals(createUnixEpochTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
+            assertEquals(createUtcTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
             assertEquals(TimeUnit.MINUTES.toMillis(-8 * 15), nitz.getLocalOffsetMillis());
             assertEquals(TimeUnit.HOURS.toMillis(1), nitz.getDstAdjustmentMillis().longValue());
             assertNull(nitz.getEmulatorHostTimeZone());
@@ -72,14 +72,14 @@
     public void testParse_noDstField() {
         {
             NitzData nitz = NitzData.parse("15/06/20,01:02:03+4");
-            assertEquals(createUnixEpochTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
+            assertEquals(createUtcTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
             assertEquals(TimeUnit.MINUTES.toMillis(4 * 15), nitz.getLocalOffsetMillis());
             assertNull(nitz.getDstAdjustmentMillis());
             assertNull(nitz.getEmulatorHostTimeZone());
         }
         {
             NitzData nitz = NitzData.parse("15/06/20,01:02:03-4");
-            assertEquals(createUnixEpochTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
+            assertEquals(createUtcTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
             assertEquals(TimeUnit.MINUTES.toMillis(-4 * 15), nitz.getLocalOffsetMillis());
             assertNull(nitz.getDstAdjustmentMillis());
             assertNull(nitz.getEmulatorHostTimeZone());
@@ -89,7 +89,7 @@
     @Test
     public void testParse_androidEmulatorTimeZoneExtension() {
         NitzData nitz = NitzData.parse("15/06/20,01:02:03-32,1,America!Los_Angeles");
-        assertEquals(createUnixEpochTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
+        assertEquals(createUtcTime(2015, 6, 20, 1, 2, 3), nitz.getCurrentTimeInMillis());
         assertEquals(TimeUnit.MINUTES.toMillis(-32 * 15), nitz.getLocalOffsetMillis());
         assertEquals(TimeUnit.HOURS.toMillis(1), nitz.getDstAdjustmentMillis().longValue());
         assertEquals("America/Los_Angeles", nitz.getEmulatorHostTimeZone().getID());
@@ -103,7 +103,7 @@
                 .toString());
     }
 
-    private static long createUnixEpochTime(
+    private static long createUtcTime(
             int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minute, int second) {
         GregorianCalendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
         calendar.clear(); // Clear millis, etc.
diff --git a/tests/telephonytests/src/com/android/internal/telephony/NitzSignalTest.java b/tests/telephonytests/src/com/android/internal/telephony/NitzSignalTest.java
deleted file mode 100644
index 352a9aa..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/NitzSignalTest.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotEquals;
-
-import org.junit.Test;
-
-public class NitzSignalTest {
-
-    /** Sample cases for equals() and hashCode(). Not exhaustive. */
-    @Test
-    public void testEqualsAndHashCode() {
-        long receiptElapsedMillis1 = 1111;
-        NitzData nitzData1 = NitzData.createForTests(0, 0, 1234, null);
-        long ageMillis1 = 11;
-        NitzSignal nitzSignal1 = new NitzSignal(receiptElapsedMillis1, nitzData1, ageMillis1);
-        assertEquals(nitzSignal1, nitzSignal1);
-        assertEquals(nitzSignal1.hashCode(), nitzSignal1.hashCode());
-
-        NitzSignal nitzSignal1v2 = new NitzSignal(receiptElapsedMillis1, nitzData1, ageMillis1);
-        assertEquals(nitzSignal1, nitzSignal1v2);
-        assertEquals(nitzSignal1v2, nitzSignal1);
-        assertEquals(nitzSignal1.hashCode(), nitzSignal1v2.hashCode());
-
-        long receiptElapsedMillis2 = 2222;
-        NitzData nitzData2 = NitzData.createForTests(0, 0, 2345, null);
-        long ageMillis2 = 11;
-        NitzSignal nitzSignal2 = new NitzSignal(receiptElapsedMillis2, nitzData2, ageMillis2);
-        assertNotEquals(nitzSignal1, nitzSignal2);
-        assertNotEquals(nitzSignal2, nitzSignal1);
-    }
-
-    @Test
-    public void testGetAgeAdjustedRealtimeMillis_zeroAge() {
-        NitzData nitzData = NitzData.createForTests(0, 0, 1234, null);
-        long receiptElapsedRealtimeMillis = 1111;
-        long ageMillis = 0;
-        NitzSignal nitzSignal =
-                new NitzSignal(receiptElapsedRealtimeMillis, nitzData, ageMillis);
-        assertEquals(receiptElapsedRealtimeMillis,
-                nitzSignal.getReceiptElapsedRealtimeMillis());
-        assertEquals(ageMillis, nitzSignal.getAgeMillis());
-        assertEquals(receiptElapsedRealtimeMillis - ageMillis,
-                nitzSignal.getAgeAdjustedElapsedRealtimeMillis());
-    }
-
-    @Test
-    public void testGetAgeAdjustedRealtimeMillis_withAge() {
-        NitzData nitzData = NitzData.createForTests(0, 0, 1234, null);
-        long receiptElapsedRealtimeMillis = 1111;
-        long ageMillis = 5000;
-        NitzSignal nitzSignal =
-                new NitzSignal(receiptElapsedRealtimeMillis, nitzData, ageMillis);
-        assertEquals(receiptElapsedRealtimeMillis,
-                nitzSignal.getReceiptElapsedRealtimeMillis());
-        assertEquals(ageMillis, nitzSignal.getAgeMillis());
-        assertEquals(receiptElapsedRealtimeMillis - ageMillis,
-                nitzSignal.getAgeAdjustedElapsedRealtimeMillis());
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java
index 5771326..a702aac 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneConfigurationManagerTest.java
@@ -26,9 +26,7 @@
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -38,7 +36,6 @@
 import android.os.Handler;
 import android.os.Message;
 import android.telephony.PhoneCapability;
-import android.telephony.SubscriptionManager;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -48,16 +45,20 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
+import org.mockito.Mock;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class PhoneConfigurationManagerTest extends TelephonyTest {
-    // Mocked classes
+    @Mock
     Handler mHandler;
+    @Mock
     CommandsInterface mMockCi0;
+    @Mock
     CommandsInterface mMockCi1;
+    @Mock
     private Phone mPhone1; // mPhone as phone 0 is already defined in TelephonyTest.
+    @Mock
     PhoneConfigurationManager.MockableInterface mMi;
 
     private static final int EVENT_MULTI_SIM_CONFIG_CHANGED = 1;
@@ -66,11 +67,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mHandler = mock(Handler.class);
-        mMockCi0 = mock(CommandsInterface.class);
-        mMockCi1 = mock(CommandsInterface.class);
-        mPhone1 = mock(Phone.class);
-        mMi = mock(PhoneConfigurationManager.MockableInterface.class);
         mPhone.mCi = mMockCi0;
         mCT.mCi = mMockCi0;
         mPhone1.mCi = mMockCi1;
@@ -78,7 +74,7 @@
 
     @After
     public void tearDown() throws Exception {
-        mPcm = null;
+        // Restore system properties.
         super.tearDown();
     }
 
@@ -144,14 +140,68 @@
 
         // Try switching to dual SIM. Shouldn't work as we haven't indicated DSDS is supported.
         mPcm.switchMultiSimConfig(2);
-        verify(mMockRadioConfig, never()).setNumOfLiveModems(anyInt(), any());
+        verify(mMockRadioConfig, never()).setModemsConfig(anyInt(), any());
     }
 
     @Test
     @SmallTest
     public void testSwitchMultiSimConfig_dsdsCapable_noRebootRequired() throws Exception {
         init(1);
-        testSwitchFromSingleToDualSimModeNoReboot();
+        verify(mMockCi0, times(1)).registerForAvailable(any(), anyInt(), any());
+
+        // Register for multi SIM config change.
+        mPcm.registerForMultiSimConfigChange(mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED, null);
+        verify(mHandler, never()).sendMessageAtTime(any(), anyLong());
+
+        // Try switching to dual SIM. Shouldn't work as we haven't indicated DSDS is supported.
+        mPcm.switchMultiSimConfig(2);
+        verify(mMockRadioConfig, never()).setModemsConfig(anyInt(), any());
+
+        // Send static capability back to indicate DSDS is supported.
+        clearInvocations(mMockRadioConfig);
+        testGetDsdsCapability();
+        // testGetDsdsCapability leads to another call to registerForAvailable()
+        verify(mMockCi0, times(2)).registerForAvailable(any(), anyInt(), any());
+
+        // Try to switch to DSDS.
+        setRebootRequiredForConfigSwitch(false);
+        mPhones = new Phone[]{mPhone, mPhone1};
+        replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
+        mPcm.switchMultiSimConfig(2);
+        ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
+        verify(mMockRadioConfig).setModemsConfig(eq(2), captor.capture());
+
+        // Send message back to indicate switch success.
+        Message message = captor.getValue();
+        AsyncResult.forMessage(message, null, null);
+        message.sendToTarget();
+        processAllMessages();
+
+        // Verify set system property being called.
+        verify(mMi).setMultiSimProperties(2);
+        verify(mMi).notifyPhoneFactoryOnMultiSimConfigChanged(any(), eq(2));
+
+        // Capture and verify registration notification.
+        verify(mHandler).sendMessageAtTime(captor.capture(), anyLong());
+        message = captor.getValue();
+        assertEquals(EVENT_MULTI_SIM_CONFIG_CHANGED, message.what);
+        assertEquals(2, ((AsyncResult) message.obj).result);
+
+        // Capture and verify broadcast.
+        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+        verify(mContext).sendBroadcast(intentCaptor.capture());
+        Intent intent = intentCaptor.getValue();
+        assertEquals(ACTION_MULTI_SIM_CONFIG_CHANGED, intent.getAction());
+        assertEquals(2, intent.getIntExtra(
+                EXTRA_ACTIVE_SIM_SUPPORTED_COUNT, 0));
+
+        // Verify registerForAvailable() and onSlotActiveStatusChange() are called for the second
+        // phone, and not for the first phone (registerForAvailable() was already called twice
+        // earlier so verify that the count is still at 2)
+        verify(mMockCi0, times(2)).registerForAvailable(any(), anyInt(), any());
+        verify(mMockCi0, never()).onSlotActiveStatusChange(anyBoolean());
+        verify(mMockCi1, times(1)).registerForAvailable(any(), anyInt(), any());
+        verify(mMockCi1, times(1)).onSlotActiveStatusChange(anyBoolean());
     }
 
     @Test
@@ -171,7 +221,7 @@
         setRebootRequiredForConfigSwitch(false);
         mPcm.switchMultiSimConfig(1);
         ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
-        verify(mMockRadioConfig).setNumOfLiveModems(eq(1), captor.capture());
+        verify(mMockRadioConfig).setModemsConfig(eq(1), captor.capture());
 
         // Send message back to indicate switch success.
         Message message = captor.getValue();
@@ -207,111 +257,4 @@
         // Verify onPhoneRemoved() gets called on MultiSimSettingController phone
         verify(mMultiSimSettingController).onPhoneRemoved();
     }
-
-    @Test
-    @SmallTest
-    public void testNoCallPreferenceIsSetAfterSwitchToDsdsMode() throws Exception {
-        final int startingDefaultSubscriptionId = 2; // arbitrary value (can't be -1 which
-        // represents the "No Call Preference" value)
-
-        /*
-            TL;DR:  the following mockito code block dynamically changes the last call to the getter
-
-            doAnswer(invocation -> {
-                Integer value = (Integer) invocation.getArguments()[0];
-                Mockito.when(object.getter()).thenReturn(value);
-                return null;
-            }).when(object).setter(anyInt());
-
-            read the code block as, whenever we call the setter, change the Mock call
-            of the getter to whatever argument value we last passed to the setter.
-
-            ex.)    object.set( 2 )   --> next call to object.get() will return 2
-         */
-
-        // setup mocks for  VOICE mSubscriptionController. getter/setter
-        doAnswer(invocation -> {
-            Integer value = (Integer) invocation.getArguments()[0];
-            Mockito.when(mSubscriptionController.getDefaultVoiceSubId()).thenReturn(value);
-            return null;
-        }).when(mSubscriptionController).setDefaultVoiceSubId(anyInt());
-
-        // start off the phone stat with 1 active sim. reset values for new test.
-        init(1);
-
-        mSubscriptionController.setDefaultVoiceSubId(startingDefaultSubscriptionId);
-
-        // assert the mSubscriptionController registers the change
-        assertEquals(startingDefaultSubscriptionId, mSubscriptionController.getDefaultVoiceSubId());
-
-        // Perform the switch to DSDS mode and ensure all existing checks are not altered
-        testSwitchFromSingleToDualSimModeNoReboot();
-
-        // VOICE check
-        assertEquals(SubscriptionManager.INVALID_SUBSCRIPTION_ID /* No CALL Preference value */,
-                mSubscriptionController.getDefaultVoiceSubId()); //  Now, when the user goes to
-        // place a CALL, they will be prompted on which sim to use.
-    }
-
-    /**
-     * must call init(1) from the parent test before calling this helper test
-     * @throws Exception
-     */
-    public void testSwitchFromSingleToDualSimModeNoReboot() throws Exception {
-        verify(mMockCi0, times(1)).registerForAvailable(any(), anyInt(), any());
-
-        // Register for multi SIM config change.
-        mPcm.registerForMultiSimConfigChange(mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED, null);
-        verify(mHandler, never()).sendMessageAtTime(any(), anyLong());
-
-        // Try switching to dual SIM. Shouldn't work as we haven't indicated DSDS is supported.
-        mPcm.switchMultiSimConfig(2);
-        verify(mMockRadioConfig, never()).setNumOfLiveModems(anyInt(), any());
-
-        // Send static capability back to indicate DSDS is supported.
-        clearInvocations(mMockRadioConfig);
-        testGetDsdsCapability();
-        // testGetDsdsCapability leads to another call to registerForAvailable()
-        verify(mMockCi0, times(2)).registerForAvailable(any(), anyInt(), any());
-
-        // Try to switch to DSDS.
-        setRebootRequiredForConfigSwitch(false);
-        mPhones = new Phone[]{mPhone, mPhone1};
-        replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
-        mPcm.switchMultiSimConfig(2);
-        ArgumentCaptor<Message> captor = ArgumentCaptor.forClass(Message.class);
-        verify(mMockRadioConfig).setNumOfLiveModems(eq(2), captor.capture());
-
-        // Send message back to indicate switch success.
-        Message message = captor.getValue();
-        AsyncResult.forMessage(message, null, null);
-        message.sendToTarget();
-        processAllMessages();
-
-        // Verify set system property being called.
-        verify(mMi).setMultiSimProperties(2);
-        verify(mMi).notifyPhoneFactoryOnMultiSimConfigChanged(any(), eq(2));
-
-        // Capture and verify registration notification.
-        verify(mHandler).sendMessageAtTime(captor.capture(), anyLong());
-        message = captor.getValue();
-        assertEquals(EVENT_MULTI_SIM_CONFIG_CHANGED, message.what);
-        assertEquals(2, ((AsyncResult) message.obj).result);
-
-        // Capture and verify broadcast.
-        ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
-        verify(mContext).sendBroadcast(intentCaptor.capture());
-        Intent intent = intentCaptor.getValue();
-        assertEquals(ACTION_MULTI_SIM_CONFIG_CHANGED, intent.getAction());
-        assertEquals(2, intent.getIntExtra(
-                EXTRA_ACTIVE_SIM_SUPPORTED_COUNT, 0));
-
-        // Verify registerForAvailable() and onSlotActiveStatusChange() are called for the second
-        // phone, and not for the first phone (registerForAvailable() was already called twice
-        // earlier so verify that the count is still at 2)
-        verify(mMockCi0, times(2)).registerForAvailable(any(), anyInt(), any());
-        verify(mMockCi0, never()).onSlotActiveStatusChange(anyBoolean());
-        verify(mMockCi1, times(1)).registerForAvailable(any(), anyInt(), any());
-        verify(mMockCi1, times(1)).onSlotActiveStatusChange(anyBoolean());
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneStateListenerExecutorTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneStateListenerExecutorTest.java
index 5cd54c1..73126f7 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneStateListenerExecutorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneStateListenerExecutorTest.java
@@ -31,7 +31,13 @@
 import java.util.concurrent.Executor;
 
 public class PhoneStateListenerExecutorTest extends TelephonyTest {
-    private Executor mSimpleExecutor = Runnable::run;
+
+    private Executor mSimpleExecutor = new Executor() {
+        @Override
+        public void execute(Runnable r) {
+            r.run();
+        }
+    };
 
     private PhoneStateListener mPhoneStateListenerUT;
 
@@ -39,7 +45,7 @@
 
     @Before
     public void setUp() throws Exception {
-        this.setUp(getClass().getSimpleName());
+        this.setUp(this.getClass().getSimpleName());
 
         mPhoneStateListenerUT = new PhoneStateListener(mSimpleExecutor) {
             @Override
@@ -59,8 +65,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mSimpleExecutor = null;
-        mPhoneStateListenerUT = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneStateListenerTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneStateListenerTest.java
index 48b49d1..4747598 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneStateListenerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneStateListenerTest.java
@@ -78,9 +78,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mPhoneStateListenerUT = null;
-        mCalledEmergencyNumber = null;
-        mTextedEmergencyNumber = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java
index 606bcec..05256b8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java
@@ -25,7 +25,6 @@
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 
 import android.app.AppOpsManager;
 import android.app.PropertyInvalidatedCache;
@@ -39,6 +38,7 @@
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 
 public class PhoneSubInfoControllerTest extends TelephonyTest {
     private static final String FEATURE_ID = "myfeatureId";
@@ -47,13 +47,12 @@
     private AppOpsManager mAppOsMgr;
     private PackageManager mPm;
 
-    // Mocked classes
+    @Mock
     GsmCdmaPhone mSecondPhone;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mSecondPhone = mock(GsmCdmaPhone.class);
         PropertyInvalidatedCache.disableForTestMode();
         /* mPhone -> PhoneId: 0 -> SubId:0
            mSecondPhone -> PhoneId:1 -> SubId: 1*/
@@ -92,9 +91,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mAppOsMgr = null;
-        mPm = null;
-        mPhoneSubInfoControllerUT = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
similarity index 86%
rename from tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
rename to tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
index d50cb72..b0e9a37 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/PhoneSwitcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony;
 
 import static android.telephony.CarrierConfigManager.KEY_DATA_SWITCH_VALIDATION_TIMEOUT_LONG;
 import static android.telephony.TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED;
@@ -27,11 +27,11 @@
 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
 
-import static com.android.internal.telephony.data.PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS;
-import static com.android.internal.telephony.data.PhoneSwitcher.EVENT_DATA_ENABLED_CHANGED;
-import static com.android.internal.telephony.data.PhoneSwitcher.EVENT_IMS_RADIO_TECH_CHANGED;
-import static com.android.internal.telephony.data.PhoneSwitcher.EVENT_MULTI_SIM_CONFIG_CHANGED;
-import static com.android.internal.telephony.data.PhoneSwitcher.EVENT_PRECISE_CALL_STATE_CHANGED;
+import static com.android.internal.telephony.PhoneSwitcher.ECBM_DEFAULT_DATA_SWITCH_BASE_TIME_MS;
+import static com.android.internal.telephony.PhoneSwitcher.EVENT_DATA_ENABLED_CHANGED;
+import static com.android.internal.telephony.PhoneSwitcher.EVENT_IMS_RADIO_TECH_CHANGED;
+import static com.android.internal.telephony.PhoneSwitcher.EVENT_MULTI_SIM_CONFIG_CHANGED;
+import static com.android.internal.telephony.PhoneSwitcher.EVENT_PRECISE_CALL_STATE_CHANGED;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -45,7 +45,6 @@
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -70,15 +69,6 @@
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
-import com.android.internal.telephony.Call;
-import com.android.internal.telephony.CommandException;
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.GsmCdmaCall;
-import com.android.internal.telephony.ISetOpportunisticDataCallback;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.dataconnection.DataEnabledSettings;
 
 import org.junit.After;
@@ -86,6 +76,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -97,23 +88,33 @@
     private static final int EVENT_RADIO_ON = 108;
     private static final int EVENT_MODEM_COMMAND_DONE = 112;
 
-    // Mocked classes
-    CompletableFuture<Boolean> mFuturePhone;
+    @Mock
     private CommandsInterface mCommandsInterface0;
+    @Mock
     private CommandsInterface mCommandsInterface1;
+    @Mock
     private Phone mPhone2; // mPhone as phone 1 is already defined in TelephonyTest.
+    @Mock
     private Phone mImsPhone;
-    // TODO: Add logic for DataSettingsManager
+    @Mock
     private DataEnabledSettings mDataEnabledSettings2;
+    @Mock
     private Handler mActivePhoneSwitchHandler;
+    @Mock
     private GsmCdmaCall mActiveCall;
+    @Mock
     private GsmCdmaCall mHoldingCall;
+    @Mock
     private GsmCdmaCall mInactiveCall;
-    private GsmCdmaCall mDialCall;
-    private GsmCdmaCall mIncomingCall;
+    @Mock
     private ISetOpportunisticDataCallback mSetOpptDataCallback1;
+    @Mock
     private ISetOpportunisticDataCallback mSetOpptDataCallback2;
+    @Mock
+    CompletableFuture<Boolean> mFuturePhone;
+    @Mock
     PhoneSwitcher.ImsRegTechProvider mMockImsRegTechProvider;
+    @Mock
     private SubscriptionInfo mSubscriptionInfo;
 
     private PhoneSwitcher mPhoneSwitcher;
@@ -131,22 +132,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mFuturePhone = mock(CompletableFuture.class);
-        mCommandsInterface0 = mock(CommandsInterface.class);
-        mCommandsInterface1 = mock(CommandsInterface.class);
-        mPhone2 = mock(Phone.class); // mPhone as phone 1 is already defined in TelephonyTest.
-        mImsPhone = mock(Phone.class);
-        mDataEnabledSettings2 = mock(DataEnabledSettings.class);
-        mActivePhoneSwitchHandler = mock(Handler.class);
-        mActiveCall = mock(GsmCdmaCall.class);
-        mHoldingCall = mock(GsmCdmaCall.class);
-        mInactiveCall = mock(GsmCdmaCall.class);
-        mDialCall = mock(GsmCdmaCall.class);
-        mIncomingCall = mock(GsmCdmaCall.class);
-        mSetOpptDataCallback1 = mock(ISetOpportunisticDataCallback.class);
-        mSetOpptDataCallback2 = mock(ISetOpportunisticDataCallback.class);
-        mMockImsRegTechProvider = mock(PhoneSwitcher.ImsRegTechProvider.class);
-        mSubscriptionInfo = mock(SubscriptionInfo.class);
 
         PhoneCapability phoneCapability = new PhoneCapability(1, 1, null, false, new int[0]);
         doReturn(phoneCapability).when(mPhoneConfigurationManager).getCurrentPhoneCapability();
@@ -154,12 +139,6 @@
         doReturn(Call.State.ACTIVE).when(mActiveCall).getState();
         doReturn(Call.State.IDLE).when(mInactiveCall).getState();
         doReturn(Call.State.HOLDING).when(mHoldingCall).getState();
-        doReturn(Call.State.DIALING).when(mDialCall).getState();
-        doReturn(Call.State.INCOMING).when(mIncomingCall).getState();
-
-        doReturn(true).when(mInactiveCall).isIdle();
-        doReturn(false).when(mActiveCall).isIdle();
-        doReturn(false).when(mHoldingCall).isIdle();
 
         replaceInstance(Phone.class, "mCi", mPhone, mCommandsInterface0);
         replaceInstance(Phone.class, "mCi", mPhone2, mCommandsInterface1);
@@ -167,10 +146,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mPhoneSwitcher = null;
-        mSubChangedListener = null;
-        mConnectivityManager = null;
-        mNetworkProviderMessenger = null;
         super.tearDown();
     }
 
@@ -189,8 +164,7 @@
         NetworkRequest internetNetworkRequest = addInternetNetworkRequest(null, 50);
 
         assertFalse("phone active after request", mPhoneSwitcher
-                .shouldApplyNetworkRequest(
-                        new TelephonyNetworkRequest(internetNetworkRequest, mPhone), 0));
+                .shouldApplyNetworkRequest(internetNetworkRequest, 0));
 
         // not registered yet - shouldn't inc
         verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong());
@@ -512,14 +486,10 @@
         NetworkRequest mmsRequest = addMmsNetworkRequest(2);
         verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
         verify(mActivePhoneSwitchHandler, never()).sendMessageAtTime(any(), anyLong());
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(mmsRequest, mPhone), 0));
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(mmsRequest, mPhone), 1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1));
 
         // Set sub 2 as preferred sub should make phone 1 preferredDataModem
         doReturn(true).when(mSubscriptionController).isOpportunistic(2);
@@ -531,14 +501,10 @@
         Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget();
         processAllMessages();
         verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(mmsRequest, mPhone), 0));
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(mmsRequest, mPhone), 1));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 0));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1));
 
         clearInvocations(mMockRadioConfig);
         clearInvocations(mActivePhoneSwitchHandler);
@@ -554,14 +520,10 @@
         Message.obtain(mPhoneSwitcher, EVENT_MODEM_COMMAND_DONE, res).sendToTarget();
         processAllMessages();
         verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong());
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(mmsRequest, mPhone), 0));
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(mmsRequest, mPhone), 1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1));
 
         // SetDataAllowed should never be triggered.
         verify(mCommandsInterface0, never()).setDataAllowed(anyBoolean(), any());
@@ -658,63 +620,6 @@
 
     @Test
     @SmallTest
-    public void testNonDefaultDataPhoneInCall_ImsCallDialingOnLte_shouldSwitchDds()
-            throws Exception {
-        initialize();
-        setAllPhonesInactive();
-
-        // Phone 0 has sub 1, phone 1 has sub 2.
-        // Sub 1 is default data sub.
-        // Both are active subscriptions are active sub, as they are in both active slots.
-        setSlotIndexToSubId(0, 1);
-        setSlotIndexToSubId(1, 2);
-        setDefaultDataSubId(1);
-        processAllMessages();
-
-        // Phone 0 should be the default data phoneId.
-        assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId());
-
-        // Phone2 has active IMS call on LTE. And data of DEFAULT apn is enabled. This should
-        // trigger data switch.
-        doReturn(mImsPhone).when(mPhone2).getImsPhone();
-        doReturn(true).when(mDataEnabledSettings2).isDataEnabled(ApnSetting.TYPE_DEFAULT);
-        mockImsRegTech(1, REGISTRATION_TECH_LTE);
-        notifyPhoneAsInDial(mImsPhone);
-
-        // Phone 1 should become the default data phone.
-        assertEquals(1, mPhoneSwitcher.getPreferredDataPhoneId());
-    }
-    @Test
-    @SmallTest
-    public void testNonDefaultDataPhoneInCall_ImsCallIncomingOnLte_shouldSwitchDds()
-            throws Exception {
-        initialize();
-        setAllPhonesInactive();
-
-        // Phone 0 has sub 1, phone 1 has sub 2.
-        // Sub 1 is default data sub.
-        // Both are active subscriptions are active sub, as they are in both active slots.
-        setSlotIndexToSubId(0, 1);
-        setSlotIndexToSubId(1, 2);
-        setDefaultDataSubId(1);
-        processAllMessages();
-
-        // Phone 0 should be the default data phoneId.
-        assertEquals(0, mPhoneSwitcher.getPreferredDataPhoneId());
-
-        // Phone2 has active IMS call on LTE. And data of DEFAULT apn is enabled. This should
-        // trigger data switch.
-        doReturn(mImsPhone).when(mPhone2).getImsPhone();
-        doReturn(true).when(mDataEnabledSettings2).isDataEnabled(ApnSetting.TYPE_DEFAULT);
-        mockImsRegTech(1, REGISTRATION_TECH_LTE);
-        notifyPhoneAsInIncomingCall(mImsPhone);
-
-        // Phone 1 should become the default data phone.
-        assertEquals(1, mPhoneSwitcher.getPreferredDataPhoneId());
-    }
-
-    @Test
-    @SmallTest
     public void testNonDefaultDataPhoneInCall_ImsCallOnWlan_shouldNotSwitchDds() throws Exception {
         initialize();
         setAllPhonesInactive();
@@ -788,10 +693,8 @@
         setSlotIndexToSubId(1, 2);
         setDefaultDataSubId(1);
         NetworkRequest internetRequest = addInternetNetworkRequest(null, 50);
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
         clearInvocations(mMockRadioConfig);
         setAllPhonesInactive();
         // Initialization done.
@@ -800,36 +703,28 @@
         notifyDataEnabled(false);
         notifyPhoneAsInCall(mPhone2);
         verify(mMockRadioConfig, never()).setPreferredDataModem(anyInt(), any());
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
 
         // Phone2 has active call. So data switch to it.
         notifyDataEnabled(true);
         verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
         clearInvocations(mMockRadioConfig);
 
         // Phone2 call ended. So data switch back to default data sub.
         notifyPhoneAsInactive(mPhone2);
         verify(mMockRadioConfig).setPreferredDataModem(eq(0), any());
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
         clearInvocations(mMockRadioConfig);
 
         // Phone2 has holding call, but data is turned off. So no data switching should happen.
         notifyPhoneAsInHoldingCall(mPhone2);
         verify(mMockRadioConfig).setPreferredDataModem(eq(1), any());
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
     }
 
 
@@ -845,17 +740,13 @@
         setSlotIndexToSubId(1, 2);
         setDefaultDataSubId(1);
         NetworkRequest internetRequest = addInternetNetworkRequest(2, 50);
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
 
         // Restricted network request will should be applied.
         internetRequest = addInternetNetworkRequest(2, 50, true);
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
     }
 
     @Test
@@ -1213,10 +1104,8 @@
         setSlotIndexToSubId(1, 2);
         setDefaultDataSubId(1);
         NetworkRequest internetRequest = addInternetNetworkRequest(null, 50);
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
         clearInvocations(mMockRadioConfig);
         setAllPhonesInactive();
         // Initialization done.
@@ -1251,10 +1140,8 @@
         setSlotIndexToSubId(1, 2);
         setDefaultDataSubId(1);
         NetworkRequest internetRequest = addInternetNetworkRequest(null, 50);
-        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 0));
-        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                new TelephonyNetworkRequest(internetRequest, mPhone), 1));
+        assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 0));
+        assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, 1));
         clearInvocations(mMockRadioConfig);
         setAllPhonesInactive();
         // Initialization done.
@@ -1350,18 +1237,6 @@
         processAllMessages();
     }
 
-    private void notifyPhoneAsInDial(Phone phone) {
-        doReturn(mDialCall).when(phone).getForegroundCall();
-        mPhoneSwitcher.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED);
-        processAllMessages();
-    }
-
-    private void notifyPhoneAsInIncomingCall(Phone phone) {
-        doReturn(mIncomingCall).when(phone).getForegroundCall();
-        mPhoneSwitcher.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED);
-        processAllMessages();
-    }
-
     private void notifyPhoneAsInHoldingCall(Phone phone) {
         doReturn(mHoldingCall).when(phone).getBackgroundCall();
         mPhoneSwitcher.sendEmptyMessage(EVENT_PRECISE_CALL_STATE_CHANGED);
@@ -1432,11 +1307,9 @@
         for (int i = 0; i < mActiveModemCount; i++) {
             if (defaultDataSub == (i + 1)) {
                 // sub id is always phoneId+1 for testing
-                assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(
-                        new TelephonyNetworkRequest(internetRequest, mPhone), i));
+                assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, i));
             } else {
-                assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(
-                        new TelephonyNetworkRequest(internetRequest, mPhone), i));
+                assertFalse(mPhoneSwitcher.shouldApplyNetworkRequest(internetRequest, i));
             }
         }
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/PhysicalChannelConfigTest.java b/tests/telephonytests/src/com/android/internal/telephony/PhysicalChannelConfigTest.java
index d804698..853162a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/PhysicalChannelConfigTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/PhysicalChannelConfigTest.java
@@ -26,7 +26,6 @@
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 
-import org.junit.After;
 import org.junit.Test;
 
 /** Unit test for {@link android.telephony.PhysicalChannelConfig}. */
@@ -64,11 +63,6 @@
                 .build();
     }
 
-    @After
-    public void tearDown() {
-        mPhysicalChannelConfig = null;
-    }
-
     @Test
     public void testDownlinkFrequencyForNrArfcn(){
         setUpPhysicalChannelConfig(NETWORK_TYPE_NR, AccessNetworkConstants.NgranBands.BAND_1,
@@ -131,9 +125,11 @@
     @Test
     public void testFrequencyRangeWithoutBand() {
         try {
-            setUpPhysicalChannelConfig(NETWORK_TYPE_UMTS, 0, CHANNEL_NUMBER, CHANNEL_NUMBER, -1);
-            fail();
-        } catch (IllegalArgumentException expected) { }
+            setUpPhysicalChannelConfig(NETWORK_TYPE_UMTS, 0, CHANNEL_NUMBER, CHANNEL_NUMBER,
+                    ServiceState.FREQUENCY_RANGE_UNKNOWN);
+            fail("Frequency range: 0 is invalid.");
+        } catch (IllegalArgumentException e) {
+        }
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ProxyControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ProxyControllerTest.java
index 21514ef..128e6d8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ProxyControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ProxyControllerTest.java
@@ -16,23 +16,14 @@
 
 package com.android.internal.telephony;
 
-import static android.telephony.RadioAccessFamily.RAF_GSM;
-import static android.telephony.RadioAccessFamily.RAF_LTE;
-
 import static com.android.internal.telephony.ProxyController.EVENT_MULTI_SIM_CONFIG_CHANGED;
-import static com.android.internal.telephony.ProxyController.EVENT_START_RC_RESPONSE;
 
-import static org.junit.Assert.assertFalse;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
-import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.Message;
-import android.telephony.RadioAccessFamily;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -42,11 +33,12 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class ProxyControllerTest extends TelephonyTest {
-    // Mocked classes
+    @Mock
     Phone mPhone2;
 
     ProxyController mProxyController;
@@ -54,14 +46,13 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mPhone2 = mock(Phone.class);
         replaceInstance(ProxyController.class, "sProxyController", null, null);
         mProxyController = ProxyController.getInstance(mContext);
     }
 
     @After
     public void tearDown() throws Exception {
-        mProxyController = null;
+        // Restore system properties.
         super.tearDown();
     }
 
@@ -82,31 +73,4 @@
         Message.obtain(mProxyController.mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED).sendToTarget();
         processAllMessages();
     }
-
-    @Test
-    @SmallTest
-    public void testRequestNotSupported() throws Exception {
-        int activeModemCount = 2;
-        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone, mPhone2});
-        doReturn(activeModemCount).when(mTelephonyManager).getPhoneCount();
-        doReturn(RAF_GSM | RAF_LTE).when(mPhone).getRadioAccessFamily();
-        doReturn(RAF_GSM).when(mPhone2).getRadioAccessFamily();
-
-        Message.obtain(mProxyController.mHandler, EVENT_MULTI_SIM_CONFIG_CHANGED).sendToTarget();
-        processAllMessages();
-        verify(mPhone2).registerForRadioCapabilityChanged(any(), anyInt(), any());
-
-        RadioAccessFamily[] rafs = new RadioAccessFamily[activeModemCount];
-        rafs[0] = new RadioAccessFamily(0, RAF_GSM);
-        rafs[1] = new RadioAccessFamily(1, RAF_GSM | RAF_LTE);
-        mProxyController.setRadioCapability(rafs);
-
-        Message.obtain(mProxyController.mHandler, EVENT_START_RC_RESPONSE,
-                new AsyncResult(null, null,
-                        new CommandException(CommandException.Error.REQUEST_NOT_SUPPORTED)))
-                .sendToTarget();
-        processAllMessages();
-
-        assertFalse(mProxyController.isWakeLockHeld());
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
index 311fe20..2b4e484 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RILTest.java
@@ -30,7 +30,6 @@
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DTMF;
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENABLE_UICC_APPLICATIONS;
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION;
-import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION;
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_SIM_PIN;
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_SIM_PIN2;
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_ENTER_SIM_PUK;
@@ -159,23 +158,22 @@
 import android.telephony.data.DataCallResponse;
 import android.telephony.data.DataProfile;
 import android.telephony.data.EpsQos;
-import android.telephony.data.Qos;
 import android.telephony.data.QosBearerFilter;
 import android.telephony.data.QosBearerSession;
 import android.telephony.data.TrafficDescriptor;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
-import android.util.SparseArray;
 
 import androidx.test.filters.FlakyTest;
 
-import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
+import com.android.internal.telephony.dataconnection.DcTracker;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.io.ByteArrayInputStream;
 import java.io.DataInputStream;
@@ -198,13 +196,12 @@
     // refer to RIL#DEFAULT_WAKE_LOCK_TIMEOUT_MS
     private static final int DEFAULT_WAKE_LOCK_TIMEOUT_MS = 60000;
 
-    // Mocked classes
+    @Mock
     private ConnectivityManager mConnectionManager;
+    @Mock
     private TelephonyManager mTelephonyManager;
+    @Mock
     private IRadio mRadioProxy;
-    private RadioDataProxy mDataProxy;
-    private RadioNetworkProxy mNetworkProxy;
-    private RadioSimProxy mSimProxy;
 
     private HalVersion mRadioVersionV10 = new HalVersion(1, 0);
     private HalVersion mRadioVersionV11 = new HalVersion(1, 1);
@@ -274,14 +271,14 @@
     private static final int AUTH_TYPE = 0;
     private static final String USER_NAME = "username";
     private static final String PASSWORD = "password";
-    private static final int TYPE = DataProfile.TYPE_3GPP;
+    private static final int TYPE = 0;
+    private static final int MAX_CONNS_TIME = 1;
+    private static final int MAX_CONNS = 3;
+    private static final int WAIT_TIME = 10;
     private static final boolean APN_ENABLED = true;
-    private static final int SUPPORTED_APN_TYPES_BITMASK = ApnSetting.TYPE_CBS
-            | ApnSetting.TYPE_IMS;
-    private static final int SUPPORTED_NETWORK_TYPES_BITMASK =
-            (int) (TelephonyManager.NETWORK_TYPE_BITMASK_UMTS
-                    | TelephonyManager.NETWORK_TYPE_BITMASK_LTE);
+    private static final int SUPPORTED_APN_TYPES_BITMASK = 123456;
     private static final int ROAMING_PROTOCOL = ApnSetting.PROTOCOL_IPV6;
+    private static final int BEARER_BITMASK = 123123;
     private static final int MTU = 1234;
     private static final boolean PERSISTENT = true;
 
@@ -293,19 +290,14 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mConnectionManager = mock(ConnectivityManager.class);
-        mTelephonyManager = mock(TelephonyManager.class);
-        mRadioProxy = mock(IRadio.class);
-        mDataProxy = mock(RadioDataProxy.class);
-        mNetworkProxy = mock(RadioNetworkProxy.class);
-        mSimProxy = mock(RadioSimProxy.class);
+        super.setUp(RILTest.class.getSimpleName());
         try {
             TelephonyDevController.create();
         } catch (RuntimeException e) {
         }
         Context context = new ContextFixture().getTestDouble();
-        doReturn(true).when(mConnectionManager).isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
+        doReturn(true).when(mConnectionManager)
+            .isNetworkSupported(ConnectivityManager.TYPE_MOBILE);
         doReturn(mConnectionManager).when(context)
             .getSystemService(Context.CONNECTIVITY_SERVICE);
         doReturn(mTelephonyManager).when(context)
@@ -315,25 +307,13 @@
                 mock(IThermalService.class), new Handler(Looper.myLooper()));
         doReturn(powerManager).when(context).getSystemService(Context.POWER_SERVICE);
         doReturn(new ApplicationInfo()).when(context).getApplicationInfo();
-        SparseArray<RadioServiceProxy> proxies = new SparseArray<>();
-        proxies.put(RIL.RADIO_SERVICE, null);
-        proxies.put(RIL.DATA_SERVICE, mDataProxy);
-        proxies.put(RIL.NETWORK_SERVICE, mNetworkProxy);
-        proxies.put(RIL.SIM_SERVICE, mSimProxy);
+
         mRILInstance = new RIL(context,
                 RadioAccessFamily.getRafFromNetworkType(RILConstants.PREFERRED_NETWORK_MODE),
-                Phone.PREFERRED_CDMA_SUBSCRIPTION, 0, proxies);
+            Phone.PREFERRED_CDMA_SUBSCRIPTION, 0);
         mRILUnderTest = spy(mRILInstance);
         doReturn(mRadioProxy).when(mRILUnderTest).getRadioProxy(any());
-        doReturn(mDataProxy).when(mRILUnderTest).getRadioServiceProxy(eq(RadioDataProxy.class),
-                any());
-        doReturn(mNetworkProxy).when(mRILUnderTest).getRadioServiceProxy(
-                eq(RadioNetworkProxy.class), any());
-        doReturn(mSimProxy).when(mRILUnderTest).getRadioServiceProxy(eq(RadioSimProxy.class),
-                any());
-        doReturn(false).when(mDataProxy).isEmpty();
-        doReturn(false).when(mNetworkProxy).isEmpty();
-        doReturn(false).when(mSimProxy).isEmpty();
+
         try {
             replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV10);
         } catch (Exception e) {
@@ -342,12 +322,8 @@
 
     @After
     public void tearDown() throws Exception {
-        if (mRILUnderTest != null) {
-            mRILUnderTest.mWakeLock.release();
-            mRILUnderTest.mAckWakeLock.release();
-            mRILUnderTest = null;
-        }
-        mRILInstance = null;
+        mRILUnderTest.mWakeLock.release();
+        mRILUnderTest.mAckWakeLock.release();
         super.tearDown();
     }
 
@@ -480,78 +456,6 @@
 
     @FlakyTest
     @Test
-    public void testSupplySimDepersonalization() throws Exception {
-
-        String controlKey = "1234";
-        PersoSubState persoType = PersoSubState.PERSOSUBSTATE_SIM_NETWORK_PUK;
-
-        // Not supported on Radio 1.0.
-        mRILUnderTest.supplySimDepersonalization(persoType, controlKey, obtainMessage());
-        verify(mRadioProxy, never()).supplySimDepersonalization(anyInt(), anyInt(), eq(controlKey));
-        verify(mRadioProxy, never()).supplyNetworkDepersonalization(
-                anyInt(), eq(controlKey));
-
-        // Make radio version 1.5 to support the operation.
-        try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV15);
-        } catch (Exception e) {
-        }
-
-        mRILUnderTest.supplySimDepersonalization(persoType, controlKey, obtainMessage());
-        verify(mRadioProxy).supplySimDepersonalization(
-                mSerialNumberCaptor.capture(),
-                eq((int) invokeMethod(
-                        mRILInstance,
-                        "convertPersoTypeToHalPersoType",
-                        new Class<?>[] {PersoSubState.class},
-                        new Object[] {persoType})),
-                eq(controlKey));
-        verifyRILResponse(
-                mRILUnderTest,
-                mSerialNumberCaptor.getValue(),
-                RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION);
-    }
-
-    @FlakyTest
-    @Test
-    public void testSupplySimDepersonalizationWithNetworkLock() throws Exception {
-
-        String controlKey = "1234";
-        PersoSubState persoType = PersoSubState.PERSOSUBSTATE_SIM_NETWORK;
-
-        // use supplyNetworkDepersonalization on Radio 1.0.
-        mRILUnderTest.supplySimDepersonalization(persoType, controlKey, obtainMessage());
-        verify(mRadioProxy, never()).supplySimDepersonalization(anyInt(), anyInt(), eq(controlKey));
-        verify(mRadioProxy).supplyNetworkDepersonalization(
-                mSerialNumberCaptor.capture(), eq(controlKey));
-        verifyRILResponse(
-                mRILUnderTest,
-                mSerialNumberCaptor.getValue(),
-                RIL_REQUEST_ENTER_NETWORK_DEPERSONALIZATION);
-
-        // Make radio version 1.5 to support the operation.
-        try {
-            replaceInstance(RIL.class, "mRadioVersion", mRILUnderTest, mRadioVersionV15);
-        } catch (Exception e) {
-        }
-
-        mRILUnderTest.supplySimDepersonalization(persoType, controlKey, obtainMessage());
-        verify(mRadioProxy).supplySimDepersonalization(
-                mSerialNumberCaptor.capture(),
-                eq((int) invokeMethod(
-                        mRILInstance,
-                        "convertPersoTypeToHalPersoType",
-                        new Class<?>[] {PersoSubState.class},
-                        new Object[] {persoType})),
-                eq(controlKey));
-        verifyRILResponse(
-                mRILUnderTest,
-                mSerialNumberCaptor.getValue(),
-                RIL_REQUEST_ENTER_SIM_DEPERSONALIZATION);
-    }
-
-    @FlakyTest
-    @Test
     public void testGetCurrentCalls() throws Exception {
         mRILUnderTest.getCurrentCalls(obtainMessage());
         verify(mRadioProxy).getCurrentCalls(mSerialNumberCaptor.capture());
@@ -1121,21 +1025,12 @@
     @FlakyTest
     @Test
     public void testSetInitialAttachApn() throws Exception {
-        ApnSetting apnSetting = new ApnSetting.Builder()
-                .setId(-1)
-                .setOperatorNumeric("22210")
-                .setEntryName("Vodafone IT")
-                .setApnName("web.omnitel.it")
-                .setApnTypeBitmask(ApnSetting.TYPE_DUN)
-                .setProtocol(ApnSetting.PROTOCOL_IP)
-                .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-                .setCarrierEnabled(true)
-                .build();
-
-        DataProfile dataProfile = new DataProfile.Builder()
-                .setApnSetting(apnSetting)
-                .setPreferred(false)
-                .build();
+        ApnSetting apnSetting = ApnSetting.makeApnSetting(
+                -1, "22210", "Vodafone IT", "web.omnitel.it", null, -1,
+                null, null, -1, "", "", 0, ApnSetting.TYPE_DUN, ApnSetting.PROTOCOL_IP,
+                ApnSetting.PROTOCOL_IP, true, 0, 0, false, 0, 0, 0, 0, -1, "");
+        DataProfile dataProfile = DcTracker.createDataProfile(
+                apnSetting, apnSetting.getProfileId(), false);
         boolean isRoaming = false;
 
         mRILUnderTest.setInitialAttachApn(dataProfile, isRoaming, obtainMessage());
@@ -1471,7 +1366,7 @@
     public void testGetBarringInfo() throws Exception {
         // Not supported on Radio 1.0.
         mRILUnderTest.getBarringInfo(obtainMessage());
-        verify(mNetworkProxy, never()).getBarringInfo(anyInt());
+        verify(mRadioProxy, never()).getBarringInfo(anyInt());
 
         // Make radio version 1.5 to support the operation.
         try {
@@ -1479,7 +1374,7 @@
         } catch (Exception e) {
         }
         mRILUnderTest.getBarringInfo(obtainMessage());
-        verify(mNetworkProxy).getBarringInfo(mSerialNumberCaptor.capture());
+        verify(mRadioProxy).getBarringInfo(mSerialNumberCaptor.capture());
         verifyRILResponse(
                 mRILUnderTest, mSerialNumberCaptor.getValue(), RIL_REQUEST_GET_BARRING_INFO);
     }
@@ -1597,10 +1492,11 @@
         record.timeStampType = RIL_TIMESTAMP_TYPE_OEM_RIL;
         record.timeStamp = TIMESTAMP;
         record.lte.add(lte);
-        ArrayList<Object> records = new ArrayList<>();
+        ArrayList<android.hardware.radio.V1_0.CellInfo> records =
+                new ArrayList<android.hardware.radio.V1_0.CellInfo>();
         records.add(record);
 
-        ArrayList<CellInfo> ret = RILUtils.convertHalCellInfoList(records);
+        ArrayList<CellInfo> ret = RIL.convertHalCellInfoList(records);
 
         assertEquals(1, ret.size());
         CellInfoLte cellInfoLte = (CellInfoLte) ret.get(0);
@@ -1638,10 +1534,11 @@
         record.timeStampType = RIL_TIMESTAMP_TYPE_OEM_RIL;
         record.timeStamp = TIMESTAMP;
         record.gsm.add(cellinfo);
-        ArrayList<Object> records = new ArrayList<>();
+        ArrayList<android.hardware.radio.V1_0.CellInfo> records =
+                new ArrayList<android.hardware.radio.V1_0.CellInfo>();
         records.add(record);
 
-        ArrayList<CellInfo> ret = RILUtils.convertHalCellInfoList(records);
+        ArrayList<CellInfo> ret = RIL.convertHalCellInfoList(records);
 
         assertEquals(1, ret.size());
         CellInfoGsm cellInfoGsm = (CellInfoGsm) ret.get(0);
@@ -1678,10 +1575,11 @@
         record.timeStampType = RIL_TIMESTAMP_TYPE_OEM_RIL;
         record.timeStamp = TIMESTAMP;
         record.wcdma.add(cellinfo);
-        ArrayList<Object> records = new ArrayList<>();
+        ArrayList<android.hardware.radio.V1_0.CellInfo> records =
+                new ArrayList<android.hardware.radio.V1_0.CellInfo>();
         records.add(record);
 
-        ArrayList<CellInfo> ret = RILUtils.convertHalCellInfoList(records);
+        ArrayList<CellInfo> ret = RIL.convertHalCellInfoList(records);
 
         assertEquals(1, ret.size());
         CellInfoWcdma cellInfoWcdma = (CellInfoWcdma) ret.get(0);
@@ -1727,10 +1625,11 @@
         record.timeStampType = RIL_TIMESTAMP_TYPE_OEM_RIL;
         record.timeStamp = TIMESTAMP;
         record.tdscdma.add(cellinfo);
-        ArrayList<Object> records = new ArrayList<>();
+        ArrayList<android.hardware.radio.V1_2.CellInfo> records =
+                new ArrayList<android.hardware.radio.V1_2.CellInfo>();
         records.add(record);
 
-        ArrayList<CellInfo> ret = RILUtils.convertHalCellInfoList(records);
+        ArrayList<CellInfo> ret = RIL.convertHalCellInfoList_1_2(records);
 
         assertEquals(1, ret.size());
         CellInfoTdscdma cellInfoTdscdma = (CellInfoTdscdma) ret.get(0);
@@ -1769,10 +1668,11 @@
         record.timeStampType = RIL_TIMESTAMP_TYPE_OEM_RIL;
         record.timeStamp = TIMESTAMP;
         record.cdma.add(cellinfo);
-        ArrayList<Object> records = new ArrayList<>();
+        ArrayList<android.hardware.radio.V1_0.CellInfo> records =
+                new ArrayList<android.hardware.radio.V1_0.CellInfo>();
         records.add(record);
 
-        ArrayList<CellInfo> ret = RILUtils.convertHalCellInfoList(records);
+        ArrayList<CellInfo> ret = RIL.convertHalCellInfoList(records);
 
         assertEquals(1, ret.size());
         CellInfoCdma cellInfoCdma = (CellInfoCdma) ret.get(0);
@@ -2055,10 +1955,10 @@
         android.hardware.radio.V1_4.CellInfo record = new android.hardware.radio.V1_4.CellInfo();
         record.info.nr(cellinfo);
 
-        ArrayList<Object> records = new ArrayList<>();
+        ArrayList<android.hardware.radio.V1_4.CellInfo> records = new ArrayList<>();
         records.add(record);
 
-        ArrayList<CellInfo> ret = RILUtils.convertHalCellInfoList(records);
+        ArrayList<CellInfo> ret = RIL.convertHalCellInfoList_1_4(records);
 
         CellInfoNr cellInfoNr = (CellInfoNr) ret.get(0);
         CellIdentityNr cellIdentityNr = (CellIdentityNr) cellInfoNr.getCellIdentity();
@@ -2108,7 +2008,7 @@
                 new android.hardware.radio.V1_5.CellIdentityLte();
         initializeCellIdentityLte_1_5(halCellIdentity, false, true);
 
-        CellIdentityLte cellIdentity = RILUtils.convertHalCellIdentityLte(halCellIdentity);
+        CellIdentityLte cellIdentity = new CellIdentityLte(halCellIdentity);
 
         assertEquals(CSG_INDICATION,
                 cellIdentity.getClosedSubscriberGroupInfo().getCsgIndicator());
@@ -2124,7 +2024,7 @@
                 new android.hardware.radio.V1_5.CellIdentityLte();
         initializeCellIdentityLte_1_5(halCellIdentity, true, false);
 
-        CellIdentityLte cellIdentity = RILUtils.convertHalCellIdentityLte(halCellIdentity);
+        CellIdentityLte cellIdentity = new CellIdentityLte(halCellIdentity);
 
         Set<String> additionalPlmns = new HashSet<>();
         Collections.addAll(additionalPlmns, ADDITIONAL_PLMNS);
@@ -2139,7 +2039,8 @@
         initializeCellIdentityWcdma_1_2(id.base);
 
         if (addAdditionalPlmns) {
-            id.additionalPlmns = new ArrayList<>(Arrays.asList(ADDITIONAL_PLMNS));
+            id.additionalPlmns = new ArrayList<>(
+                    Arrays.asList(ADDITIONAL_PLMNS));
         }
 
         if (addCsgInfo) {
@@ -2153,7 +2054,7 @@
                 new android.hardware.radio.V1_5.CellIdentityWcdma();
         initializeCellIdentityWcdma_1_5(halCellIdentity, false, true);
 
-        CellIdentityWcdma cellIdentity = RILUtils.convertHalCellIdentityWcdma(halCellIdentity);
+        CellIdentityWcdma cellIdentity = new CellIdentityWcdma(halCellIdentity);
 
         assertEquals(CSG_INDICATION,
                 cellIdentity.getClosedSubscriberGroupInfo().getCsgIndicator());
@@ -2169,7 +2070,7 @@
                 new android.hardware.radio.V1_5.CellIdentityWcdma();
         initializeCellIdentityWcdma_1_5(halCellIdentity, true, false);
 
-        CellIdentityWcdma cellIdentity = RILUtils.convertHalCellIdentityWcdma(halCellIdentity);
+        CellIdentityWcdma cellIdentity = new CellIdentityWcdma(halCellIdentity);
 
         Set<String> additionalPlmns = new HashSet<>();
         Collections.addAll(additionalPlmns, ADDITIONAL_PLMNS);
@@ -2184,7 +2085,8 @@
         initializeCellIdentityTdscdma_1_2(id.base);
 
         if (addAdditionalPlmns) {
-            id.additionalPlmns = new ArrayList<>(Arrays.asList(ADDITIONAL_PLMNS));
+            id.additionalPlmns = new ArrayList<>(
+                    Arrays.asList(ADDITIONAL_PLMNS));
         }
 
         if (addCsgInfo) {
@@ -2198,7 +2100,7 @@
                 new android.hardware.radio.V1_5.CellIdentityTdscdma();
         initializeCellIdentityTdscdma_1_5(halCellIdentity, false, true);
 
-        CellIdentityTdscdma cellIdentity = RILUtils.convertHalCellIdentityTdscdma(halCellIdentity);
+        CellIdentityTdscdma cellIdentity = new CellIdentityTdscdma(halCellIdentity);
 
         assertEquals(CSG_INDICATION,
                 cellIdentity.getClosedSubscriberGroupInfo().getCsgIndicator());
@@ -2214,7 +2116,7 @@
                 new android.hardware.radio.V1_5.CellIdentityTdscdma();
         initializeCellIdentityTdscdma_1_5(halCellIdentity, true, false);
 
-        CellIdentityTdscdma cellIdentity = RILUtils.convertHalCellIdentityTdscdma(halCellIdentity);
+        CellIdentityTdscdma cellIdentity = new CellIdentityTdscdma(halCellIdentity);
 
         Set<String> additionalPlmns = new HashSet<>();
         Collections.addAll(additionalPlmns, ADDITIONAL_PLMNS);
@@ -2264,7 +2166,7 @@
                 .setTrafficDescriptors(new ArrayList<>())
                 .build();
 
-        assertEquals(response, RILUtils.convertHalDataCallResult(result10));
+        assertEquals(response, RIL.convertDataCallResult(result10));
 
         // Test V1.4 SetupDataCallResult
         android.hardware.radio.V1_4.SetupDataCallResult result14 =
@@ -2283,7 +2185,7 @@
                 "fd00:976a:c206:20::6", "fd00:976a:c206:20::9", "fd00:976a:c202:1d::9"));
         result14.mtu = 1500;
 
-        assertEquals(response, RILUtils.convertHalDataCallResult(result14));
+        assertEquals(response, RIL.convertDataCallResult(result14));
 
         // Test V1.5 SetupDataCallResult
         android.hardware.radio.V1_5.SetupDataCallResult result15 =
@@ -2339,7 +2241,7 @@
                 .setTrafficDescriptors(new ArrayList<>())
                 .build();
 
-        assertEquals(response, RILUtils.convertHalDataCallResult(result15));
+        assertEquals(response, RIL.convertDataCallResult(result15));
 
         // Test V1.6 SetupDataCallResult
         android.hardware.radio.V1_6.SetupDataCallResult result16 =
@@ -2403,7 +2305,7 @@
 
         result16.qosSessions = new ArrayList<>(Arrays.asList(halQosSession));
 
-        EpsQos epsQos = new EpsQos(new Qos.QosBandwidth(4, 7), new Qos.QosBandwidth(5, 8), 4);
+        EpsQos epsQos = new EpsQos(halEpsQos);
         QosBearerFilter qosFilter = new QosBearerFilter(
                 Arrays.asList(
                         new LinkAddress(InetAddresses.parseNumericAddress("122.22.22.22"), 32)),
@@ -2428,12 +2330,8 @@
         android.hardware.radio.V1_6.OptionalOsAppId halOsAppId =
                 new android.hardware.radio.V1_6.OptionalOsAppId();
         android.hardware.radio.V1_6.OsAppId osAppId = new android.hardware.radio.V1_6.OsAppId();
-        // 97a498e3fc925c9489860333d06e4e470a454e5445525052495345.
-        // [OsAppId.ANDROID_OS_ID, "ENTERPRISE", 1]
-        byte[] osAppIdArray = {-105, -92, -104, -29, -4, -110, 92,
-                -108, -119, -122, 3, 51, -48, 110, 78, 71, 10, 69, 78, 84, 69,
-                82, 80, 82, 73, 83, 69};
-        osAppId.osAppId = RILUtils.primitiveArrayToArrayList(osAppIdArray);
+        byte[] osAppIdArray = {1, 2, 3, 4};
+        osAppId.osAppId = mRILUnderTest.primitiveArrayToArrayList(osAppIdArray);
         halOsAppId.value(osAppId);
 
         halTrafficDescriptor.dnn = halDnn;
@@ -2470,7 +2368,7 @@
                 .setTrafficDescriptors(trafficDescriptors)
                 .build();
 
-        assertEquals(response, RILUtils.convertHalDataCallResult(result16));
+        assertEquals(response, RIL.convertDataCallResult(result16));
     }
 
     @Test
@@ -2499,7 +2397,8 @@
 
     @Test
     public void testCellInfoTimestamp_1_4() {
-        ArrayList<Object> records = new ArrayList<>();
+        ArrayList<android.hardware.radio.V1_4.CellInfo> records =
+                new ArrayList<android.hardware.radio.V1_4.CellInfo>();
 
         for (int i = 0; i < 5 /* arbitrary */; i++) {
             android.hardware.radio.V1_4.CellInfo record =
@@ -2511,7 +2410,7 @@
 
             records.add(record);
         }
-        List<CellInfo> cil = RILUtils.convertHalCellInfoList(records);
+        List<CellInfo> cil = RIL.convertHalCellInfoList_1_4(records);
 
         // Check that all timestamps are set to a valid number and are equal
         final long ts = cil.get(0).getTimeStamp();
@@ -2523,7 +2422,8 @@
 
     @Test
     public void testCellInfoTimestamp_1_2() {
-        ArrayList<Object> records = new ArrayList<>();
+        ArrayList<android.hardware.radio.V1_2.CellInfo> records =
+                new ArrayList<android.hardware.radio.V1_2.CellInfo>();
 
         for (int i = 0; i < 5 /* arbitrary */; i++) {
             android.hardware.radio.V1_2.CellInfo record =
@@ -2538,7 +2438,7 @@
 
             records.add(record);
         }
-        List<CellInfo> cil = RILUtils.convertHalCellInfoList(records);
+        List<CellInfo> cil = RIL.convertHalCellInfoList_1_2(records);
 
         // Check that all timestamps are set to a valid number and are equal
         final long ts = cil.get(0).getTimeStamp();
@@ -2593,9 +2493,10 @@
         record.timeStamp = TIMESTAMP;
         record.lte.add(lte);
         record.connectionStatus = 0;
-        ArrayList<Object> records = new ArrayList<>();
+        ArrayList<android.hardware.radio.V1_2.CellInfo> records =
+                new ArrayList<android.hardware.radio.V1_2.CellInfo>();
         records.add(record);
-        return RILUtils.convertHalCellInfoList(records);
+        return RIL.convertHalCellInfoList_1_2(records);
     }
 
     private ArrayList<CellInfo> getCellInfoListForGSM(
@@ -2620,10 +2521,11 @@
         record.timeStamp = TIMESTAMP;
         record.gsm.add(cellinfo);
         record.connectionStatus = 0;
-        ArrayList<Object> records = new ArrayList<>();
+        ArrayList<android.hardware.radio.V1_2.CellInfo> records =
+                new ArrayList<android.hardware.radio.V1_2.CellInfo>();
         records.add(record);
 
-        return RILUtils.convertHalCellInfoList(records);
+        return RIL.convertHalCellInfoList_1_2(records);
     }
 
     private static void initializeCellIdentityWcdma_1_2(
@@ -2662,10 +2564,11 @@
         record.timeStamp = TIMESTAMP;
         record.wcdma.add(cellinfo);
         record.connectionStatus = 0;
-        ArrayList<Object> records = new ArrayList<>();
+        ArrayList<android.hardware.radio.V1_2.CellInfo> records =
+                new ArrayList<android.hardware.radio.V1_2.CellInfo>();
         records.add(record);
 
-        return RILUtils.convertHalCellInfoList(records);
+        return RIL.convertHalCellInfoList_1_2(records);
     }
 
     private ArrayList<CellInfo> getCellInfoListForCdma(String alphaLong, String alphaShort) {
@@ -2690,58 +2593,62 @@
         record.timeStamp = TIMESTAMP;
         record.cdma.add(cellinfo);
         record.connectionStatus = 0;
-        ArrayList<Object> records = new ArrayList<>();
+        ArrayList<android.hardware.radio.V1_2.CellInfo> records =
+                new ArrayList<android.hardware.radio.V1_2.CellInfo>();
         records.add(record);
 
-        return RILUtils.convertHalCellInfoList(records);
+        return RIL.convertHalCellInfoList_1_2(records);
     }
 
     @Test
     public void testSetupDataCall() throws Exception {
-        ApnSetting apn = new ApnSetting.Builder()
-                .setId(1234)
-                .setEntryName(APN)
-                .setApnName(APN)
-                .setApnTypeBitmask(SUPPORTED_APN_TYPES_BITMASK)
-                .setProtocol(ApnSetting.PROTOCOL_IPV6)
-                .setRoamingProtocol(ApnSetting.PROTOCOL_IPV6)
-                .setCarrierEnabled(true)
-                .setProfileId(PROFILE_ID)
-                .setAuthType(AUTH_TYPE)
-                .setUser(USER_NAME)
-                .setPassword(PASSWORD)
-                .setNetworkTypeBitmask(SUPPORTED_NETWORK_TYPES_BITMASK)
-                .setMtuV4(MTU)
-                .setModemCognitive(true)
-                .build();
-
         DataProfile dp = new DataProfile.Builder()
-                .setApnSetting(apn)
+                .setProfileId(PROFILE_ID)
+                .setApn(APN)
+                .setProtocolType(PROTOCOL)
+                .setAuthType(AUTH_TYPE)
+                .setUserName(USER_NAME)
+                .setPassword(PASSWORD)
+                .setType(TYPE)
+                .setMaxConnectionsTime(MAX_CONNS_TIME)
+                .setMaxConnections(MAX_CONNS)
+                .setWaitTime(WAIT_TIME)
+                .enable(APN_ENABLED)
+                .setSupportedApnTypesBitmask(SUPPORTED_APN_TYPES_BITMASK)
+                .setRoamingProtocolType(ROAMING_PROTOCOL)
+                .setBearerBitmask(BEARER_BITMASK)
+                .setMtu(MTU)
+                .setPersistent(PERSISTENT)
                 .setPreferred(false)
                 .build();
 
         mRILUnderTest.setupDataCall(AccessNetworkConstants.AccessNetworkType.EUTRAN, dp, false,
-                false, 0, null, DataCallResponse.PDU_SESSION_ID_NOT_SET, null, null, true,
-                obtainMessage());
-        ArgumentCaptor<DataProfile> dpiCaptor = ArgumentCaptor.forClass(DataProfile.class);
-        verify(mDataProxy).setupDataCall(mSerialNumberCaptor.capture(),
-                anyInt(), eq(AccessNetworkConstants.AccessNetworkType.EUTRAN), dpiCaptor.capture(),
-                eq(false), eq(false), anyInt(), any(), anyInt(), any(), any(), eq(true));
+                false, 0, null,
+                DataCallResponse.PDU_SESSION_ID_NOT_SET, null, null, true, obtainMessage());
+        ArgumentCaptor<DataProfileInfo> dpiCaptor = ArgumentCaptor.forClass(DataProfileInfo.class);
+        verify(mRadioProxy).setupDataCall(
+                mSerialNumberCaptor.capture(), eq(AccessNetworkConstants.AccessNetworkType.EUTRAN),
+                dpiCaptor.capture(), eq(true), eq(false), eq(false));
         verifyRILResponse(
                 mRILUnderTest, mSerialNumberCaptor.getValue(), RIL_REQUEST_SETUP_DATA_CALL);
-        DataProfile dpi = dpiCaptor.getValue();
-        assertEquals(PROFILE_ID, dpi.getProfileId());
-        assertEquals(APN, dpi.getApn());
-        assertEquals(PROTOCOL, dpi.getProtocolType());
-        assertEquals(AUTH_TYPE, dpi.getAuthType());
-        assertEquals(USER_NAME, dpi.getUserName());
-        assertEquals(PASSWORD, dpi.getPassword());
-        assertEquals(TYPE, dpi.getType());
-        assertEquals(APN_ENABLED, dpi.isEnabled());
-        assertEquals(SUPPORTED_APN_TYPES_BITMASK, dpi.getSupportedApnTypesBitmask());
-        assertEquals(ROAMING_PROTOCOL, dpi.getRoamingProtocolType());
-        assertEquals(SUPPORTED_NETWORK_TYPES_BITMASK, dpi.getBearerBitmask());
-        assertEquals(MTU, dpi.getMtu());
+        DataProfileInfo dpi = dpiCaptor.getValue();
+        assertEquals(PROFILE_ID, dpi.profileId);
+        assertEquals(APN, dpi.apn);
+        assertEquals(PROTOCOL, ApnSetting.getProtocolIntFromString(dpi.protocol));
+        assertEquals(AUTH_TYPE, dpi.authType);
+        assertEquals(USER_NAME, dpi.user);
+        assertEquals(PASSWORD, dpi.password);
+        assertEquals(TYPE, dpi.type);
+        assertEquals(MAX_CONNS_TIME, dpi.maxConnsTime);
+        assertEquals(MAX_CONNS, dpi.maxConns);
+        assertEquals(WAIT_TIME, dpi.waitTime);
+        assertEquals(APN_ENABLED, dpi.enabled);
+        assertEquals(SUPPORTED_APN_TYPES_BITMASK, dpi.supportedApnTypesBitmap);
+        assertEquals(ROAMING_PROTOCOL, ApnSetting.getProtocolIntFromString(dpi.protocol));
+        assertEquals(
+                BEARER_BITMASK,
+                ServiceState.convertBearerBitmaskToNetworkTypeBitmask(dpi.bearerBitmap >> 1));
+        assertEquals(MTU, dpi.mtu);
     }
 
     @Test
@@ -2825,7 +2732,7 @@
         expected.add(c4);
         expected.add(c5);
 
-        ArrayList<Carrier> result = RILUtils.convertToHalCarrierRestrictionList(carriers);
+        ArrayList<Carrier> result = RIL.createCarrierRestrictionList(carriers);
 
         assertTrue(result.equals(expected));
     }
@@ -2834,7 +2741,7 @@
     public void testEnableUiccApplications() throws Exception {
         // Not supported on Radio 1.0.
         mRILUnderTest.enableUiccApplications(false, obtainMessage());
-        verify(mSimProxy, never()).enableUiccApplications(anyInt(), anyBoolean());
+        verify(mRadioProxy, never()).enableUiccApplications(anyInt(), anyBoolean());
 
         // Make radio version 1.5 to support the operation.
         try {
@@ -2842,7 +2749,7 @@
         } catch (Exception e) {
         }
         mRILUnderTest.enableUiccApplications(false, obtainMessage());
-        verify(mSimProxy).enableUiccApplications(mSerialNumberCaptor.capture(), anyBoolean());
+        verify(mRadioProxy).enableUiccApplications(mSerialNumberCaptor.capture(), anyBoolean());
         verifyRILResponse(mRILUnderTest, mSerialNumberCaptor.getValue(),
                 RIL_REQUEST_ENABLE_UICC_APPLICATIONS);
     }
@@ -2851,7 +2758,7 @@
     public void testAreUiccApplicationsEnabled() throws Exception {
         // Not supported on Radio 1.0.
         mRILUnderTest.areUiccApplicationsEnabled(obtainMessage());
-        verify(mSimProxy, never()).areUiccApplicationsEnabled(mSerialNumberCaptor.capture());
+        verify(mRadioProxy, never()).areUiccApplicationsEnabled(mSerialNumberCaptor.capture());
 
         // Make radio version 1.5 to support the operation.
         try {
@@ -2859,7 +2766,7 @@
         } catch (Exception e) {
         }
         mRILUnderTest.areUiccApplicationsEnabled(obtainMessage());
-        verify(mSimProxy).areUiccApplicationsEnabled(mSerialNumberCaptor.capture());
+        verify(mRadioProxy).areUiccApplicationsEnabled(mSerialNumberCaptor.capture());
         verifyRILResponse(mRILUnderTest, mSerialNumberCaptor.getValue(),
                 RIL_REQUEST_GET_UICC_APPLICATIONS_ENABLEMENT);
     }
@@ -2871,7 +2778,7 @@
         Message message = obtainMessage();
         mRILUnderTest.areUiccApplicationsEnabled(message);
         processAllMessages();
-        verify(mSimProxy, never()).areUiccApplicationsEnabled(mSerialNumberCaptor.capture());
+        verify(mRadioProxy, never()).areUiccApplicationsEnabled(mSerialNumberCaptor.capture());
         // Sending message is handled by getRadioProxy when proxy is null.
         // areUiccApplicationsEnabled shouldn't explicitly send another callback.
         assertEquals(null, message.obj);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RadioAccessFamilyTest.java b/tests/telephonytests/src/com/android/internal/telephony/RadioAccessFamilyTest.java
index 97d4a06..83c362b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RadioAccessFamilyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RadioAccessFamilyTest.java
@@ -28,10 +28,10 @@
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidTestingRunner.class)
-public class RadioAccessFamilyTest {
+public class RadioAccessFamilyTest extends TelephonyTest {
     @Test
     @SmallTest
-    public void testCompareSameFamily() {
+    public void testCompareSameFamily() throws Exception {
         // same family same number results in no clear winner
         assertEquals(0, RadioAccessFamily.compare(
                     TelephonyManager.NETWORK_TYPE_BITMASK_HSUPA,
@@ -47,7 +47,7 @@
 
     @Test
     @SmallTest
-    public void testComparedGreatestUnique() {
+    public void testComparedGreatestUnique() throws Exception {
         // Because LHS supports a unique higher-generation RAT, prefer that to a large list of
         // older RATs. Since RHS is greater, compare should be positive.
         assertTrue(0 < RadioAccessFamily.compare(
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RadioConfigResponseTest.java b/tests/telephonytests/src/com/android/internal/telephony/RadioConfigResponseTest.java
index 14be75f..d529d67 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RadioConfigResponseTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RadioConfigResponseTest.java
@@ -23,16 +23,28 @@
 import android.telephony.TelephonyManager;
 import android.testing.AndroidTestingRunner;
 
+import org.junit.After;
+import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.Set;
 
 @RunWith(AndroidTestingRunner.class)
-public class RadioConfigResponseTest {
+public class RadioConfigResponseTest extends TelephonyTest {
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(RadioConfigResponseTest.class.getSimpleName());
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
     @Test
     public void testVersion_1_5() {
-        Set<String> caps = RILUtils.getCaps(RIL.RADIO_HAL_VERSION_1_5, false);
+        Set<String> caps = RadioConfigResponse.getCaps(RIL.RADIO_HAL_VERSION_1_5, false);
         assertFalse(
                 caps.contains(TelephonyManager.CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE));
         assertFalse(
@@ -48,7 +60,7 @@
 
     @Test
     public void testReducedFeatureSet() {
-        Set<String> caps = RILUtils.getCaps(RIL.RADIO_HAL_VERSION_1_6, true);
+        Set<String> caps = RadioConfigResponse.getCaps(RIL.RADIO_HAL_VERSION_1_6, true);
         assertFalse(
                 caps.contains(TelephonyManager.CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE));
         assertTrue(
@@ -66,7 +78,7 @@
 
     @Test
     public void testNonReducedFeatureSet() {
-        Set<String> caps = RILUtils.getCaps(RIL.RADIO_HAL_VERSION_1_6, false);
+        Set<String> caps = RadioConfigResponse.getCaps(RIL.RADIO_HAL_VERSION_1_6, false);
         assertTrue(
                 caps.contains(TelephonyManager.CAPABILITY_SECONDARY_LINK_BANDWIDTH_VISIBLE));
         assertTrue(
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RadioInterfaceCapabilityControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/RadioInterfaceCapabilityControllerTest.java
index 00bca27..e8e1124 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RadioInterfaceCapabilityControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RadioInterfaceCapabilityControllerTest.java
@@ -19,7 +19,6 @@
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertTrue;
 
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -35,6 +34,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.HashSet;
 import java.util.Set;
@@ -42,15 +42,15 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class RadioInterfaceCapabilityControllerTest extends TelephonyTest {
-    // Mocked classes
+    @Mock
     RadioConfig mMockRadioConfig;
+
+    @Mock
     CommandsInterface mMockCommandsInterface;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mMockRadioConfig = mock(RadioConfig.class);
-        mMockCommandsInterface = mock(CommandsInterface.class);
     }
 
     @After
diff --git a/tests/telephonytests/src/com/android/internal/telephony/RatRatcheterTest.java b/tests/telephonytests/src/com/android/internal/telephony/RatRatcheterTest.java
index 6cbb1da..c378995 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/RatRatcheterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/RatRatcheterTest.java
@@ -46,8 +46,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mServiceState = null;
-        mBundle = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTest.java
index 500d69c..9057935 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTest.java
@@ -16,12 +16,9 @@
 
 package com.android.internal.telephony;
 
-import static android.telephony.ServiceState.UNKNOWN_ID;
-
 import android.os.Bundle;
 import android.os.Parcel;
 import android.telephony.AccessNetworkConstants;
-import android.telephony.CellIdentityLte;
 import android.telephony.LteVopsSupportInfo;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.ServiceState;
@@ -33,7 +30,6 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
 
 public class ServiceStateTest extends TestCase {
 
@@ -406,50 +402,4 @@
 
         assertEquals(ss.getDuplexMode(), ServiceState.DUPLEX_MODE_TDD);
     }
-
-    @SmallTest
-    public void testCreateLocationInfoSanitizedCopy() {
-        ServiceState ss = new ServiceState();
-        NetworkRegistrationInfo nri = new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .setCellIdentity(new CellIdentityLte())
-                .build();
-        ss.addNetworkRegistrationInfo(nri);
-        ss.setCdmaSystemAndNetworkId(12345, 6789);
-        ss.setOperatorName(
-                /*longName=*/ "AwesomeTelecomm", /*shortName=*/ "AT", /*numeric=*/ "123456");
-
-        ServiceState fineLocationSanitizedSs =
-                ss.createLocationInfoSanitizedCopy(/*removeCoarseLocation=*/ false);
-        // CellIdentities is fine location protected, it should be sanitized
-        assertCellIdentitiesSanitized(fineLocationSanitizedSs);
-        // All other coarse location protected fields should remain
-        assertEquals("AwesomeTelecomm", fineLocationSanitizedSs.getOperatorAlphaLong());
-        assertEquals("AT", fineLocationSanitizedSs.getOperatorAlphaShort());
-        assertEquals("123456", fineLocationSanitizedSs.getOperatorNumeric());
-        assertEquals(12345, fineLocationSanitizedSs.getCdmaSystemId());
-        assertEquals(6789, fineLocationSanitizedSs.getCdmaNetworkId());
-
-        ServiceState coarseLocationSanitizedSs =
-                ss.createLocationInfoSanitizedCopy(/*removeCoarseLocation=*/ true);
-        // CellIdentities is fine location protected, it should be sanitized
-        assertCellIdentitiesSanitized(coarseLocationSanitizedSs);
-        // All other coarse location protected fields should be sanitized as well
-        assertEquals(null, coarseLocationSanitizedSs.getOperatorAlphaLong());
-        assertEquals(null, coarseLocationSanitizedSs.getOperatorAlphaShort());
-        assertEquals(null, coarseLocationSanitizedSs.getOperatorNumeric());
-        assertEquals(UNKNOWN_ID, coarseLocationSanitizedSs.getCdmaSystemId());
-        assertEquals(UNKNOWN_ID, coarseLocationSanitizedSs.getCdmaNetworkId());
-    }
-
-    private void assertCellIdentitiesSanitized(ServiceState ss) {
-        List<NetworkRegistrationInfo> networkRegistrationInfoList =
-                ss.getNetworkRegistrationInfoList();
-        if (networkRegistrationInfoList == null) return;
-        for (NetworkRegistrationInfo nri : networkRegistrationInfoList) {
-            assertNull(nri.getCellIdentity());
-        }
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
index 7d9891d..98d5da3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ServiceStateTrackerTest.java
@@ -20,7 +20,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyLong;
@@ -30,6 +29,7 @@
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
@@ -43,7 +43,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
@@ -56,6 +55,7 @@
 import android.os.PersistableBundle;
 import android.os.Process;
 import android.os.SystemClock;
+import android.os.TimestampedValue;
 import android.os.UserHandle;
 import android.os.WorkSource;
 import android.telephony.AccessNetworkConstants;
@@ -69,7 +69,13 @@
 import android.telephony.CellIdentityWcdma;
 import android.telephony.CellInfo;
 import android.telephony.CellInfoGsm;
+import android.telephony.CellSignalStrength;
+import android.telephony.CellSignalStrengthCdma;
 import android.telephony.CellSignalStrengthGsm;
+import android.telephony.CellSignalStrengthLte;
+import android.telephony.CellSignalStrengthNr;
+import android.telephony.CellSignalStrengthTdscdma;
+import android.telephony.CellSignalStrengthWcdma;
 import android.telephony.INetworkService;
 import android.telephony.LteVopsSupportInfo;
 import android.telephony.NetworkRegistrationInfo;
@@ -77,6 +83,7 @@
 import android.telephony.NrVopsSupportInfo;
 import android.telephony.PhysicalChannelConfig;
 import android.telephony.ServiceState;
+import android.telephony.SignalStrength;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyManager;
@@ -102,6 +109,7 @@
 import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 import org.mockito.Mockito;
 
 import java.lang.reflect.Method;
@@ -111,20 +119,25 @@
 import java.util.HashSet;
 import java.util.List;
 
+
 public class ServiceStateTrackerTest extends TelephonyTest {
-    // Mocked classes
+    @Mock
     private ProxyController mProxyController;
+    @Mock
     private Handler mTestHandler;
-    private NetworkService mIwlanNetworkService;
-    private INetworkService.Stub mIwlanNetworkServiceStub;
-    private SubscriptionInfo mSubInfo;
-    private ServiceStateStats mServiceStateStats;
 
     private CellularNetworkService mCellularNetworkService;
 
-    // SST now delegates all signal strength operations to SSC
-    // Add Mock SSC as the dependency to avoid NPE
-    private SignalStrengthController mSsc;
+    @Mock
+    private NetworkService mIwlanNetworkService;
+    @Mock
+    private INetworkService.Stub mIwlanNetworkServiceStub;
+
+    @Mock
+    private SubscriptionInfo mSubInfo;
+
+    @Mock
+    private ServiceStateStats mServiceStateStats;
 
     private ServiceStateTracker sst;
     private ServiceStateTrackerTestHandler mSSTTestHandler;
@@ -175,9 +188,6 @@
 
         @Override
         public void onLooperPrepared() {
-            mSsc = new SignalStrengthController(mPhone);
-            doReturn(mSsc).when(mPhone).getSignalStrengthController();
-
             sst = new ServiceStateTracker(mPhone, mSimulatedCommands);
             sst.setServiceStateStats(mServiceStateStats);
             doReturn(sst).when(mPhone).getServiceStateTracker();
@@ -218,14 +228,9 @@
 
     @Before
     public void setUp() throws Exception {
+
         logd("ServiceStateTrackerTest +Setup!");
-        super.setUp(getClass().getSimpleName());
-        mProxyController = Mockito.mock(ProxyController.class);
-        mTestHandler = Mockito.mock(Handler.class);
-        mIwlanNetworkService = Mockito.mock(NetworkService.class);
-        mIwlanNetworkServiceStub = Mockito.mock(INetworkService.Stub.class);
-        mSubInfo = Mockito.mock(SubscriptionInfo.class);
-        mServiceStateStats = Mockito.mock(ServiceStateStats.class);
+        super.setUp("ServiceStateTrackerTest");
 
         mContextFixture.putResource(R.string.config_wwan_network_service_package,
                 "com.android.phone");
@@ -261,14 +266,16 @@
         doReturn(dds).when(mPhone).getSubId();
         doReturn(true).when(mPhone).areAllDataDisconnected();
 
-        doReturn(true).when(mPackageManager)
-                .hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CDMA);
-
         mSSTTestHandler = new ServiceStateTrackerTestHandler(getClass().getSimpleName());
         mSSTTestHandler.start();
         waitUntilReady();
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
 
+        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
+        intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, 0);
+        mContext.sendBroadcast(intent);
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+
         // Override SPN related resource
         mContextFixture.putResource(
                 com.android.internal.R.string.lockscreen_carrier_default,
@@ -280,10 +287,6 @@
                 com.android.internal.R.array.wfcSpnFormats,
                 WIFI_CALLING_FORMATTERS);
 
-        // Start with power off delay disabled.
-        mContextFixture.putIntResource(
-                com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 0);
-
         mBundle.putBoolean(
                 CarrierConfigManager.KEY_ENABLE_CARRIER_DISPLAY_NAME_RESOLVER_BOOL, true);
         mBundle.putInt(CarrierConfigManager.KEY_WFC_SPN_FORMAT_IDX_INT, 0);
@@ -333,28 +336,17 @@
                     15, /* SIGNAL_STRENGTH_GOOD */
                     30  /* SIGNAL_STRENGTH_GREAT */
                 });
-
-        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, 0);
-        mContext.sendBroadcast(intent);
-        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-
         logd("ServiceStateTrackerTest -Setup!");
     }
 
     @After
     public void tearDown() throws Exception {
-        sst.removeCallbacksAndMessages(null);
         sst = null;
         mSSTTestHandler.quit();
         mSSTTestHandler.join();
-        mSSTTestHandler = null;
         if (mCellularNetworkService != null) {
             mCellularNetworkService.onDestroy();
-            mCellularNetworkService = null;
         }
-        mSsc = null;
-        mBundle = null;
         super.tearDown();
     }
 
@@ -696,6 +688,58 @@
         verify(mPhone, times(1)).notifyServiceStateChanged(any(ServiceState.class));
     }
 
+    private void sendSignalStrength(SignalStrength ss) {
+        mSimulatedCommands.setSignalStrength(ss);
+        mSimulatedCommands.notifySignalStrength();
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+    }
+
+    @Test
+    @MediumTest
+    public void testSignalStrength() {
+        // Send in GSM Signal Strength Info and expect isGsm == true
+        SignalStrength ss = new SignalStrength(
+                new CellSignalStrengthCdma(),
+                new CellSignalStrengthGsm(-53, 0, SignalStrength.INVALID),
+                new CellSignalStrengthWcdma(),
+                new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte(),
+                new CellSignalStrengthNr());
+
+        sendSignalStrength(ss);
+        assertEquals(sst.getSignalStrength(), ss);
+        assertEquals(sst.getSignalStrength().isGsm(), true);
+
+        // Send in CDMA+LTE Signal Strength Info and expect isGsm == true
+        ss = new SignalStrength(
+                new CellSignalStrengthCdma(-90, -12,
+                        SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
+                new CellSignalStrengthGsm(),
+                new CellSignalStrengthWcdma(),
+                new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte(
+                        -110, -114, -5, 0, SignalStrength.INVALID, SignalStrength.INVALID),
+                new CellSignalStrengthNr());
+
+        sendSignalStrength(ss);
+        assertEquals(sst.getSignalStrength(), ss);
+        assertEquals(sst.getSignalStrength().isGsm(), true);
+
+        // Send in CDMA-only Signal Strength Info and expect isGsm == false
+        ss = new SignalStrength(
+                new CellSignalStrengthCdma(-90, -12,
+                        SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
+                new CellSignalStrengthGsm(),
+                new CellSignalStrengthWcdma(),
+                new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte(),
+                new CellSignalStrengthNr());
+
+        sendSignalStrength(ss);
+        assertEquals(sst.getSignalStrength(), ss);
+        assertEquals(sst.getSignalStrength().isGsm(), false);
+    }
+
     private void sendCarrierConfigUpdate() {
         CarrierConfigManager mockConfigManager = Mockito.mock(CarrierConfigManager.class);
         when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
@@ -709,6 +753,182 @@
     }
 
     @Test
+    public void testLteSignalStrengthReportingCriteria() {
+        SignalStrength ss = new SignalStrength(
+                new CellSignalStrengthCdma(),
+                new CellSignalStrengthGsm(),
+                new CellSignalStrengthWcdma(),
+                new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte(
+                        -110, /* rssi */
+                        -114, /* rsrp */
+                        -5, /* rsrq */
+                        0, /* rssnr */
+                        SignalStrength.INVALID, /* cqi */
+                        SignalStrength.INVALID /* ta */),
+                new CellSignalStrengthNr());
+
+        mBundle.putBoolean(CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL,
+                true);
+
+        sendCarrierConfigUpdate();
+
+        mSimulatedCommands.setSignalStrength(ss);
+        mSimulatedCommands.notifySignalStrength();
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+        // Default thresholds are POOR=-115 MODERATE=-105 GOOD=-95 GREAT=-85
+        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_POOR, sst.getSignalStrength().getLevel());
+
+        int[] lteThresholds = {
+                -130, // SIGNAL_STRENGTH_POOR
+                -120, // SIGNAL_STRENGTH_MODERATE
+                -110, // SIGNAL_STRENGTH_GOOD
+                -100,  // SIGNAL_STRENGTH_GREAT
+        };
+        mBundle.putIntArray(CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
+                lteThresholds);
+        sendCarrierConfigUpdate();
+
+        mSimulatedCommands.setSignalStrength(ss);
+        mSimulatedCommands.notifySignalStrength();
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+        assertEquals(sst.getSignalStrength().getLevel(),
+                CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
+    }
+
+    @Test
+    public void test5gNrSignalStrengthReportingCriteria_UseSsRsrp() {
+        SignalStrength ss = new SignalStrength(
+                new CellSignalStrengthCdma(),
+                new CellSignalStrengthGsm(),
+                new CellSignalStrengthWcdma(),
+                new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte(),
+                new CellSignalStrengthNr(
+                    -139, /** csiRsrp NONE */
+                    -20, /** csiRsrq NONE */
+                    -23, /** CsiSinr NONE */
+                    -44, /** SsRsrp SIGNAL_STRENGTH_GREAT */
+                    -20, /** SsRsrq NONE */
+                    -23) /** SsSinr NONE */
+         );
+
+        // SSRSRP = 1 << 0
+        mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
+                CellSignalStrengthNr.USE_SSRSRP);
+        sendCarrierConfigUpdate();
+        mSimulatedCommands.setSignalStrength(ss);
+        mSimulatedCommands.notifySignalStrength();
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_GREAT, sst.getSignalStrength().getLevel());
+    }
+
+    @Test
+    public void test5gNrSignalStrengthReportingCriteria_UseSsRsrpAndSsRsrq() {
+        SignalStrength ss = new SignalStrength(
+                new CellSignalStrengthCdma(),
+                new CellSignalStrengthGsm(),
+                new CellSignalStrengthWcdma(),
+                new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte(),
+                new CellSignalStrengthNr(
+                    -139, /** csiRsrp NONE */
+                    -20, /** csiRsrq NONE */
+                    -23, /** CsiSinr NONE */
+                    -44, /** SsRsrp SIGNAL_STRENGTH_GREAT */
+                    -32, /** SsRsrq NONE */
+                    -23) /** SsSinr NONE */
+        );
+
+        // SSRSRP = 1 << 0 | SSSINR = 1 << 2
+        mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
+                CellSignalStrengthNr.USE_SSRSRP | CellSignalStrengthNr.USE_SSRSRQ);
+        sendCarrierConfigUpdate();
+        mSimulatedCommands.setSignalStrength(ss);
+        mSimulatedCommands.notifySignalStrength();
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN,
+                sst.getSignalStrength().getLevel());
+    }
+
+    @Test
+    public void test5gNrSignalStrengthReportingCriteria_ConfiguredThresholds() {
+        SignalStrength ss = new SignalStrength(
+                new CellSignalStrengthCdma(),
+                new CellSignalStrengthGsm(),
+                new CellSignalStrengthWcdma(),
+                new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte(),
+                new CellSignalStrengthNr(
+                    -139, /** csiRsrp NONE */
+                    -20, /** csiRsrq NONE */
+                    -23, /** CsiSinr NONE */
+                    -44, /** SsRsrp SIGNAL_STRENGTH_GREAT */
+                    -20, /** SsRsrq NONE */
+                    -23) /** SsSinr NONE */
+        );
+
+        // SSRSRP = 1 << 0
+        mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
+                CellSignalStrengthNr.USE_SSRSRP);
+        sendCarrierConfigUpdate();
+        mSimulatedCommands.setSignalStrength(ss);
+        mSimulatedCommands.notifySignalStrength();
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_GREAT, sst.getSignalStrength().getLevel());
+
+        int[] nrSsRsrpThresholds = {
+                -45, // SIGNAL_STRENGTH_POOR
+                -40, // SIGNAL_STRENGTH_MODERATE
+                -37, // SIGNAL_STRENGTH_GOOD
+                -34,  // SIGNAL_STRENGTH_GREAT
+        };
+        mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY,
+                nrSsRsrpThresholds);
+        mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
+                CellSignalStrengthNr.USE_SSRSRP);
+        sendCarrierConfigUpdate();
+        mSimulatedCommands.setSignalStrength(ss);
+        mSimulatedCommands.notifySignalStrength();
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_POOR,
+                sst.getSignalStrength().getLevel());
+    }
+
+    @Test
+    public void testWcdmaSignalStrengthReportingCriteria() {
+        SignalStrength ss = new SignalStrength(
+                new CellSignalStrengthCdma(),
+                new CellSignalStrengthGsm(),
+                new CellSignalStrengthWcdma(-79, 0, -85, -5),
+                new CellSignalStrengthTdscdma(),
+                new CellSignalStrengthLte(),
+                new CellSignalStrengthNr());
+
+        mSimulatedCommands.setSignalStrength(ss);
+        mSimulatedCommands.notifySignalStrength();
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+        assertEquals(sst.getSignalStrength().getLevel(), CellSignalStrength.SIGNAL_STRENGTH_GOOD);
+
+        int[] wcdmaThresholds = {
+                -110, // SIGNAL_STRENGTH_POOR
+                -100, // SIGNAL_STRENGTH_MODERATE
+                -90, // SIGNAL_STRENGTH_GOOD
+                -80  // SIGNAL_STRENGTH_GREAT
+        };
+        mBundle.putIntArray(CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY,
+                wcdmaThresholds);
+        mBundle.putString(
+                CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING,
+                "rscp");
+        sendCarrierConfigUpdate();
+        mSimulatedCommands.setSignalStrength(ss);
+        mSimulatedCommands.notifySignalStrength();
+        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
+        assertEquals(sst.getSignalStrength().getLevel(), CellSignalStrength.SIGNAL_STRENGTH_GOOD);
+    }
+
+    @Test
     @MediumTest
     // TODO(nharold): we probably should remove support for this procedure (GET_LOC)
     public void testGsmCellLocation() {
@@ -1411,7 +1631,7 @@
         mContextFixture.putBooleanResource(
                 R.bool.config_user_notification_of_restrictied_mobile_access, true);
         doReturn(new ApplicationInfo()).when(mContext).getApplicationInfo();
-        Drawable mockDrawable = Mockito.mock(Drawable.class);
+        Drawable mockDrawable = mock(Drawable.class);
         Resources mockResources = mContext.getResources();
         when(mockResources.getDrawable(anyInt(), any())).thenReturn(mockDrawable);
 
@@ -1443,7 +1663,7 @@
         mContextFixture.putBooleanResource(
                 R.bool.config_user_notification_of_restrictied_mobile_access, true);
         doReturn(new ApplicationInfo()).when(mContext).getApplicationInfo();
-        Drawable mockDrawable = Mockito.mock(Drawable.class);
+        Drawable mockDrawable = mock(Drawable.class);
         Resources mockResources = mContext.getResources();
         when(mockResources.getDrawable(anyInt(), any())).thenReturn(mockDrawable);
 
@@ -1476,7 +1696,7 @@
         mContextFixture.putBooleanResource(
                 R.bool.config_user_notification_of_restrictied_mobile_access, true);
         doReturn(new ApplicationInfo()).when(mContext).getApplicationInfo();
-        Drawable mockDrawable = Mockito.mock(Drawable.class);
+        Drawable mockDrawable = mock(Drawable.class);
         Resources mockResources = mContext.getResources();
         when(mockResources.getDrawable(anyInt(), any())).thenReturn(mockDrawable);
 
@@ -1508,7 +1728,7 @@
         mContextFixture.putBooleanResource(
                 R.bool.config_user_notification_of_restrictied_mobile_access, true);
         doReturn(new ApplicationInfo()).when(mContext).getApplicationInfo();
-        Drawable mockDrawable = Mockito.mock(Drawable.class);
+        Drawable mockDrawable = mock(Drawable.class);
         Resources mockResources = mContext.getResources();
         when(mockResources.getDrawable(anyInt(), any())).thenReturn(mockDrawable);
 
@@ -1542,7 +1762,7 @@
         mContextFixture.putBooleanResource(
                 R.bool.config_user_notification_of_restrictied_mobile_access, true);
         doReturn(new ApplicationInfo()).when(mContext).getApplicationInfo();
-        Drawable mockDrawable = Mockito.mock(Drawable.class);
+        Drawable mockDrawable = mock(Drawable.class);
         Resources mockResources = mContext.getResources();
         when(mockResources.getDrawable(anyInt(), any())).thenReturn(mockDrawable);
 
@@ -1719,10 +1939,7 @@
     @Test
     @SmallTest
     public void testImsRegisteredDelayShutDown() throws Exception {
-        doReturn(false).when(mPhone).isUsingNewDataStack();
         doReturn(true).when(mPhone).isPhoneTypeGsm();
-        mContextFixture.putIntResource(
-                com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 1000 /*ms*/);
         sst.setImsRegistrationState(true);
         mSimulatedCommands.setRadioPowerFailResponse(false);
         sst.setRadioPower(true);
@@ -1742,28 +1959,8 @@
 
     @Test
     @SmallTest
-    public void testImsRegisteredNoDelayShutDown() throws Exception {
-        doReturn(true).when(mPhone).isPhoneTypeGsm();
-        // The radio power off delay time is 0, so there should should be no delay.
-        sst.setImsRegistrationState(true);
-        mSimulatedCommands.setRadioPowerFailResponse(false);
-        sst.setRadioPower(true);
-        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-
-        // Turn off the radio and ensure radio power is off
-        assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
-        sst.setRadioPower(false);
-        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-        assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
-    }
-
-    @Test
-    @SmallTest
     public void testImsRegisteredDelayShutDownTimeout() throws Exception {
-        doReturn(false).when(mPhone).isUsingNewDataStack();
         doReturn(true).when(mPhone).isPhoneTypeGsm();
-        mContextFixture.putIntResource(
-                com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 1000 /*ms*/);
         sst.setImsRegistrationState(true);
         mSimulatedCommands.setRadioPowerFailResponse(false);
         sst.setRadioPower(true);
@@ -1779,7 +1976,7 @@
         // move to off.
         // Timeout for IMS reg + some extra time to remove race conditions
         waitForDelayedHandlerAction(mSSTTestHandler.getThreadHandler(),
-                sst.getRadioPowerOffDelayTimeoutForImsRegistration() + 1000, 1000);
+                ServiceStateTracker.DELAY_RADIO_OFF_FOR_IMS_DEREG_TIMEOUT + 100, 1000);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         assertEquals(TelephonyManager.RADIO_POWER_OFF, mSimulatedCommands.getRadioState());
     }
@@ -1788,8 +1985,6 @@
     @SmallTest
     public void testImsRegisteredAPMOnOffToggle() throws Exception {
         doReturn(true).when(mPhone).isPhoneTypeGsm();
-        mContextFixture.putIntResource(
-                com.android.internal.R.integer.config_delay_for_ims_dereg_millis, 1000 /*ms*/);
         sst.setImsRegistrationState(true);
         mSimulatedCommands.setRadioPowerFailResponse(false);
         sst.setRadioPower(true);
@@ -1805,14 +2000,14 @@
         // Ensure the timeout was cancelled and we still see radio power is on.
         // Timeout for IMS reg + some extra time to remove race conditions
         waitForDelayedHandlerAction(mSSTTestHandler.getThreadHandler(),
-                sst.getRadioPowerOffDelayTimeoutForImsRegistration() + 1000, 1000);
+                ServiceStateTracker.DELAY_RADIO_OFF_FOR_IMS_DEREG_TIMEOUT + 100, 1000);
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
         assertEquals(TelephonyManager.RADIO_POWER_ON, mSimulatedCommands.getRadioState());
     }
 
     @Test
     @SmallTest
-    public void testSetTimeFromNITZStr_withoutAge() throws Exception {
+    public void testSetTimeFromNITZStr() throws Exception {
         {
             // Mock sending incorrect nitz str from RIL
             mSimulatedCommands.triggerNITZupdate("38/06/20,00:00:00+0");
@@ -1820,55 +2015,21 @@
             verify(mNitzStateMachine, times(0)).handleNitzReceived(any());
         }
         {
-            // Mock sending correct nitz str from RIL with a zero ageMs
+            // Mock sending correct nitz str from RIL
             String nitzStr = "15/06/20,00:00:00+0";
             NitzData expectedNitzData = NitzData.parse(nitzStr);
             mSimulatedCommands.triggerNITZupdate(nitzStr);
             waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
 
-            ArgumentCaptor<NitzSignal> argumentsCaptor =
-                    ArgumentCaptor.forClass(NitzSignal.class);
+            ArgumentCaptor<TimestampedValue<NitzData>> argumentsCaptor =
+                    ArgumentCaptor.forClass(TimestampedValue.class);
             verify(mNitzStateMachine, times(1))
                     .handleNitzReceived(argumentsCaptor.capture());
 
             // Confirm the argument was what we expected.
-            NitzSignal actualNitzSignal = argumentsCaptor.getValue();
-            assertEquals(expectedNitzData, actualNitzSignal.getNitzData());
-            assertTrue(actualNitzSignal.getReceiptElapsedRealtimeMillis()
-                    <= SystemClock.elapsedRealtime());
-            assertEquals(actualNitzSignal.getAgeMillis(), 0);
-        }
-    }
-
-    @Test
-    @SmallTest
-    public void testSetTimeFromNITZStr_withAge() throws Exception {
-        {
-            // Mock sending incorrect nitz str from RIL with a non-zero ageMs
-            long ageMs = 60 * 1000;
-            mSimulatedCommands.triggerNITZupdate("38/06/20,00:00:00+0", ageMs);
-            waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-            verify(mNitzStateMachine, times(0)).handleNitzReceived(any());
-        }
-        {
-            // Mock sending correct nitz str from RIL with a non-zero ageMs
-            String nitzStr = "21/08/15,00:00:00+0";
-            long ageMs = 60 * 1000;
-            NitzData expectedNitzData = NitzData.parse(nitzStr);
-            mSimulatedCommands.triggerNITZupdate(nitzStr, ageMs);
-            waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-
-            ArgumentCaptor<NitzSignal> argumentsCaptor =
-                    ArgumentCaptor.forClass(NitzSignal.class);
-            verify(mNitzStateMachine, times(1))
-                    .handleNitzReceived(argumentsCaptor.capture());
-
-            // Confirm the argument was what we expected.
-            NitzSignal actualNitzSignal = argumentsCaptor.getValue();
-            assertEquals(expectedNitzData, actualNitzSignal.getNitzData());
-            assertTrue(actualNitzSignal.getReceiptElapsedRealtimeMillis()
-                    <= SystemClock.elapsedRealtime());
-            assertEquals(actualNitzSignal.getAgeMillis(), ageMs);
+            TimestampedValue<NitzData> actualNitzSignal = argumentsCaptor.getValue();
+            assertEquals(expectedNitzData, actualNitzSignal.getValue());
+            assertTrue(actualNitzSignal.getReferenceTimeMillis() <= SystemClock.elapsedRealtime());
         }
     }
 
@@ -2054,17 +2215,14 @@
 
     }
 
-    private void sendPhyChanConfigChange(int[] bandwidths, int networkType, int pci,
-            int[][] contextIDs) {
+    private void sendPhyChanConfigChange(int[] bandwidths, int networkType, int pci) {
         ArrayList<PhysicalChannelConfig> pc = new ArrayList<>();
         int ssType = PhysicalChannelConfig.CONNECTION_PRIMARY_SERVING;
-        for (int i = 0; i < bandwidths.length; i++) {
+        for (int bw : bandwidths) {
             pc.add(new PhysicalChannelConfig.Builder()
                     .setCellConnectionStatus(ssType)
-                    .setCellBandwidthDownlinkKhz(bandwidths[i])
-                    .setContextIds(contextIDs != null ? contextIDs[i] : new int[0])
+                    .setCellBandwidthDownlinkKhz(bw)
                     .setNetworkType(networkType)
-                    .setBand(1)
                     .setPhysicalCellId(pci)
                     .build());
 
@@ -2076,10 +2234,6 @@
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
     }
 
-    private void sendPhyChanConfigChange(int[] bandwidths, int networkType, int pci) {
-        sendPhyChanConfigChange(bandwidths, networkType, pci, null);
-    }
-
     private void sendRegStateUpdateForLteCellId(CellIdentityLte cellId) {
         LteVopsSupportInfo lteVopsSupportInfo =
                 new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
@@ -2130,30 +2284,6 @@
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
     }
 
-    private void sendRegStateUpdateForLteOnOos() throws Exception {
-        LteVopsSupportInfo lteVopsSupportInfo =
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE,
-                        LteVopsSupportInfo.LTE_STATUS_NOT_AVAILABLE);
-        NetworkRegistrationInfo dataResult = new NetworkRegistrationInfo(
-                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
-                TelephonyManager.NETWORK_TYPE_UNKNOWN, 0, false, null, null, "", 1, false, false,
-                false, lteVopsSupportInfo);
-        NetworkRegistrationInfo voiceResult = new NetworkRegistrationInfo(
-                NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING,
-                TelephonyManager.NETWORK_TYPE_UNKNOWN, 0, false, null, null, "", false, 0, 0, 0);
-        sst.mPollingContext[0] = 2;
-        sst.sendMessage(sst.obtainMessage(
-                ServiceStateTracker.EVENT_POLL_STATE_PS_CELLULAR_REGISTRATION,
-                new AsyncResult(sst.mPollingContext, dataResult, null)));
-        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-        sst.sendMessage(sst.obtainMessage(
-                ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
-                new AsyncResult(sst.mPollingContext, voiceResult, null)));
-        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-    }
-
     @Test
     public void testPhyChanBandwidthUpdatedOnDataRegState() throws Exception {
         // Cell ID change should trigger hasLocationChanged.
@@ -2204,14 +2334,6 @@
     }
 
     @Test
-    public void testUpdateNrFrequencyRangeFromPhysicalChannelConfigs() {
-        when(mPhone.getDataNetworkController().isInternetNetwork(eq(3))).thenReturn(true);
-        sendPhyChanConfigChange(new int[] {1000, 500}, TelephonyManager.NETWORK_TYPE_NR, 1,
-                new int[][]{{0, 1}, {2, 3}});
-        assertEquals(ServiceState.FREQUENCY_RANGE_MID, sst.mSS.getNrFrequencyRange());
-    }
-
-    @Test
     public void testPhyChanBandwidthResetsOnOos() throws Exception {
         testPhyChanBandwidthRatchetedOnPhyChanBandwidth();
         LteVopsSupportInfo lteVopsSupportInfo =
@@ -2235,7 +2357,7 @@
                 ServiceStateTracker.EVENT_POLL_STATE_CS_CELLULAR_REGISTRATION,
                 new AsyncResult(sst.mPollingContext, voiceResult, null)));
         waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-        assertEquals(0, sst.mSS.getCellBandwidths().length);
+        assertTrue(Arrays.equals(new int[0], sst.mSS.getCellBandwidths()));
     }
 
     @Test
@@ -2257,7 +2379,7 @@
     @SmallTest
     @Test
     public void testRilDataTechnologyChangeTransportPreference() {
-        when(mAccessNetworksManager.isAnyApnOnIwlan()).thenReturn(false);
+        when(mTransportManager.isAnyApnPreferredOnIwlan()).thenReturn(false);
 
         // Start state: Cell data only LTE + IWLAN
         CellIdentityLte cellIdentity =
@@ -2276,7 +2398,7 @@
                 mTestHandler, EVENT_DATA_RAT_CHANGED, null);
         // transport preference change for a PDN for IWLAN occurred, no registration change, but
         // trigger unrelated poll to pick up transport preference.
-        when(mAccessNetworksManager.isAnyApnOnIwlan()).thenReturn(true);
+        when(mTransportManager.isAnyApnPreferredOnIwlan()).thenReturn(true);
         changeRegStateWithIwlan(
                 // WWAN
                 NetworkRegistrationInfo.REGISTRATION_STATE_HOME, cellIdentity,
@@ -2364,7 +2486,6 @@
         doReturn(true).when(mPhone).isPhoneTypeCdmaLte();
         doReturn(CdmaSubscriptionSourceManager.SUBSCRIPTION_FROM_RUIM).when(mCdmaSSM)
                 .getCdmaSubscriptionSource();
-        doReturn(PHONE_ID).when(mPhone).getPhoneId();
 
         logd("Calling updatePhoneType");
         // switch to CDMA
@@ -2543,28 +2664,6 @@
     }
 
     @Test
-    public void testLastKnownCellIdentity() throws Exception {
-        CellIdentityLte cellIdentity =
-                new CellIdentityLte(1, 1, 5, 1, new int[] {1, 2}, 5000, "001", "01", "test",
-                        "tst", Collections.emptyList(), null);
-
-        sendPhyChanConfigChange(new int[] {10000}, TelephonyManager.NETWORK_TYPE_LTE, 1);
-        sendRegStateUpdateForLteCellId(cellIdentity);
-        assertEquals(ServiceState.STATE_IN_SERVICE, sst.mSS.getState());
-        assertEquals(cellIdentity, sst.getLastKnownCellIdentity());
-        assertFalse(sst.hasMessages(sst.EVENT_RESET_LAST_KNOWN_CELL_IDENTITY));
-
-        sendRegStateUpdateForLteOnOos();
-        assertEquals(ServiceState.STATE_OUT_OF_SERVICE, sst.mSS.getState());
-        assertEquals(cellIdentity, sst.getLastKnownCellIdentity());
-        assertTrue(sst.hasMessages(sst.EVENT_RESET_LAST_KNOWN_CELL_IDENTITY));
-
-        sst.obtainMessage(sst.EVENT_RESET_LAST_KNOWN_CELL_IDENTITY, null).sendToTarget();
-        waitForLastHandlerAction(mSSTTestHandler.getThreadHandler());
-        assertNull(sst.getLastKnownCellIdentity());
-    }
-
-    @Test
     public void testUpdateSpnDisplay_noService_displayEmergencyCallOnly() {
         // GSM phone
         doReturn(true).when(mPhone).isPhoneTypeGsm();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java
deleted file mode 100644
index 583c22b..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthControllerTest.java
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony;
-
-import static android.telephony.SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI;
-import static android.telephony.SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_SSSINR;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.Context;
-import android.content.Intent;
-import android.os.Handler;
-import android.os.Message;
-import android.os.PersistableBundle;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.CarrierConfigManager;
-import android.telephony.CellSignalStrength;
-import android.telephony.CellSignalStrengthCdma;
-import android.telephony.CellSignalStrengthGsm;
-import android.telephony.CellSignalStrengthLte;
-import android.telephony.CellSignalStrengthNr;
-import android.telephony.CellSignalStrengthTdscdma;
-import android.telephony.CellSignalStrengthWcdma;
-import android.telephony.SignalStrength;
-import android.telephony.SignalStrengthUpdateRequest;
-import android.telephony.SignalThresholdInfo;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Unit test for {@link SignalStrengthUpdateRequest}.
- */
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class SignalStrengthControllerTest extends TelephonyTest {
-
-    private static final String TAG = "SignalStrengthControllerTest";
-
-    private static final int ACTIVE_SUB_ID = 0;
-    private static final int INVALID_SUB_ID = 1000;
-    private static final int CALLING_UID = 12345;
-    private static final int PHONE_ID = 0;
-    private static final String HOME_PLMN = "310260";
-    private static final String PLMN1 = "480123";
-    private static final String PLMN2 = "586111";
-    private static final String HOME_PNN = "home pnn";
-    private static final String[] CARRIER_CONFIG_SPDI = new String[] {HOME_PLMN, PLMN2};
-    private static final String[] CARRIER_CONFIG_EHPLMN = new String[] {HOME_PLMN, PLMN1};
-    private static final String[] CARRIER_CONFIG_PNN = new String[] {
-            String.format("%s,%s", HOME_PNN, "short"), "f2,s2"
-    };
-
-    // Mocked classes
-    private Handler mHandler;
-
-    private SignalStrengthController mSsc;
-    private PersistableBundle mBundle;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp(this.getClass().getSimpleName());
-        mHandler = Mockito.mock(Handler.class);
-        when(mPhone.getSubId()).thenReturn(ACTIVE_SUB_ID);
-        mSsc = new SignalStrengthController(mPhone);
-        replaceInstance(Handler.class, "mLooper", mHandler, mSsc.getLooper());
-        replaceInstance(Phone.class, "mLooper", mPhone, mSsc.getLooper());
-
-        mBundle = mContextFixture.getCarrierConfigBundle();
-        mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY,
-                new int[] {
-                        -110, /* SIGNAL_STRENGTH_POOR */
-                        -90, /* SIGNAL_STRENGTH_MODERATE */
-                        -80, /* SIGNAL_STRENGTH_GOOD */
-                        -65,  /* SIGNAL_STRENGTH_GREAT */
-                });
-        mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY,
-                new int[] {
-                        -31, /* SIGNAL_STRENGTH_POOR */
-                        -19, /* SIGNAL_STRENGTH_MODERATE */
-                        -7, /* SIGNAL_STRENGTH_GOOD */
-                        6  /* SIGNAL_STRENGTH_GREAT */
-                });
-        mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY,
-                new int[] {
-                        -5, /* SIGNAL_STRENGTH_POOR */
-                        5, /* SIGNAL_STRENGTH_MODERATE */
-                        15, /* SIGNAL_STRENGTH_GOOD */
-                        30  /* SIGNAL_STRENGTH_GREAT */
-                });
-        processAllMessages();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mSsc = null;
-        mBundle = null;
-        super.tearDown();
-    }
-
-    /**
-     * Verify that SignalStrengthUpdateRequest with invalid subId should trigger
-     * setAlwaysReportSignalStrength with false.
-     */
-    @Test
-    public void updateAlwaysReportSignalStrength_requestWithInvalidSubId_shouldBeFalse() {
-        SignalStrengthUpdateRequest request = createTestSignalStrengthUpdateRequest(
-                createTestSignalThresholdInfo(),
-                true /* shouldReportWhileIdle*/,
-                true /* shouldReportSystemWhileIdle */
-        );
-
-        mSsc.setSignalStrengthUpdateRequest(INVALID_SUB_ID, CALLING_UID,
-                request, Message.obtain(mHandler));
-        processAllMessages();
-
-        verify(mPhone).setAlwaysReportSignalStrength(eq(false));
-    }
-
-    /**
-     * Verify that with a valid subId, SignalStrengthUpdateRequest asking to report signal while
-     * idle should trigger setAlwaysReportSignalStrength with true.
-     */
-    @Test
-    public void updateAlwaysReportSignalStrength_requestReportWhileIdle_shouldBeTrue() {
-        SignalStrengthUpdateRequest request = createTestSignalStrengthUpdateRequest(
-                createTestSignalThresholdInfo(),
-                true /* shouldReportWhileIdle*/,
-                false /* shouldReportSystemWhileIdle */
-        );
-
-        mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
-                request, Message.obtain(mHandler));
-        processAllMessages();
-
-        verify(mPhone).setAlwaysReportSignalStrength(eq(true));
-    }
-
-    /**
-     * Verify that with a valid subId, SignalStrengthUpdateRequest asking to report system signal
-     * while idle should trigger setAlwaysReportSignalStrength with true.
-     */
-    @Test
-    public void updateAlwaysReportSignalStrength_requestReportSystemWhileIdle_shouldBeTrue() {
-        SignalStrengthUpdateRequest request = createTestSignalStrengthUpdateRequest(
-                createTestSignalThresholdInfo(),
-                false /* shouldReportWhileIdle*/,
-                true /* shouldReportSystemWhileIdle */
-        );
-
-        mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
-                request, Message.obtain(mHandler));
-        processAllMessages();
-
-        verify(mPhone).setAlwaysReportSignalStrength(eq(true));
-    }
-
-    /**
-     * Verify that when device is high powered, shouldHonorSystemThresholds should return true.
-     */
-    @Test
-    public void shouldHonorSystemThresholds_deviceIsHighPowered_returnTrue() {
-        when(mPhone.isDeviceIdle()).thenReturn(false);
-
-        assertThat(mSsc.shouldHonorSystemThresholds()).isTrue();
-    }
-
-    /**
-     * Verify that when device is idle and no SignalUpdateRequest received before,
-     * shouldHonorSystemThresholds should return false.
-     */
-    @Test
-    public void shouldHonorSystemThresholds_deviceIdle_noSignalRequest_returnTrue() {
-        when(mPhone.isDeviceIdle()).thenReturn(true);
-
-        assertThat(mSsc.shouldHonorSystemThresholds()).isFalse();
-    }
-
-    /**
-     * Verify that when device is idle and with SignalUpdateRequest to report system threshold
-     * received before, shouldHonorSystemThresholds should return false.
-     */
-    @Test
-    public void shouldHonorSystemThresholds_deviceIdle_systemSignalRequest_returnTrue() {
-        when(mPhone.isDeviceIdle()).thenReturn(true);
-
-        SignalStrengthUpdateRequest request = createTestSignalStrengthUpdateRequest(
-                createTestSignalThresholdInfo(),
-                false /* shouldReportWhileIdle*/,
-                true /* shouldReportSystemWhileIdle */
-        );
-        mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
-                request, Message.obtain(mHandler));
-        processAllMessages();
-
-        assertThat(mSsc.shouldHonorSystemThresholds()).isTrue();
-    }
-
-    /**
-     * Verify that when no SignalUpdateRequest received, shouldEnableSignalThresholdForAppRequest
-     * should return false.
-     */
-    @Test
-    public void shouldEnableSignalThresholdForAppRequest_noRequest_returnFalse() {
-        assertThat(mSsc.shouldEnableSignalThresholdForAppRequest(
-                AccessNetworkConstants.AccessNetworkType.GERAN,
-                SIGNAL_MEASUREMENT_TYPE_RSSI,
-                ACTIVE_SUB_ID,
-                false /* isDeviceIdle */
-        )).isFalse();
-    }
-
-    /**
-     * Verify that in high power mode, the shouldEnableSignalThresholdForAppRequest should return
-     * true if the queried ran/measurement/subId parameters match exist SignalUpdateRecord.
-     */
-    @Test
-    public void shouldEnableSignalThresholdForAppRequest_highPowered_matchedRequest_returnTrue() {
-        SignalStrengthUpdateRequest request = createTestSignalStrengthUpdateRequest(
-                createTestSignalThresholdInfo(),
-                false /* shouldReportWhileIdle*/,
-                false /* shouldReportSystemWhileIdle */
-        );
-        mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
-                request, Message.obtain(mHandler));
-        processAllMessages();
-
-        assertThat(mSsc.shouldEnableSignalThresholdForAppRequest(
-                AccessNetworkConstants.AccessNetworkType.GERAN,
-                SIGNAL_MEASUREMENT_TYPE_RSSI,
-                ACTIVE_SUB_ID,
-                false /* isDeviceIdle */
-        )).isTrue();
-    }
-
-    /**
-     * Verify that in idle mode, the shouldEnableSignalThresholdForAppRequest should return
-     * false if the queried ran/measurement/subId parameters match exist SignalUpdateRequest which
-     * did not ask to report signal while idle.
-     */
-    @Test
-    public void enableSignalThresholdForAppRequest_idle_noReportInIdle_returnTrue() {
-        SignalStrengthUpdateRequest request = createTestSignalStrengthUpdateRequest(
-                createTestSignalThresholdInfo(),
-                false /* shouldReportWhileIdle*/,
-                false /* shouldReportSystemWhileIdle */
-        );
-        mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
-                request, Message.obtain(mHandler));
-        processAllMessages();
-
-        assertThat(mSsc.shouldEnableSignalThresholdForAppRequest(
-                AccessNetworkConstants.AccessNetworkType.GERAN,
-                SIGNAL_MEASUREMENT_TYPE_RSSI,
-                ACTIVE_SUB_ID,
-                true /* isDeviceIdle */
-        )).isFalse();
-    }
-
-    /**
-     * Verify that in idle mode, the shouldEnableSignalThresholdForAppRequest should return
-     * true if the queried ran/measurement/subId parameters match exist SignalUpdateRecord which
-     * request to report signal while idle.
-     */
-    @Test
-    public void shouldEnableSignalThresholdForAppRequest_idle_reportInIdle_returnTrue() {
-        SignalStrengthUpdateRequest request = createTestSignalStrengthUpdateRequest(
-                createTestSignalThresholdInfo(),
-                true /* shouldReportWhileIdle*/,
-                false /* shouldReportSystemWhileIdle */
-        );
-        mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
-                request, Message.obtain(mHandler));
-        processAllMessages();
-
-        assertThat(mSsc.shouldEnableSignalThresholdForAppRequest(
-                AccessNetworkConstants.AccessNetworkType.GERAN,
-                SIGNAL_MEASUREMENT_TYPE_RSSI,
-                ACTIVE_SUB_ID,
-                true /* isDeviceIdle */
-        )).isTrue();
-    }
-
-    /**
-     * Verify that in idle mode, the shouldEnableSignalThresholdForAppRequest should return
-     * true if the queried ran/measurement/subId parameters match exist SignalUpdateRecord which
-     * request to report system signal while idle.
-     */
-    @Test
-    public void shouldEnableSignalThresholdForAppRequest_idle_reportSystemInIdle_returnTrue() {
-        SignalStrengthUpdateRequest request = createTestSignalStrengthUpdateRequest(
-                createTestSignalThresholdInfo(),
-                false /* shouldReportWhileIdle*/,
-                true /* shouldReportSystemWhileIdle */
-        );
-        mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
-                request, Message.obtain(mHandler));
-        processAllMessages();
-
-        assertThat(mSsc.shouldEnableSignalThresholdForAppRequest(
-                AccessNetworkConstants.AccessNetworkType.GERAN,
-                SIGNAL_MEASUREMENT_TYPE_RSSI,
-                ACTIVE_SUB_ID,
-                true /* isDeviceIdle */
-        )).isTrue();
-    }
-
-    @Test
-    public void getConsolidatedSignalThresholds_consolidateAppsThresholdsWithSystem() {
-        when(mPhone.isDeviceIdle()).thenReturn(false);
-
-        final int ran = AccessNetworkConstants.AccessNetworkType.NGRAN;
-        final int measurement = SIGNAL_MEASUREMENT_TYPE_SSSINR;
-        final int[] systemThresholds = new int[]{0, 10, 20, 30};
-        final int hysteresis = 2;
-
-        // Map key is the candidate thresholds from application, map value is the expected
-        // consolidated thresholds with systemThresholds.
-        Map<int[], int[]> cases = Map.of(
-                new int[]{-3, -6}, new int[]{-6, -3, 0, 10, 20, 30},
-                new int[]{34, 39}, new int[]{0, 10, 20, 30, 34, 39},
-                new int[]{-5, 4, 13, 23, 33}, new int[]{-5, 0, 4, 10, 13, 20, 23, 30, 33},
-                new int[]{9, 10, 11, 12}, new int[]{0, 10, 20, 30},
-                new int[]{1, 3, 5, 7, 8}, new int[]{0, 3, 7, 10, 20, 30},
-                new int[]{17, 12, 16, 14, 17}, new int[]{0, 10, 14, 17, 20, 30}
-        );
-
-        for (int[] candidate : cases.keySet()) {
-            int[] target = cases.get(candidate);
-
-            SignalThresholdInfo info = new SignalThresholdInfo.Builder()
-                    .setRadioAccessNetworkType(ran)
-                    .setSignalMeasurementType(measurement)
-                    .setThresholds(candidate, true /* isSystem */)
-                    .build();
-            SignalStrengthUpdateRequest request = createTestSignalStrengthUpdateRequest(
-                    info,
-                    false /* shouldReportWhileIdle*/,
-                    false /* shouldReportSystemWhileIdle */
-            );
-            mSsc.setSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
-                    request, Message.obtain(mHandler));
-            processAllMessages();
-
-            assertThat(mSsc.getConsolidatedSignalThresholds(
-                    ran, measurement, systemThresholds, hysteresis
-            )).isEqualTo(target);
-
-            // Each pair in the Map is tested separately (instead of cumulatively).
-            // Remove the request once it is done.
-            mSsc.clearSignalStrengthUpdateRequest(ACTIVE_SUB_ID, CALLING_UID,
-                    request, Message.obtain(mHandler));
-            processAllMessages();
-        }
-    }
-
-    @Test
-    @MediumTest
-    public void testSignalStrength() {
-        // Send in GSM Signal Strength Info and expect isGsm == true
-        SignalStrength ss = new SignalStrength(
-                new CellSignalStrengthCdma(),
-                new CellSignalStrengthGsm(-53, 0, SignalStrength.INVALID),
-                new CellSignalStrengthWcdma(),
-                new CellSignalStrengthTdscdma(),
-                new CellSignalStrengthLte(),
-                new CellSignalStrengthNr());
-
-        sendSignalStrength(ss);
-        assertEquals(mSsc.getSignalStrength(), ss);
-        assertEquals(mSsc.getSignalStrength().isGsm(), true);
-
-        // Send in CDMA+LTE Signal Strength Info and expect isGsm == true
-        ss = new SignalStrength(
-                new CellSignalStrengthCdma(-90, -12,
-                        SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
-                new CellSignalStrengthGsm(),
-                new CellSignalStrengthWcdma(),
-                new CellSignalStrengthTdscdma(),
-                new CellSignalStrengthLte(
-                        -110, -114, -5, 0, SignalStrength.INVALID, SignalStrength.INVALID),
-                new CellSignalStrengthNr());
-
-        sendSignalStrength(ss);
-        assertEquals(mSsc.getSignalStrength(), ss);
-        assertEquals(mSsc.getSignalStrength().isGsm(), true);
-
-        // Send in CDMA-only Signal Strength Info and expect isGsm == false
-        ss = new SignalStrength(
-                new CellSignalStrengthCdma(-90, -12,
-                        SignalStrength.INVALID, SignalStrength.INVALID, SignalStrength.INVALID),
-                new CellSignalStrengthGsm(),
-                new CellSignalStrengthWcdma(),
-                new CellSignalStrengthTdscdma(),
-                new CellSignalStrengthLte(),
-                new CellSignalStrengthNr());
-
-        sendSignalStrength(ss);
-        assertEquals(mSsc.getSignalStrength(), ss);
-        assertEquals(mSsc.getSignalStrength().isGsm(), false);
-    }
-
-    @Test
-    public void testLteSignalStrengthReportingCriteria() {
-        SignalStrength ss = new SignalStrength(
-                new CellSignalStrengthCdma(),
-                new CellSignalStrengthGsm(),
-                new CellSignalStrengthWcdma(),
-                new CellSignalStrengthTdscdma(),
-                new CellSignalStrengthLte(
-                        -110, /* rssi */
-                        -114, /* rsrp */
-                        -5, /* rsrq */
-                        0, /* rssnr */
-                        SignalStrength.INVALID, /* cqi */
-                        SignalStrength.INVALID /* ta */),
-                new CellSignalStrengthNr());
-
-        mBundle.putBoolean(CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL,
-                true);
-
-        sendCarrierConfigUpdate();
-
-        mSimulatedCommands.setSignalStrength(ss);
-        mSimulatedCommands.notifySignalStrength();
-        processAllMessages();
-        // Default thresholds are POOR=-115 MODERATE=-105 GOOD=-95 GREAT=-85
-        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_POOR, mSsc.getSignalStrength().getLevel());
-
-        int[] lteThresholds = {
-                -130, // SIGNAL_STRENGTH_POOR
-                -120, // SIGNAL_STRENGTH_MODERATE
-                -110, // SIGNAL_STRENGTH_GOOD
-                -100,  // SIGNAL_STRENGTH_GREAT
-        };
-        mBundle.putIntArray(CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
-                lteThresholds);
-        sendCarrierConfigUpdate();
-
-        mSimulatedCommands.setSignalStrength(ss);
-        mSimulatedCommands.notifySignalStrength();
-        processAllMessages();
-        assertEquals(mSsc.getSignalStrength().getLevel(),
-                CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
-    }
-
-    @Test
-    public void testLteSignalStrengthReportingCriteria_convertRssnrUnitFromTenDbToDB() {
-        SignalStrength ss = new SignalStrength(
-                new CellSignalStrengthCdma(),
-                new CellSignalStrengthGsm(),
-                new CellSignalStrengthWcdma(),
-                new CellSignalStrengthTdscdma(),
-                new CellSignalStrengthLte(
-                        -110, /* rssi */
-                        -114, /* rsrp */
-                        -5, /* rsrq */
-                        CellSignalStrengthLte.convertRssnrUnitFromTenDbToDB(-34), /* rssnr */
-                        SignalStrength.INVALID, /* cqi */
-                        SignalStrength.INVALID /* ta */),
-                new CellSignalStrengthNr());
-
-        int[] lteThresholds = {
-                -3, // SIGNAL_STRENGTH_POOR
-                1, // SIGNAL_STRENGTH_MODERATE
-                5, // SIGNAL_STRENGTH_GOOD
-                13,  // SIGNAL_STRENGTH_GREAT
-        };
-        mBundle.putIntArray(CarrierConfigManager.KEY_LTE_RSSNR_THRESHOLDS_INT_ARRAY ,
-                lteThresholds);
-        mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USED_FOR_LTE_SIGNAL_BAR_INT,
-                CellSignalStrengthLte.USE_RSSNR);
-        sendCarrierConfigUpdate();
-        sendSignalStrength(ss);
-        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN,
-                mSsc.getSignalStrength().getLevel());
-
-        ss = new SignalStrength(
-                new CellSignalStrengthCdma(),
-                new CellSignalStrengthGsm(),
-                new CellSignalStrengthWcdma(),
-                new CellSignalStrengthTdscdma(),
-                new CellSignalStrengthLte(
-                        -110, /* rssi */
-                        -114, /* rsrp */
-                        -5, /* rsrq */
-                        CellSignalStrengthLte.convertRssnrUnitFromTenDbToDB(129), /* rssnr */
-                        SignalStrength.INVALID, /* cqi */
-                        SignalStrength.INVALID /* ta */),
-                new CellSignalStrengthNr());
-        sendSignalStrength(ss);
-        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_GOOD, mSsc.getSignalStrength().getLevel());
-    }
-
-    @Test
-    public void test5gNrSignalStrengthReportingCriteria_UseSsRsrp() {
-        SignalStrength ss = new SignalStrength(
-                new CellSignalStrengthCdma(),
-                new CellSignalStrengthGsm(),
-                new CellSignalStrengthWcdma(),
-                new CellSignalStrengthTdscdma(),
-                new CellSignalStrengthLte(),
-                new CellSignalStrengthNr(
-                        -139, /** csiRsrp NONE */
-                        -20, /** csiRsrq NONE */
-                        -23, /** CsiSinr NONE */
-                        -44, /** SsRsrp SIGNAL_STRENGTH_GREAT */
-                        -20, /** SsRsrq NONE */
-                        -23) /** SsSinr NONE */
-        );
-
-        // SSRSRP = 1 << 0
-        mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
-                CellSignalStrengthNr.USE_SSRSRP);
-        sendCarrierConfigUpdate();
-        mSimulatedCommands.setSignalStrength(ss);
-        mSimulatedCommands.notifySignalStrength();
-        processAllMessages();
-        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_GREAT, mSsc.getSignalStrength().getLevel());
-    }
-
-    @Test
-    public void test5gNrSignalStrengthReportingCriteria_UseSsRsrpAndSsRsrq() {
-        SignalStrength ss = new SignalStrength(
-                new CellSignalStrengthCdma(),
-                new CellSignalStrengthGsm(),
-                new CellSignalStrengthWcdma(),
-                new CellSignalStrengthTdscdma(),
-                new CellSignalStrengthLte(),
-                new CellSignalStrengthNr(
-                        -139, /** csiRsrp NONE */
-                        -20, /** csiRsrq NONE */
-                        -23, /** CsiSinr NONE */
-                        -44, /** SsRsrp SIGNAL_STRENGTH_GREAT */
-                        -32, /** SsRsrq NONE */
-                        -23) /** SsSinr NONE */
-        );
-
-        // SSRSRP = 1 << 0 | SSSINR = 1 << 2
-        mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
-                CellSignalStrengthNr.USE_SSRSRP | CellSignalStrengthNr.USE_SSRSRQ);
-        sendCarrierConfigUpdate();
-        mSimulatedCommands.setSignalStrength(ss);
-        mSimulatedCommands.notifySignalStrength();
-        processAllMessages();
-        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN,
-                mSsc.getSignalStrength().getLevel());
-    }
-
-    @Test
-    public void test5gNrSignalStrengthReportingCriteria_ConfiguredThresholds() {
-        SignalStrength ss = new SignalStrength(
-                new CellSignalStrengthCdma(),
-                new CellSignalStrengthGsm(),
-                new CellSignalStrengthWcdma(),
-                new CellSignalStrengthTdscdma(),
-                new CellSignalStrengthLte(),
-                new CellSignalStrengthNr(
-                        -139, /** csiRsrp NONE */
-                        -20, /** csiRsrq NONE */
-                        -23, /** CsiSinr NONE */
-                        -64, /** SsRsrp SIGNAL_STRENGTH_GREAT */
-                        -20, /** SsRsrq NONE */
-                        -23) /** SsSinr NONE */
-        );
-
-        // SSRSRP = 1 << 0
-        mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
-                CellSignalStrengthNr.USE_SSRSRP);
-        sendCarrierConfigUpdate();
-        mSimulatedCommands.setSignalStrength(ss);
-        mSimulatedCommands.notifySignalStrength();
-        processAllMessages();
-        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_GREAT, mSsc.getSignalStrength().getLevel());
-
-        int[] nrSsRsrpThresholds = {
-                -110, /* SIGNAL_STRENGTH_POOR */
-                -60, /* SIGNAL_STRENGTH_MODERATE */
-                -55, /* SIGNAL_STRENGTH_GOOD */
-                -45,  /* SIGNAL_STRENGTH_GREAT */
-        };
-        mBundle.putIntArray(CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY,
-                nrSsRsrpThresholds);
-        mBundle.putInt(CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT,
-                CellSignalStrengthNr.USE_SSRSRP);
-        sendCarrierConfigUpdate();
-        mSimulatedCommands.setSignalStrength(ss);
-        mSimulatedCommands.notifySignalStrength();
-        processAllMessages();
-        assertEquals(CellSignalStrength.SIGNAL_STRENGTH_POOR,
-                mSsc.getSignalStrength().getLevel());
-    }
-
-    @Test
-    public void testWcdmaSignalStrengthReportingCriteria() {
-        SignalStrength ss = new SignalStrength(
-                new CellSignalStrengthCdma(),
-                new CellSignalStrengthGsm(),
-                new CellSignalStrengthWcdma(-79, 0, -85, -5),
-                new CellSignalStrengthTdscdma(),
-                new CellSignalStrengthLte(),
-                new CellSignalStrengthNr());
-
-        mSimulatedCommands.setSignalStrength(ss);
-        mSimulatedCommands.notifySignalStrength();
-        processAllMessages();
-        assertEquals(mSsc.getSignalStrength().getLevel(), CellSignalStrength.SIGNAL_STRENGTH_GOOD);
-
-        int[] wcdmaThresholds = {
-                -110, // SIGNAL_STRENGTH_POOR
-                -100, // SIGNAL_STRENGTH_MODERATE
-                -90, // SIGNAL_STRENGTH_GOOD
-                -80  // SIGNAL_STRENGTH_GREAT
-        };
-        mBundle.putIntArray(CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY,
-                wcdmaThresholds);
-        mBundle.putString(
-                CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING,
-                "rscp");
-        sendCarrierConfigUpdate();
-        mSimulatedCommands.setSignalStrength(ss);
-        mSimulatedCommands.notifySignalStrength();
-        processAllMessages();
-        assertEquals(mSsc.getSignalStrength().getLevel(), CellSignalStrength.SIGNAL_STRENGTH_GOOD);
-    }
-
-    private void sendCarrierConfigUpdate() {
-        CarrierConfigManager mockConfigManager = Mockito.mock(CarrierConfigManager.class);
-        when(mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE))
-                .thenReturn(mockConfigManager);
-        when(mockConfigManager.getConfigForSubId(anyInt())).thenReturn(mBundle);
-
-        Intent intent = new Intent().setAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, PHONE_ID);
-        mContext.sendBroadcast(intent);
-        processAllMessages();
-    }
-
-    private void sendSignalStrength(SignalStrength ss) {
-        mSimulatedCommands.setSignalStrength(ss);
-        mSimulatedCommands.notifySignalStrength();
-        processAllMessages();
-    }
-
-    private SignalThresholdInfo createTestSignalThresholdInfo() {
-        SignalThresholdInfo info = new SignalThresholdInfo.Builder()
-                .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
-                .setSignalMeasurementType(SIGNAL_MEASUREMENT_TYPE_RSSI)
-                .setThresholds(new int[]{-100, -90})
-                .build();
-        return info;
-    }
-
-    private SignalStrengthUpdateRequest createTestSignalStrengthUpdateRequest(
-            SignalThresholdInfo info, boolean shouldReportWhileIdle,
-            boolean shouldReportSystemWhileIdle) {
-        List<SignalThresholdInfo> infoList = new ArrayList<>();
-        infoList.add(info);
-
-        SignalStrengthUpdateRequest.Builder builder = new SignalStrengthUpdateRequest.Builder()
-                .setSignalThresholdInfos(infoList);
-        if (shouldReportWhileIdle) {
-            builder.setReportingRequestedWhileIdle(true);
-        }
-        if (shouldReportSystemWhileIdle) {
-            builder.setSystemThresholdReportingRequestedWhileIdle(true);
-        }
-        return builder.build();
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthUpdateRequestTest.java b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthUpdateRequestTest.java
index 9e07e0e..9c29eda 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthUpdateRequestTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SignalStrengthUpdateRequestTest.java
@@ -18,8 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.junit.Assert.assertThrows;
-
 import android.os.Parcel;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.SignalStrengthUpdateRequest;
@@ -32,64 +30,40 @@
 import org.junit.Test;
 
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 
 public class SignalStrengthUpdateRequestTest extends TestCase {
 
-    private final SignalThresholdInfo mRssiInfoOnGERAN = new SignalThresholdInfo.Builder()
+    private SignalThresholdInfo mRssiInfo = new SignalThresholdInfo.Builder()
             .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
             .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
             .setThresholds(new int[]{-109, -103, -97, -89})
             .build();
 
-    private final SignalThresholdInfo mRssiInfoOnGERAN2 = new SignalThresholdInfo.Builder()
-            .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.GERAN)
-            .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
-            .setThresholds(new int[]{-108, -102, -96, -88})
-            .build();
-
-    private final SignalThresholdInfo mRssiInfoOnCDMA2000 = new SignalThresholdInfo.Builder()
-            .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.CDMA2000)
-            .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSSI)
-            .setThresholds(new int[]{-109, -103, -97, -89})
-            .build();
-
-    private final SignalThresholdInfo mRscpInfoOnUTRAN = new SignalThresholdInfo.Builder()
+    private SignalThresholdInfo mRscpInfo = new SignalThresholdInfo.Builder()
             .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.UTRAN)
             .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSCP)
             .setThresholds(new int[]{-115, -105, -95, -85})
             .build();
 
-    private final SignalThresholdInfo mRsrpInfoOnEUTRAN = new SignalThresholdInfo.Builder()
-            .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
-            .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRP)
-            .setThresholds(new int[]{-115, -105, -95, -85})
-            .build();
-
-    private final SignalThresholdInfo mRsrqInfoEUTRAN = new SignalThresholdInfo.Builder()
-            .setRadioAccessNetworkType(AccessNetworkConstants.AccessNetworkType.EUTRAN)
-            .setSignalMeasurementType(SignalThresholdInfo.SIGNAL_MEASUREMENT_TYPE_RSRQ)
-            .setThresholds(new int[]{-30, -20, -10, -1})
-            .build();
-
     @Test
     @SmallTest
     public void testPublicConstructorWithInvalidParam() {
         // null Collection
         validateBuilderWithInvalidParam(null);
 
-        // duplication of SignalMeasurementType for the same RAN in Collection
-        validateBuilderWithInvalidParam(List.of(mRssiInfoOnGERAN, mRssiInfoOnGERAN2));
+        // duplication of SignalMeasurementType in Collection
+        validateBuilderWithInvalidParam(List.of(mRssiInfo, mRssiInfo));
 
+        // The following two cases can not turn on until the implement is ready:
         // empty Collections
-        validateBuilderWithInvalidParam(List.of());
+        // validateBuilderWithInvalidParam(List.of());
     }
 
     @Test
     @SmallTest
     public void testPublicConstructorWithValidParam() {
-        Collection<SignalThresholdInfo> infos = List.of(mRssiInfoOnGERAN, mRscpInfoOnUTRAN);
+        Collection<SignalThresholdInfo> infos = List.of(mRssiInfo, mRscpInfo);
         SignalStrengthUpdateRequest request = new SignalStrengthUpdateRequest.Builder()
                 .setSignalThresholdInfos(infos).setReportingRequestedWhileIdle(false).build();
         assertFalse(request.isReportingRequestedWhileIdle());
@@ -100,7 +74,7 @@
     @Test
     @SmallTest
     public void testParcel() {
-        Collection<SignalThresholdInfo> infos = List.of(mRssiInfoOnGERAN, mRscpInfoOnUTRAN);
+        Collection<SignalThresholdInfo> infos = List.of(mRssiInfo, mRscpInfo);
         SignalStrengthUpdateRequest request = new SignalStrengthUpdateRequest.Builder()
                 .setSignalThresholdInfos(infos).setReportingRequestedWhileIdle(true).build();
 
@@ -116,14 +90,14 @@
     @Test
     @SmallTest
     public void testEquals() {
-        Collection<SignalThresholdInfo> infos1 = List.of(mRssiInfoOnGERAN, mRssiInfoOnCDMA2000);
+        Collection<SignalThresholdInfo> infos1 = List.of(mRssiInfo, mRscpInfo);
         SignalStrengthUpdateRequest request1 = new SignalStrengthUpdateRequest.Builder()
                 .setSignalThresholdInfos(infos1).setReportingRequestedWhileIdle(false).build();
 
         assertTrue(request1.equals(request1));
 
         // Ordering does not matter
-        Collection<SignalThresholdInfo> infos2 = List.of(mRssiInfoOnCDMA2000, mRssiInfoOnGERAN);
+        Collection<SignalThresholdInfo> infos2 = List.of(mRscpInfo, mRssiInfo);
         SignalStrengthUpdateRequest request2 = new SignalStrengthUpdateRequest.Builder()
                 .setSignalThresholdInfos(infos2).setReportingRequestedWhileIdle(false).build();
         assertTrue(request1.equals(request2));
@@ -135,57 +109,11 @@
         SignalStrengthUpdateRequest request4 = new SignalStrengthUpdateRequest.Builder()
                 .setSignalThresholdInfos(infos1).setReportingRequestedWhileIdle(false)
                 .setSystemThresholdReportingRequestedWhileIdle(true).build();
-        assertFalse(request1.equals(request4));
 
         // return false if the object is not SignalStrengthUpdateRequest
         assertFalse(request1.equals("test"));
     }
 
-    @Test
-    @SmallTest
-    public void testMultipleSignalMeasurementTypeOnSameRan() {
-        Collection<SignalThresholdInfo> infos = List.of(mRsrpInfoOnEUTRAN, mRsrqInfoEUTRAN);
-        SignalStrengthUpdateRequest request = new SignalStrengthUpdateRequest.Builder()
-                .setSignalThresholdInfos(infos).build();
-
-        assertFalse(request.isReportingRequestedWhileIdle());
-        assertFalse(request.isSystemThresholdReportingRequestedWhileIdle());
-        assertEquals(infos, request.getSignalThresholdInfos());
-    }
-
-    @Test
-    @SmallTest
-    public void testSameSignalMeasurementTypeOnDifferentRan() {
-        Collection<SignalThresholdInfo> infos = List.of(mRssiInfoOnGERAN, mRssiInfoOnCDMA2000);
-        SignalStrengthUpdateRequest request = new SignalStrengthUpdateRequest.Builder()
-                .setSignalThresholdInfos(infos).build();
-
-        assertFalse(request.isReportingRequestedWhileIdle());
-        assertFalse(request.isSystemThresholdReportingRequestedWhileIdle());
-        assertEquals(infos, request.getSignalThresholdInfos());
-    }
-
-    @Test
-    @SmallTest
-    public void testSetSystemThresholdReportingRequestedWhileIdleToTrue_withNullThresholds() {
-        assertThrows(IllegalArgumentException.class,
-                () -> new SignalStrengthUpdateRequest.Builder()
-                        .setSystemThresholdReportingRequestedWhileIdle(true).build());
-    }
-
-    @Test
-    @SmallTest
-    public void testSetSystemThresholdReportingRequestedWhileIdleToTrue_withEmptyThresholds() {
-        SignalStrengthUpdateRequest request = new SignalStrengthUpdateRequest.Builder()
-                .setSignalThresholdInfos(Collections.EMPTY_LIST)
-                .setSystemThresholdReportingRequestedWhileIdle(true)
-                .build();
-
-        assertThat(request.getSignalThresholdInfos()).isEmpty();
-        assertThat(request.isReportingRequestedWhileIdle()).isFalse();
-        assertThat(request.isSystemThresholdReportingRequestedWhileIdle()).isTrue();
-    }
-
     private void validateBuilderWithInvalidParam(Collection<SignalThresholdInfo> infos) {
         try {
             new SignalStrengthUpdateRequest.Builder()
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimActivationTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SimActivationTrackerTest.java
index 23d992a..b99736f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimActivationTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimActivationTrackerTest.java
@@ -16,16 +16,6 @@
  */
 package com.android.internal.telephony;
 
-import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_ACTIVATED;
-import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_DEACTIVATED;
-import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_RESTRICTED;
-import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
 import junit.framework.AssertionFailedError;
 
 import org.junit.After;
@@ -34,12 +24,23 @@
 
 import java.security.InvalidParameterException;
 
+import static org.junit.Assert.assertEquals;
+import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_ACTIVATED;
+import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
+import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_RESTRICTED;
+import static android.telephony.TelephonyManager.SIM_ACTIVATION_STATE_DEACTIVATED;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
 public class SimActivationTrackerTest extends TelephonyTest {
     private SimActivationTracker mSAT;
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
+        super.setUp("SimActivaitonTrackerTest");
         mSAT = new SimActivationTracker(mPhone);
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
index e5ac907..c545cdd 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommands.java
@@ -17,7 +17,6 @@
 package com.android.internal.telephony.test;
 
 import android.compat.annotation.UnsupportedAppUsage;
-import android.hardware.radio.RadioError;
 import android.hardware.radio.V1_0.DataRegStateResult;
 import android.hardware.radio.V1_0.SetupDataCallResult;
 import android.hardware.radio.V1_0.VoiceRegStateResult;
@@ -44,7 +43,6 @@
 import android.telephony.ImsiEncryptionInfo;
 import android.telephony.NetworkRegistrationInfo;
 import android.telephony.NetworkScanRequest;
-import android.telephony.PcoData;
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SignalThresholdInfo;
@@ -63,7 +61,7 @@
 import com.android.internal.telephony.LastCallFailCause;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.RILUtils;
+import com.android.internal.telephony.RIL;
 import com.android.internal.telephony.RadioCapability;
 import com.android.internal.telephony.SmsResponse;
 import com.android.internal.telephony.UUSInfo;
@@ -71,12 +69,12 @@
 import com.android.internal.telephony.gsm.SmsBroadcastConfigInfo;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
 import com.android.internal.telephony.uicc.AdnCapacity;
+import com.android.internal.telephony.uicc.ReceivedPhonebookRecords;
+import com.android.internal.telephony.uicc.SimPhonebookRecord;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
 import com.android.internal.telephony.uicc.IccCardStatus;
 import com.android.internal.telephony.uicc.IccIoResult;
 import com.android.internal.telephony.uicc.IccSlotStatus;
-import com.android.internal.telephony.uicc.ReceivedPhonebookRecords;
-import com.android.internal.telephony.uicc.SimPhonebookRecord;
 import com.android.telephony.Rlog;
 
 import java.util.ArrayList;
@@ -87,7 +85,6 @@
 public class SimulatedCommands extends BaseCommands
         implements CommandsInterface, SimulatedRadioControl {
     private static final String LOG_TAG = "SimulatedCommands";
-    private boolean mSupportsEid = true;
 
     private enum SimLockState {
         NONE,
@@ -1192,13 +1189,6 @@
         }
     }
 
-    public void triggerNITZupdate(String NITZStr, long ageMs) {
-        if (NITZStr != null) {
-            mNITZTimeRegistrant.notifyRegistrant(new AsyncResult (null, new Object[]{NITZStr,
-                    SystemClock.elapsedRealtime(), ageMs}, null));
-        }
-    }
-
     @Override
     public void setupDataCall(int accessNetworkType, DataProfile dataProfile, boolean isRoaming,
             boolean allowRoaming, int reason, LinkProperties linkProperties, int pduSessionId,
@@ -1229,7 +1219,7 @@
             }
         }
 
-        DataCallResponse response = RILUtils.convertHalDataCallResult(mSetupDataCallResult);
+        DataCallResponse response = RIL.convertDataCallResult(mSetupDataCallResult);
         if (mDcSuccess) {
             resultSuccess(result, response);
         } else {
@@ -1240,7 +1230,7 @@
     @Override
     public void deactivateDataCall(int cid, int reason, Message result) {
         SimulatedCommandsVerifier.getInstance().deactivateDataCall(cid, reason, result);
-        resultSuccess(result, RadioError.NONE);
+        resultSuccess(result, null);
     }
 
     @Override
@@ -2337,14 +2327,10 @@
 
     @Override
     public void registerForPcoData(Handler h, int what, Object obj) {
-        SimulatedCommandsVerifier.getInstance().registerForPcoData(h, what, obj);
-        mPcoDataRegistrants.addUnique(h, what, obj);
     }
 
     @Override
     public void unregisterForPcoData(Handler h) {
-        SimulatedCommandsVerifier.getInstance().unregisterForPcoData(h);
-        mPcoDataRegistrants.remove(h);
     }
 
     @Override
@@ -2366,8 +2352,8 @@
     }
 
     @Override
-    public void setSignalStrengthReportingCriteria(List<SignalThresholdInfo> signalThresholdInfos,
-            Message result) {
+    public void setSignalStrengthReportingCriteria(SignalThresholdInfo signalThresholdInfo,
+            int ran, Message result) {
     }
 
     @Override
@@ -2481,15 +2467,6 @@
                 new ReceivedPhonebookRecords(4, phonebookRecordInfoGroup), null));
     }
 
-    public void setSupportsEid(boolean supportsEid) {
-        mSupportsEid = supportsEid;
-    }
-
-    @Override
-    public boolean supportsEid() {
-        return mSupportsEid;
-    }
-
     @Override
     public void getSimPhonebookCapacity(Message result) {
         resultSuccess(result, new AdnCapacity(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
@@ -2497,14 +2474,7 @@
 
     @Override
     public void updateSimPhonebookRecord(SimPhonebookRecord phonebookRecord, Message result) {
-        int recordId = phonebookRecord.getRecordId();
-        // Based on design, the record ID starts from 1.
-        // So if the record ID passed from upper layer is 0, it indicates to insert one new record
-        // without record ID specific.
-        if (recordId == 0) {
-            recordId = 1; // hack code for unit test
-        }
-        resultSuccess(result, new int[]{recordId});
+        resultSuccess(result, new int[]{phonebookRecord.getRecordIndex()});
         notifySimPhonebookChanged();
     }
 
@@ -2512,9 +2482,4 @@
     public void notifySimPhonebookChanged() {
         mSimPhonebookChangedRegistrants.notifyRegistrants();
     }
-
-    public void triggerPcoData(int cid, String bearerProto, int pcoId, byte[] contents) {
-        PcoData response = new PcoData(cid, bearerProto, pcoId, contents);
-        mPcoDataRegistrants.notifyRegistrants(new AsyncResult(null, response, null));
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
index f93e9e1..e9c74ae 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SimulatedCommandsVerifier.java
@@ -38,8 +38,6 @@
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.PersoSubState;
 import com.android.internal.telephony.uicc.SimPhonebookRecord;
 
-import java.util.List;
-
 public class SimulatedCommandsVerifier implements CommandsInterface {
     private static SimulatedCommandsVerifier sInstance;
 
@@ -1427,8 +1425,8 @@
     }
 
     @Override
-    public void setSignalStrengthReportingCriteria(List<SignalThresholdInfo> signalThresholdInfos,
-            Message result) {
+    public void setSignalStrengthReportingCriteria(SignalThresholdInfo signalThresholdInfo,
+            int ran, Message result) {
     }
 
     @Override
@@ -1527,12 +1525,4 @@
     @Override
     public void unregisterForSimPhonebookRecordsReceived(Handler h){
     }
-
-    @Override
-    public void registerForSlicingConfigChanged(Handler h, int what, Object obj) {
-    }
-
-    @Override
-    public void unregisterForSlicingConfigChanged(Handler h) {
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SlidingWindowEventCounterTest.java b/tests/telephonytests/src/com/android/internal/telephony/SlidingWindowEventCounterTest.java
index 7b613f8..da8b4c2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SlidingWindowEventCounterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SlidingWindowEventCounterTest.java
@@ -75,12 +75,5 @@
         counter.addOccurrence(mInitialTime + 101);
         counter.addOccurrence(mInitialTime + 102);
         assertFalse(counter.isInWindow());
-
-        counter = new SlidingWindowEventCounter(0, 2);
-        counter.addOccurrence(mInitialTime);
-        counter.addOccurrence(mInitialTime);
-        assertFalse(counter.isInWindow());
-        assertFalse(counter.addOccurrence(mInitialTime));
-        assertFalse(counter.addOccurrence(mInitialTime));
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/Sms7BitEncodingTranslatorTest.java b/tests/telephonytests/src/com/android/internal/telephony/Sms7BitEncodingTranslatorTest.java
index cc0eb94..3c7632b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/Sms7BitEncodingTranslatorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/Sms7BitEncodingTranslatorTest.java
@@ -20,7 +20,6 @@
 import static org.junit.Assert.fail;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 
 import android.test.suitebuilder.annotation.SmallTest;
 
@@ -28,18 +27,19 @@
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
+import org.mockito.Mock;
 
 import java.io.UnsupportedEncodingException;
 
 public class Sms7BitEncodingTranslatorTest extends TelephonyTest {
-    // Mocked classes
+
+    @Mock
     SmsController mSmsController;
 
     @Before
     public void setUp() throws Exception {
         logd("+Setup!");
         super.setUp(getClass().getSimpleName());
-        mSmsController = mock(SmsController.class);
         mServiceManagerMockedServices.put("isms", mSmsController);
         doReturn(false).when(mSmsController).isImsSmsSupportedForSubscriber(anyInt());
         logd("-Setup!");
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SmsDispatchersControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SmsDispatchersControllerTest.java
index 6ef8508..ee9e2b8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SmsDispatchersControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SmsDispatchersControllerTest.java
@@ -27,7 +27,6 @@
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -47,22 +46,21 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.HashMap;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class SmsDispatchersControllerTest extends TelephonyTest {
-    // Mocked classes
+    @Mock
     private SMSDispatcher.SmsTracker mTracker;
 
     private SmsDispatchersController mSmsDispatchersController;
     private boolean mInjectionCallbackTriggered = false;
-
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mTracker = mock(SMSDispatcher.SmsTracker.class);
         setupMockPackagePermissionChecks();
 
         mSmsDispatchersController = new SmsDispatchersController(mPhone, mSmsStorageMonitor,
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SmsNumberUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/SmsNumberUtilsTest.java
index 3c1cec1..ff3c36c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SmsNumberUtilsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SmsNumberUtilsTest.java
@@ -131,7 +131,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mHbpcdContentProvider = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SmsPermissionsTest.java b/tests/telephonytests/src/com/android/internal/telephony/SmsPermissionsTest.java
index 2a7f35b..c69c733 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SmsPermissionsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SmsPermissionsTest.java
@@ -24,6 +24,7 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
 
 import android.Manifest;
 import android.app.AppOpsManager;
@@ -35,7 +36,9 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
 
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -47,9 +50,11 @@
 
     private HandlerThread mHandlerThread;
 
-    // Mocked classes
+    @Mock
     private Phone mMockPhone;
+    @Mock
     private Context mMockContext;
+    @Mock
     private AppOpsManager mMockAppOps;
 
     private SmsPermissions mSmsPermissionsTest;
@@ -59,11 +64,9 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mMockPhone = Mockito.mock(Phone.class);
-        mMockContext = Mockito.mock(Context.class);
-        mMockAppOps = Mockito.mock(AppOpsManager.class);
+        super.setUp("SmsPermissionsTest");
 
+        MockitoAnnotations.initMocks(this);
         mHandlerThread = new HandlerThread("IccSmsInterfaceManagerTest");
         mHandlerThread.start();
         final CountDownLatch initialized = new CountDownLatch(1);
@@ -94,8 +97,6 @@
     public void tearDown() throws Exception {
         mHandlerThread.quit();
         mHandlerThread.join();
-        mHandlerThread = null;
-        mSmsPermissionsTest = null;
         super.tearDown();
     }
 
@@ -256,7 +257,7 @@
 
     @Test
     public void testPackageNameMatchesCallingUid() {
-        AppOpsManager mockAppOpsManager = Mockito.mock(AppOpsManager.class);
+        AppOpsManager mockAppOpsManager = mock(AppOpsManager.class);
         Mockito.when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(
                 mockAppOpsManager);
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
index 6a4c9c2..8f2c08e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionControllerTest.java
@@ -25,7 +25,6 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNotSame;
 import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
@@ -35,7 +34,6 @@
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -56,14 +54,12 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
-import android.telephony.UiccPortInfo;
 import android.telephony.UiccSlotInfo;
 import android.test.mock.MockContentResolver;
 
 import androidx.test.filters.FlakyTest;
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.telephony.data.PhoneSwitcher;
 import com.android.internal.telephony.uicc.IccCardStatus;
 import com.android.internal.telephony.uicc.UiccController;
 import com.android.internal.telephony.uicc.UiccSlot;
@@ -72,10 +68,10 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
@@ -90,15 +86,19 @@
     private SubscriptionController mSubscriptionControllerUT;
     private MockContentResolver mMockContentResolver;
     private FakeTelephonyProvider mFakeTelephonyProvider;
-    private PersistableBundle mCarrierConfigs;
-
-    // Mocked classes
+    @Mock
     private UiccSlot mUiccSlot;
-    private ITelephonyRegistry.Stub mTelephonyRegistryMock;
+    @Mock
+    private ITelephonyRegistry.Stub mTelephonyRegisteryMock;
+    @Mock
     private MultiSimSettingController mMultiSimSettingControllerMock;
+    @Mock
     private ISetOpportunisticDataCallback mSetOpptDataCallback;
+    @Mock
     private Handler mHandler;
+    @Mock
     private SubscriptionInfo mMockSubscriptionInfo;
+    private PersistableBundle mCarrierConfigs;
 
     private static final String MAC_ADDRESS_PREFIX = "mac_";
     private static final String DISPLAY_NAME_PREFIX = "my_phone_";
@@ -110,13 +110,8 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mUiccSlot = mock(UiccSlot.class);
-        mTelephonyRegistryMock = mock(ITelephonyRegistry.Stub.class);
-        mMultiSimSettingControllerMock = mock(MultiSimSettingController.class);
-        mSetOpptDataCallback = mock(ISetOpportunisticDataCallback.class);
-        mHandler = mock(Handler.class);
-        mMockSubscriptionInfo = mock(SubscriptionInfo.class);
+        super.setUp("SubscriptionControllerTest");
+
         if (Looper.myLooper() == null) {
             Looper.prepare();
         }
@@ -141,24 +136,24 @@
         mCarrierConfigs = mContextFixture.getCarrierConfigBundle();
 
         mContextFixture.putIntArrayResource(com.android.internal.R.array.sim_colors, new int[]{5});
+
         setupMocksForTelephonyPermissions(Build.VERSION_CODES.R);
     }
 
     @After
     public void tearDown() throws Exception {
         mContextFixture.addCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
-        /* Should clear fake content provider and resolver here */
+        /* should clear fake content provider and resolver here */
         mContext.getContentResolver().delete(SubscriptionManager.CONTENT_URI, null, null);
 
-        /* Clear sub info in mSubscriptionControllerUT since they will otherwise be persistent
+        /*clear sub info in mSubscriptionControllerUT since they will otherwise be persistent
          * between each test case. */
         if (mSubscriptionControllerUT != null) {
             mSubscriptionControllerUT.clearSubInfo();
             mSubscriptionControllerUT.resetStaticMembers();
-            mSubscriptionControllerUT = null;
         }
 
-        /* Clear settings for default voice/data/sms sub ID */
+        /* clear settings for default voice/data/sms sub ID */
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.MULTI_SIM_VOICE_CALL_SUBSCRIPTION,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
@@ -169,11 +164,7 @@
                 Settings.Global.MULTI_SIM_SMS_SUBSCRIPTION,
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
 
-        mCallingPackage = null;
-        mCallingFeature = null;
-        mMockContentResolver = null;
-        mFakeTelephonyProvider = null;
-        mCarrierConfigs = null;
+        mSubscriptionControllerUT = null;
         super.tearDown();
     }
 
@@ -203,42 +194,6 @@
     }
 
     @Test @SmallTest
-    public void testUsageSettingProperty() {
-        testInsertSim();
-        /* Get SUB ID */
-        int[] subIds = mSubscriptionControllerUT.getActiveSubIdList(/*visibleOnly*/false);
-        assertTrue(subIds != null && subIds.length != 0);
-        final int subId = subIds[0];
-
-        /* Getting, there is no direct getter function for each fields of property */
-        SubscriptionInfo subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);
-
-        // assertEquals(SubscriptionManager.USAGE_SETTING_UNKNOWN, subInfo.getUsageSetting());
-
-        assertThrows(IllegalArgumentException.class,
-                () -> mSubscriptionControllerUT.setUsageSetting(
-                        SubscriptionManager.USAGE_SETTING_UNKNOWN,
-                        subId,
-                        mCallingPackage));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> mSubscriptionControllerUT.setUsageSetting(
-                        SubscriptionManager.USAGE_SETTING_DEFAULT,
-                        SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
-                        mCallingPackage));
-
-        mSubscriptionControllerUT.setUsageSetting(
-                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
-                subId,
-                mCallingPackage);
-
-        subInfo = mSubscriptionControllerUT
-                .getActiveSubscriptionInfo(subId, mCallingPackage, mCallingFeature);
-        assertEquals(SubscriptionManager.USAGE_SETTING_DATA_CENTRIC, subInfo.getUsageSetting());
-    }
-
-    @Test @SmallTest
     public void testChangeSIMProperty() {
         int dataRoaming = 1;
         int iconTint = 1;
@@ -810,7 +765,6 @@
     @Test @SmallTest
     public void testInsertRemoteSim() {
         makeThisDeviceMultiSimCapable();
-        mContextFixture.addSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
 
         // verify there are no sim's in the system.
         assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage,
@@ -899,7 +853,6 @@
     @Test @SmallTest
     public void testInsertMultipleRemoteSims() {
         makeThisDeviceMultiSimCapable();
-        mContextFixture.addSystemFeature(PackageManager.FEATURE_AUTOMOTIVE);
 
         // verify that there are no subscription info records
         assertEquals(0, mSubscriptionControllerUT.getAllSubInfoCount(mCallingPackage,
@@ -1030,7 +983,7 @@
         assertEquals(null, prop);
 
         // group UUID should succeed once privileged phone state permission is granted
-        setupReadPrivilegePermission();
+        mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
         prop = mSubscriptionControllerUT.getSubscriptionProperty(1, SubscriptionManager.GROUP_UUID,
                 mContext.getOpPackageName(), mContext.getAttributionTag());
         assertNotEquals(null, prop);
@@ -1328,8 +1281,8 @@
     }
 
     private void registerMockTelephonyRegistry() {
-        mServiceManagerMockedServices.put("telephony.registry", mTelephonyRegistryMock);
-        doReturn(mTelephonyRegistryMock).when(mTelephonyRegistryMock)
+        mServiceManagerMockedServices.put("telephony.registry", mTelephonyRegisteryMock);
+        doReturn(mTelephonyRegisteryMock).when(mTelephonyRegisteryMock)
                 .queryLocalInterface(anyString());
     }
 
@@ -1374,10 +1327,8 @@
         // If the calling package does not have the READ_PHONE_STATE permission or carrier
         // privileges then getActiveSubscriptionInfo should throw a SecurityException;
         testInsertSim();
-        setupReadPrivilegePermission();
-        int subId = getFirstSubId();
-        removeReadPrivilegePermission();
         mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL);
+        int subId = getFirstSubId();
 
         try {
             mSubscriptionControllerUT.getActiveSubscriptionInfo(subId, mCallingPackage,
@@ -1395,7 +1346,6 @@
         testInsertSim();
         setupReadPhoneNumbersTest();
         setIdentifierAccess(false);
-        setupReadPrivilegePermission();
         int subId = getFirstSubId();
 
         SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
@@ -1415,7 +1365,6 @@
         testInsertSim();
         setupReadPhoneNumbersTest();
         setPhoneNumberAccess(PackageManager.PERMISSION_GRANTED);
-        setupReadPrivilegePermission();
         int subId = getFirstSubId();
 
         SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
@@ -1431,7 +1380,6 @@
         // privileges the ICC ID should be available in the SubscriptionInfo.
         testInsertSim();
         setupIdentifierCarrierPrivilegesTest();
-        setupReadPrivilegePermission();
         int subId = getFirstSubId();
 
         SubscriptionInfo subscriptionInfo = mSubscriptionControllerUT.getActiveSubscriptionInfo(
@@ -1815,15 +1763,6 @@
         setCarrierPrivileges(true);
     }
 
-    private void setupReadPrivilegePermission() throws Exception {
-        mContextFixture.addCallingOrSelfPermissionToCurrentPermissions(
-                Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
-    }
-    private void removeReadPrivilegePermission() throws Exception {
-        mContextFixture.removeCallingOrSelfPermission(
-                Manifest.permission.READ_PRIVILEGED_PHONE_STATE);
-    }
-
     private int getFirstSubId() throws Exception {
         return getSubIdAtIndex(0);
     }
@@ -1838,8 +1777,8 @@
     public void testGetEnabledSubscriptionIdSingleSIM() {
         // A single SIM device may have logical slot 0 mapped to physical slot 1
         // (i.e. logical slot -1 mapped to physical slot 0)
-        UiccSlotInfo slot0 = getFakeUiccSlotInfo(false, -1, null);
-        UiccSlotInfo slot1 = getFakeUiccSlotInfo(true, 0, null);
+        UiccSlotInfo slot0 = getFakeUiccSlotInfo(false, -1);
+        UiccSlotInfo slot1 = getFakeUiccSlotInfo(true, 0);
         UiccSlotInfo [] uiccSlotInfos = {slot0, slot1};
         UiccSlot [] uiccSlots = {mUiccSlot, mUiccSlot};
 
@@ -1862,8 +1801,8 @@
         doReturn(SINGLE_SIM).when(mTelephonyManager).getActiveModemCount();
         // A dual SIM device may have logical slot 0 mapped to physical slot 0
         // (i.e. logical slot 1 mapped to physical slot 1)
-        UiccSlotInfo slot0 = getFakeUiccSlotInfo(true, 0, null);
-        UiccSlotInfo slot1 = getFakeUiccSlotInfo(true, 1, null);
+        UiccSlotInfo slot0 = getFakeUiccSlotInfo(true, 0);
+        UiccSlotInfo slot1 = getFakeUiccSlotInfo(true, 1);
         UiccSlotInfo [] uiccSlotInfos = {slot0, slot1};
         UiccSlot [] uiccSlots = {mUiccSlot, mUiccSlot};
 
@@ -1885,17 +1824,13 @@
     }
 
 
-    private UiccSlotInfo getFakeUiccSlotInfo(boolean active, int logicalSlotIndex, String iccId) {
-        return getFakeUiccSlotInfo(active, logicalSlotIndex, "fake card Id", iccId);
+    private UiccSlotInfo getFakeUiccSlotInfo(boolean active, int logicalSlotIndex) {
+        return getFakeUiccSlotInfo(active, logicalSlotIndex, "fake card Id");
     }
 
-    private UiccSlotInfo getFakeUiccSlotInfo(
-            boolean active, int logicalSlotIndex, String cardId, String iccId) {
-        return new UiccSlotInfo(false, cardId,
-                UiccSlotInfo.CARD_STATE_INFO_PRESENT, true, true,
-                Collections.singletonList(
-                        new UiccPortInfo(iccId, 0, logicalSlotIndex, active)
-                ));
+    private UiccSlotInfo getFakeUiccSlotInfo(boolean active, int logicalSlotIndex, String cardId) {
+        return new UiccSlotInfo(active, false, cardId,
+                UiccSlotInfo.CARD_STATE_INFO_PRESENT, logicalSlotIndex, true, true);
     }
 
     @Test
@@ -1940,7 +1875,7 @@
         IccCardStatus.CardState cardState = CARDSTATE_PRESENT;
         doReturn(uiccSlots).when(mUiccController).getUiccSlots();
         doReturn(cardState).when(mUiccSlot).getCardState();
-        doReturn("123").when(mUiccSlot).getIccId(0); // default port index
+        doReturn("123").when(mUiccSlot).getIccId();
         mSubscriptionControllerUT.clearSubInfoRecord(1);
 
         // Active sub list should return 1 now.
@@ -1970,8 +1905,7 @@
         doReturn(uiccSlots).when(mUiccController).getUiccSlots();
         doReturn(cardState).when(mUiccSlot).getCardState();
         // IccId ends with a 'F' which should be ignored and taking into account.
-        doReturn("123F").when(mUiccSlot).getIccId(0); // default port index
-
+        doReturn("123F").when(mUiccSlot).getIccId();
         mSubscriptionControllerUT.clearSubInfoRecord(1);
 
         // Active sub list should return 1 now.
@@ -2011,7 +1945,7 @@
         String iccId = "123F";
         mSubscriptionControllerUT.addSubInfoRecord(iccId, 0);
         mSubscriptionControllerUT.registerForUiccAppsEnabled(mHandler, 0, null, false);
-        UiccSlotInfo slot = getFakeUiccSlotInfo(true, 0, iccId + "FF", iccId);
+        UiccSlotInfo slot = getFakeUiccSlotInfo(true, 0, iccId + "FF");
         UiccSlotInfo[] uiccSlotInfos = {slot};
         doReturn(uiccSlotInfos).when(mTelephonyManager).getUiccSlotsInfo();
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
index ea38e2d..1161792 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/SubscriptionInfoUpdaterTest.java
@@ -27,7 +27,6 @@
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -67,17 +66,20 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class SubscriptionInfoUpdaterTest extends TelephonyTest {
+
     private static final int FAKE_SUB_ID_1 = 0;
     private static final int FAKE_SUB_ID_2 = 1;
     private static final int FAKE_CARD_ID = 0;
@@ -89,16 +91,23 @@
 
     private SubscriptionInfoUpdater mUpdater;
     private IccRecords mIccRecord;
-
-    // Mocked classes
+    @Mock
     private UserInfo mUserInfo;
+    @Mock
     private SubscriptionInfo mSubInfo;
+    @Mock
     private ContentProvider mContentProvider;
+    @Mock
     private HashMap<String, Object> mSubscriptionContent;
+    @Mock
     private IccFileHandler mIccFileHandler;
+    @Mock
     private EuiccController mEuiccController;
+    @Mock
     private IntentBroadcaster mIntentBroadcaster;
+    @Mock
     private IPackageManager mPackageManager;
+    @Mock
     private UiccSlot mUiccSlot;
 
     /*Custom ContentProvider */
@@ -111,16 +120,7 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mUserInfo = mock(UserInfo.class);
-        mSubInfo = mock(SubscriptionInfo.class);
-        mContentProvider = mock(ContentProvider.class);
-        mSubscriptionContent = mock(HashMap.class);
-        mIccFileHandler = mock(IccFileHandler.class);
-        mEuiccController = mock(EuiccController.class);
-        mIntentBroadcaster = mock(IntentBroadcaster.class);
-        mPackageManager = mock(IPackageManager.class);
-        mUiccSlot = mock(UiccSlot.class);
+        super.setUp(this.getClass().getSimpleName());
 
         replaceInstance(SubscriptionInfoUpdater.class, "sIccId", null, new String[1]);
         replaceInstance(SubscriptionInfoUpdater.class, "sContext", null, null);
@@ -169,8 +169,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mIccRecord = null;
-        mUpdater = null;
         super.tearDown();
     }
 
@@ -202,7 +200,7 @@
                 .getSubInfoUsingSlotIndexPrivileged(eq(FAKE_SUB_ID_1));
         doReturn(new int[]{FAKE_SUB_ID_1}).when(mSubscriptionController)
                 .getActiveSubIdList(/*visibleOnly*/false);
-        mUpdater.updateInternalIccStateForInactivePort(FAKE_SUB_ID_1, null);
+        mUpdater.updateInternalIccStateForInactiveSlot(FAKE_SUB_ID_1, null);
 
         processAllMessages();
         assertTrue(mUpdater.isSubInfoInitialized());
@@ -281,8 +279,7 @@
         String iccId = "123456";
         doReturn(mIccCard).when(mPhone).getIccCard();
         doReturn(false).when(mIccCard).isEmptyProfile();
-        doReturn(mUiccPort).when(mUiccController).getUiccPort(anyInt());
-        doReturn(iccId).when(mUiccPort).getIccId();
+        doReturn(iccId).when(mUiccSlot).getIccId();
         doReturn(mSubInfo).when(mSubscriptionController).getSubInfoForIccId(iccId);
         doReturn(false).when(mSubInfo).areUiccApplicationsEnabled();
 
@@ -627,12 +624,12 @@
         // Info for 1 and 3 should be updated as active embedded subscriptions.
         ArgumentCaptor<ContentValues> iccid1Values = ArgumentCaptor.forClass(ContentValues.class);
         verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), iccid1Values.capture(),
-                eq(SubscriptionManager.ICC_ID + "='1'"), isNull());
+                eq(SubscriptionManager.ICC_ID + "=\"1\""), isNull());
         assertEquals(1,
                 iccid1Values.getValue().getAsInteger(SubscriptionManager.IS_EMBEDDED).intValue());
         ArgumentCaptor<ContentValues> iccid3Values = ArgumentCaptor.forClass(ContentValues.class);
         verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), iccid3Values.capture(),
-                eq(SubscriptionManager.ICC_ID + "='3'"), isNull());
+                eq(SubscriptionManager.ICC_ID + "=\"3\""), isNull());
         assertEquals(1,
                 iccid3Values.getValue().getAsInteger(SubscriptionManager.IS_EMBEDDED).intValue());
 
@@ -640,7 +637,7 @@
         // in the list provided by the LPA.
         ArgumentCaptor<ContentValues> iccid2Values = ArgumentCaptor.forClass(ContentValues.class);
         verify(mContentProvider).update(eq(SubscriptionManager.CONTENT_URI), iccid2Values.capture(),
-                eq(SubscriptionManager.ICC_ID + " IN ('2')"), isNull());
+                eq(SubscriptionManager.ICC_ID + " IN (\"2\")"), isNull());
         assertEquals(0,
                 iccid2Values.getValue().getAsInteger(SubscriptionManager.IS_EMBEDDED).intValue());
     }
@@ -745,8 +742,8 @@
 
         doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId);
         doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
-        doReturn(carrierPackageName).when(mTelephonyManager)
-                .getCarrierServicePackageNameForLogicalSlot(eq(phoneId));
+        doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager)
+                .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId));
         ((MockContentResolver) mContext.getContentResolver()).addProvider(
                 SubscriptionManager.CONTENT_URI.getAuthority(),
                 new FakeSubscriptionContentProvider());
@@ -771,8 +768,8 @@
         doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId);
         doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
         doReturn(false).when(mSubInfo).isOpportunistic();
-        doReturn(carrierPackageName).when(mTelephonyManager)
-                .getCarrierServicePackageNameForLogicalSlot(eq(phoneId));
+        doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager)
+                .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId));
         ((MockContentResolver) mContext.getContentResolver()).addProvider(
                 SubscriptionManager.CONTENT_URI.getAuthority(),
                 new FakeSubscriptionContentProvider());
@@ -804,8 +801,8 @@
                 ParcelUuid.fromString("11111111-2222-3333-4444-555555555555"), carrierPackageName);
         doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId);
         doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
-        doReturn(carrierPackageName).when(mTelephonyManager)
-                .getCarrierServicePackageNameForLogicalSlot(eq(phoneId));
+        doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager)
+                .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId));
         ((MockContentResolver) mContext.getContentResolver()).addProvider(
                 SubscriptionManager.CONTENT_URI.getAuthority(),
                 new FakeSubscriptionContentProvider());
@@ -841,8 +838,8 @@
         doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
         doReturn(ParcelUuid.fromString("11111111-2222-3333-4444-555555555555"))
             .when(mSubInfo).getGroupUuid();
-        doReturn(carrierPackageName).when(mTelephonyManager)
-                .getCarrierServicePackageNameForLogicalSlot(eq(phoneId));
+        doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager)
+                .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId));
         ((MockContentResolver) mContext.getContentResolver()).addProvider(
                 SubscriptionManager.CONTENT_URI.getAuthority(),
                 new FakeSubscriptionContentProvider());
@@ -863,103 +860,6 @@
 
     @Test
     @SmallTest
-    public void testUpdateFromCarrierConfigPreferredUsageSettingDataCentric() throws Exception {
-        testUpdateFromCarrierConfigPreferredUsageSetting(
-                SubscriptionManager.USAGE_SETTING_UNKNOWN,
-                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
-                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC);
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateFromCarrierConfigPreferredUsageSettingDataCentric2() throws Exception {
-        testUpdateFromCarrierConfigPreferredUsageSetting(
-                SubscriptionManager.USAGE_SETTING_DEFAULT,
-                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
-                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC);
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateFromCarrierConfigPreferredUsageSettingDefault() throws Exception {
-        testUpdateFromCarrierConfigPreferredUsageSetting(
-                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
-                SubscriptionManager.USAGE_SETTING_DEFAULT,
-                SubscriptionManager.USAGE_SETTING_DEFAULT);
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateFromCarrierConfigPreferredUsageSettingNoChange() throws Exception {
-        testUpdateFromCarrierConfigPreferredUsageSetting(
-                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
-                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
-                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC);
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateFromCarrierConfigPreferredUsageSettingInvalid() throws Exception {
-        testUpdateFromCarrierConfigPreferredUsageSetting(
-                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
-                SubscriptionManager.USAGE_SETTING_UNKNOWN,
-                SubscriptionManager.USAGE_SETTING_DATA_CENTRIC);
-    }
-
-    private PersistableBundle getCarrierConfigForSubInfoUpdateUsageSetting(
-            @SubscriptionManager.UsageSetting int usageSetting) {
-        PersistableBundle p = new PersistableBundle();
-        p.putString(CarrierConfigManager.KEY_SUBSCRIPTION_GROUP_UUID_STRING, "");
-        p.putBoolean(CarrierConfigManager.KEY_IS_OPPORTUNISTIC_SUBSCRIPTION_BOOL, false);
-        p.putInt(CarrierConfigManager.KEY_CELLULAR_USAGE_SETTING_INT, usageSetting);
-        return p;
-    }
-
-    private void testUpdateFromCarrierConfigPreferredUsageSetting(
-            int initialSetting, int requestedSetting, int expectedSetting) throws Exception {
-        final String carrierPackageName = "FakeCarrierPackageName";
-        final int phoneId = mPhone.getPhoneId();
-
-        // Install fixtures, ensure the test will hit the right code path
-        doReturn(carrierPackageName).when(mTelephonyManager)
-                .getCarrierServicePackageNameForLogicalSlot(eq(phoneId));
-        ((MockContentResolver) mContext.getContentResolver()).addProvider(
-                SubscriptionManager.CONTENT_URI.getAuthority(),
-                new FakeSubscriptionContentProvider());
-
-        // Setup overlay
-        setupUsageSettingResources();
-
-        // Setup subscription
-        doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId);
-        doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
-        doReturn(null).when(mSubInfo).getGroupUuid();
-        doReturn(false).when(mSubInfo).isOpportunistic();
-        doReturn(initialSetting).when(mSubInfo).getUsageSetting();
-
-        // Get a config bundle for that prefers data centric
-        PersistableBundle carrierConfig = getCarrierConfigForSubInfoUpdateUsageSetting(
-                requestedSetting);
-
-        mUpdater.updateSubscriptionByCarrierConfig(mPhone.getPhoneId(),
-                carrierPackageName, carrierConfig);
-
-        ArgumentCaptor<ContentValues> cvCaptor = ArgumentCaptor.forClass(ContentValues.class);
-        verify(mContentProvider, times(1)).update(
-                eq(SubscriptionManager.getUriForSubscriptionId(FAKE_SUB_ID_1)),
-                cvCaptor.capture(), eq(null), eq(null));
-
-        if (initialSetting != expectedSetting) {
-            assertEquals(expectedSetting,
-                    (int) cvCaptor.getValue().getAsInteger(SubscriptionManager.USAGE_SETTING));
-        } else {
-            // If the content value was not set, the captor value will be null
-            assertNull(cvCaptor.getValue().getAsInteger(SubscriptionManager.USAGE_SETTING));
-        }
-    }
-
-    @Test
-    @SmallTest
     public void testUpdateFromCarrierConfigCarrierCertificates() {
         String[] certs = new String[2];
         certs[0] = "d1f1";
@@ -981,8 +881,8 @@
         doReturn(FAKE_SUB_ID_1).when(mSubscriptionController).getSubIdUsingPhoneId(phoneId);
         doReturn(mSubInfo).when(mSubscriptionController).getSubscriptionInfo(eq(FAKE_SUB_ID_1));
         doReturn(false).when(mSubInfo).isOpportunistic();
-        doReturn(carrierPackageName).when(mTelephonyManager)
-                .getCarrierServicePackageNameForLogicalSlot(eq(phoneId));
+        doReturn(Collections.singletonList(carrierPackageName)).when(mTelephonyManager)
+                .getCarrierPackageNamesForIntentAndPhone(any(), eq(phoneId));
         ((MockContentResolver) mContext.getContentResolver()).addProvider(
                 SubscriptionManager.CONTENT_URI.getAuthority(),
                 new FakeSubscriptionContentProvider());
@@ -1005,8 +905,8 @@
     @SmallTest
     public void testSimReady() throws Exception {
         replaceInstance(SubscriptionInfoUpdater.class, "sIccId", null,new String[]{""});
-        doReturn(mUiccPort).when(mUiccController).getUiccPort(anyInt());
-        doReturn(FAKE_ICCID_1).when(mUiccPort).getIccId();
+
+        doReturn(FAKE_ICCID_1).when(mUiccSlot).getIccId();
 
         mUpdater.updateInternalIccState(
             IccCardConstants.INTENT_VALUE_ICC_READY, "TESTING", FAKE_SUB_ID_1);
@@ -1024,8 +924,7 @@
     public void testSimReadyAndLoaded() throws Exception {
         replaceInstance(SubscriptionInfoUpdater.class, "sIccId", null,new String[]{""});
 
-        doReturn(mUiccPort).when(mUiccController).getUiccPort(anyInt());
-        doReturn(null).when(mUiccPort).getIccId();
+        doReturn(null).when(mUiccSlot).getIccId();
 
         mUpdater.updateInternalIccState(
             IccCardConstants.INTENT_VALUE_ICC_READY, "TESTING", FAKE_SUB_ID_1);
@@ -1041,36 +940,4 @@
                 eq(FAKE_ICCID_1), eq(FAKE_SUB_ID_1));
         verify(mSubscriptionController, times(1)).notifySubscriptionInfoChanged();
     }
-
-    private void setupUsageSettingResources() {
-        // The most common case, request a voice-centric->data-centric change
-        mContextFixture.putIntResource(
-                com.android.internal.R.integer.config_default_cellular_usage_setting,
-                SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC);
-        mContextFixture.putIntArrayResource(
-                com.android.internal.R.array.config_supported_cellular_usage_settings,
-                new int[]{
-                        SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC,
-                        SubscriptionManager.USAGE_SETTING_DATA_CENTRIC});
-    }
-
-    @Test
-    @SmallTest
-    public void testCalculateUsageSetting() throws Exception {
-        setupUsageSettingResources();
-        assertEquals(SubscriptionManager.USAGE_SETTING_DATA_CENTRIC,
-                mUpdater.calculateUsageSetting(
-                    SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC,
-                    SubscriptionManager.USAGE_SETTING_DATA_CENTRIC));
-
-        // Test that a voice-centric-only device only allows voice-centric configuration
-        mContextFixture.putIntArrayResource(
-                com.android.internal.R.array.config_supported_cellular_usage_settings,
-                new int[]{SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC});
-
-        assertEquals(SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC,
-                mUpdater.calculateUsageSetting(
-                    SubscriptionManager.USAGE_SETTING_VOICE_CENTRIC,
-                    SubscriptionManager.USAGE_SETTING_DATA_CENTRIC));
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
index 0e6e2f7..b545c2b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyPermissionsTest.java
@@ -25,7 +25,6 @@
 import static org.mockito.ArgumentMatchers.nullable;
 import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.app.AppOpsManager;
@@ -49,9 +48,10 @@
 import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.pm.permission.LegacyPermissionManagerService;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.lang.reflect.Field;
 import java.util.Map;
@@ -67,17 +67,27 @@
     private static final String FEATURE = "com.example.feature";
     private static final String MSG = "message";
 
-    // Mocked classes
+    @Mock
     private Context mMockContext;
+    @Mock
     private AppOpsManager mMockAppOps;
+    @Mock
     private SubscriptionManager mMockSubscriptionManager;
+    @Mock
     private ITelephony mMockTelephony;
+    @Mock
     private IBinder mMockTelephonyBinder;
+    @Mock
     private PackageManager mMockPackageManager;
+    @Mock
     private ApplicationInfo mMockApplicationInfo;
+    @Mock
     private TelephonyManager mTelephonyManagerMock;
+    @Mock
     private TelephonyManager mTelephonyManagerMockForSub1;
+    @Mock
     private TelephonyManager mTelephonyManagerMockForSub2;
+    @Mock
     private LegacyPermissionManagerService mMockLegacyPermissionManagerService;
 
     private MockContentResolver mMockContentResolver;
@@ -85,17 +95,7 @@
 
     @Before
     public void setUp() throws Exception {
-        mMockContext = mock(Context.class);
-        mMockAppOps = mock(AppOpsManager.class);
-        mMockSubscriptionManager = mock(SubscriptionManager.class);
-        mMockTelephony = mock(ITelephony.class);
-        mMockTelephonyBinder = mock(IBinder.class);
-        mMockPackageManager = mock(PackageManager.class);
-        mMockApplicationInfo = mock(ApplicationInfo.class);
-        mTelephonyManagerMock = mock(TelephonyManager.class);
-        mTelephonyManagerMockForSub1 = mock(TelephonyManager.class);
-        mTelephonyManagerMockForSub2 = mock(TelephonyManager.class);
-        mMockLegacyPermissionManagerService = mock(LegacyPermissionManagerService.class);
+        MockitoAnnotations.initMocks(this);
 
         when(mMockContext.getSystemService(Context.TELEPHONY_SERVICE)).thenReturn(
                 mTelephonyManagerMock);
@@ -130,12 +130,6 @@
         setTelephonyMockAsService();
     }
 
-    @After
-    public void tearDown() {
-        mMockContentResolver = null;
-        mFakeSettingsConfigProvider = null;
-    }
-
     @Test
     public void testCheckReadPhoneState_noPermissions() {
         try {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
index dbb371b..d14bbd0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyRegistryTest.java
@@ -47,11 +47,9 @@
 import android.telephony.CellIdentityGsm;
 import android.telephony.CellLocation;
 import android.telephony.LinkCapacityEstimate;
-import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PhoneCapability;
 import android.telephony.PhysicalChannelConfig;
 import android.telephony.PreciseDataConnectionState;
-import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyCallback;
@@ -61,7 +59,6 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
-import android.text.TextUtils;
 
 import androidx.annotation.NonNull;
 
@@ -71,6 +68,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -83,10 +81,8 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class TelephonyRegistryTest extends TelephonyTest {
-    // Mocked classes
+    @Mock
     private SubscriptionInfo mMockSubInfo;
-    private TelephonyRegistry.ConfigurationProvider mMockConfigurationProvider;
-
     private TelephonyCallbackWrapper mTelephonyCallback;
     private List<LinkCapacityEstimate> mLinkCapacityEstimateList;
     private TelephonyRegistry mTelephonyRegistry;
@@ -94,11 +90,9 @@
     private int mActiveSubId;
     private TelephonyDisplayInfo mTelephonyDisplayInfo;
     private int mSrvccState = -1;
-    private ServiceState mServiceState = null;
     private int mRadioPowerState = RADIO_POWER_UNAVAILABLE;
-    private int mDataConnectionState = TelephonyManager.DATA_UNKNOWN;
-    private int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
     private List<PhysicalChannelConfig> mPhysicalChannelConfigs;
+    private TelephonyRegistry.ConfigurationProvider mMockConfigurationProvider;
     private CellLocation mCellLocation;
 
     // All events contribute to TelephonyRegistry#isPhoneStatePermissionRequired
@@ -161,12 +155,10 @@
             TelephonyCallback.ActiveDataSubscriptionIdListener,
             TelephonyCallback.RadioPowerStateListener,
             TelephonyCallback.PreciseDataConnectionStateListener,
-            TelephonyCallback.DataConnectionStateListener,
             TelephonyCallback.DisplayInfoListener,
             TelephonyCallback.LinkCapacityEstimateChangedListener,
             TelephonyCallback.PhysicalChannelConfigListener,
-            TelephonyCallback.CellLocationListener,
-            TelephonyCallback.ServiceStateListener {
+            TelephonyCallback.CellLocationListener {
         // This class isn't mockable to get invocation counts because the IBinder is null and
         // crashes the TelephonyRegistry. Make a cheesy verify(times()) alternative.
         public AtomicInteger invocationCount = new AtomicInteger(0);
@@ -178,12 +170,6 @@
         }
 
         @Override
-        public void onServiceStateChanged(ServiceState serviceState) {
-            invocationCount.incrementAndGet();
-            mServiceState = serviceState;
-        }
-
-        @Override
         public void onPhoneCapabilityChanged(PhoneCapability capability) {
             invocationCount.incrementAndGet();
             mPhoneCapability = capability;
@@ -203,12 +189,6 @@
             invocationCount.incrementAndGet();
         }
         @Override
-        public void onDataConnectionStateChanged(int state, int networkType) {
-            invocationCount.incrementAndGet();
-            mDataConnectionState = state;
-            mNetworkType = networkType;
-        }
-        @Override
         public void onDisplayInfoChanged(TelephonyDisplayInfo displayInfo) {
             mTelephonyDisplayInfo = displayInfo;
         }
@@ -235,12 +215,16 @@
         mTelephonyRegistry.systemRunning();
     }
 
-    private final Executor mSimpleExecutor = Runnable::run;
+    private Executor mSimpleExecutor = new Executor() {
+        @Override
+        public void execute(Runnable r) {
+            r.run();
+        }
+    };
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mMockSubInfo = mock(SubscriptionInfo.class);
+        super.setUp("TelephonyRegistryTest");
         mMockConfigurationProvider = mock(TelephonyRegistry.ConfigurationProvider.class);
         when(mMockConfigurationProvider.getRegistrationLimit()).thenReturn(-1);
         when(mMockConfigurationProvider.isRegistrationLimitEnabledInPlatformCompat(anyInt()))
@@ -259,9 +243,6 @@
         addTelephonyRegistryService();
         mTelephonyCallback = new TelephonyCallbackWrapper();
         mTelephonyCallback.init(mSimpleExecutor);
-        mContextFixture.putStringArrayResource(
-                com.android.internal.R.array.config_serviceStateLocationAllowedPackages,
-                new String[0]);
         processAllMessages();
         assertEquals(mTelephonyRegistry.asBinder(),
                 ServiceManager.getService("telephony.registry"));
@@ -270,20 +251,6 @@
     @After
     public void tearDown() throws Exception {
         mTelephonyRegistry = null;
-        mTelephonyCallback = null;
-        if (mLinkCapacityEstimateList != null) {
-            mLinkCapacityEstimateList.clear();
-            mLinkCapacityEstimateList = null;
-        }
-        mTelephonyRegistry = null;
-        mPhoneCapability = null;
-        mTelephonyDisplayInfo = null;
-        mServiceState = null;
-        if (mPhysicalChannelConfigs != null) {
-            mPhysicalChannelConfigs.clear();
-            mPhysicalChannelConfigs = null;
-        }
-        mCellLocation = null;
         super.tearDown();
     }
 
@@ -295,7 +262,7 @@
         PhoneCapability phoneCapability = new PhoneCapability(1, 2, null, false, new int[0]);
         int[] events = {TelephonyCallback.EVENT_PHONE_CAPABILITY_CHANGED};
         mTelephonyRegistry.notifyPhoneCapabilityChanged(phoneCapability);
-        mTelephonyRegistry.listenWithEventList(false, false, 0, mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithEventList(0, mContext.getOpPackageName(),
                 mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
         processAllMessages();
         assertEquals(phoneCapability, mPhoneCapability);
@@ -315,9 +282,8 @@
         when(mSubscriptionManager.getActiveSubscriptionIdList()).thenReturn(activeSubs);
         int activeSubId = 0;
         mTelephonyRegistry.notifyActiveDataSubIdChanged(activeSubId);
-        mTelephonyRegistry.listenWithEventList(false, false, activeSubId,
-                mContext.getOpPackageName(), mContext.getAttributionTag(),
-                mTelephonyCallback.callback, events, true);
+        mTelephonyRegistry.listenWithEventList(activeSubId, mContext.getOpPackageName(),
+                mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
         processAllMessages();
         assertEquals(activeSubId, mActiveSubId);
 
@@ -343,9 +309,8 @@
         int[] events = {TelephonyCallback.EVENT_SRVCC_STATE_CHANGED};
         mTelephonyRegistry.notifySrvccStateChanged(1 /*subId*/, srvccState);
         // Should receive callback when listen is called that contains the latest notify result.
-        mTelephonyRegistry.listenWithEventList(false, false, 1 /*subId*/,
-                mContext.getOpPackageName(), mContext.getAttributionTag(),
-                mTelephonyCallback.callback, events, true);
+        mTelephonyRegistry.listenWithEventList(1 /*subId*/, mContext.getOpPackageName(),
+                mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
         processAllMessages();
         assertEquals(srvccState, mSrvccState);
 
@@ -357,82 +322,6 @@
     }
 
     /**
-     * Test that we first receive a callback when listen(...) is called that contains the latest
-     * notify(...) response and then that the callback is called correctly when notify(...) is
-     * called.
-     */
-    @Test
-    @SmallTest
-    public void testSrvccStateChangedWithRenouncedLocationAccess() throws Exception {
-        // Return a slotIndex / phoneId of 0 for all sub ids given.
-        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
-        doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
-        int srvccState = TelephonyManager.SRVCC_STATE_HANDOVER_STARTED;
-        int[] events = {TelephonyCallback.EVENT_SRVCC_STATE_CHANGED};
-        mTelephonyRegistry.notifySrvccStateChanged(1 /*subId*/, srvccState);
-        // Should receive callback when listen is called that contains the latest notify result.
-        mTelephonyRegistry.listenWithEventList(true, true, 1 /*subId*/,
-                mContext.getOpPackageName(), mContext.getAttributionTag(),
-                mTelephonyCallback.callback, events, true);
-        processAllMessages();
-        assertEquals(srvccState, mSrvccState);
-        assertServiceStateForLocationAccessSanitization(mServiceState);
-
-        // trigger callback
-        srvccState = TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED;
-        mTelephonyRegistry.notifySrvccStateChanged(1 /*subId*/, srvccState);
-        processAllMessages();
-        assertEquals(srvccState, mSrvccState);
-    }
-
-    /**
-     * Test that we first receive a callback when listen(...) is called that contains the latest
-     * notify(...) response and then that the callback is called correctly when notify(...) is
-     * called.
-     */
-    @Test
-    @SmallTest
-    public void testSrvccStateChangedWithRenouncedFineLocationAccess() throws Exception {
-        // Return a slotIndex / phoneId of 0 for all sub ids given.
-        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
-        doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
-        int srvccState = TelephonyManager.SRVCC_STATE_HANDOVER_STARTED;
-        int[] events = {TelephonyCallback.EVENT_SRVCC_STATE_CHANGED};
-        mTelephonyRegistry.notifySrvccStateChanged(1 /*subId*/, srvccState);
-        // Should receive callback when listen is called that contains the latest notify result.
-        mTelephonyRegistry.listenWithEventList(false, true, 1 /*subId*/,
-                mContext.getOpPackageName(), mContext.getAttributionTag(),
-                mTelephonyCallback.callback, events, true);
-        processAllMessages();
-        assertEquals(srvccState, mSrvccState);
-        assertServiceStateForFineAccessSanitization(mServiceState);
-
-        // trigger callback
-        srvccState = TelephonyManager.SRVCC_STATE_HANDOVER_COMPLETED;
-        mTelephonyRegistry.notifySrvccStateChanged(1 /*subId*/, srvccState);
-        processAllMessages();
-        assertEquals(srvccState, mSrvccState);
-    }
-
-    private void assertServiceStateForFineAccessSanitization(ServiceState state) {
-        if (state == null) return;
-
-        if (state.getNetworkRegistrationInfoList() != null) {
-            for (NetworkRegistrationInfo nrs : state.getNetworkRegistrationInfoList()) {
-                assertEquals(nrs.getCellIdentity(), null);
-            }
-        }
-    }
-
-    private void assertServiceStateForLocationAccessSanitization(ServiceState state) {
-        if (state == null) return;
-        assertServiceStateForFineAccessSanitization(state);
-        assertEquals(TextUtils.isEmpty(state.getOperatorAlphaLong()), true);
-        assertEquals(TextUtils.isEmpty(state.getOperatorAlphaShort()), true);
-        assertEquals(TextUtils.isEmpty(state.getOperatorNumeric()), true);
-    }
-
-    /**
      * Test that a SecurityException is thrown when we try to listen to a SRVCC state change without
      * READ_PRIVILEGED_PHONE_STATE.
      */
@@ -445,9 +334,8 @@
         int[] events = {TelephonyCallback.EVENT_SRVCC_STATE_CHANGED};
         mTelephonyRegistry.notifySrvccStateChanged(0 /*subId*/, srvccState);
         try {
-            mTelephonyRegistry.listenWithEventList(false, false, 0 /*subId*/,
-                    mContext.getOpPackageName(), mContext.getAttributionTag(),
-                    mTelephonyCallback.callback, events, true);
+            mTelephonyRegistry.listenWithEventList(0 /*subId*/, mContext.getOpPackageName(),
+                    mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
             fail();
         } catch (SecurityException e) {
             // pass test!
@@ -460,7 +348,7 @@
     @Test
     public void testMultiSimConfigChange() {
         int[] events = {TelephonyCallback.EVENT_RADIO_POWER_STATE_CHANGED};
-        mTelephonyRegistry.listenWithEventList(false, false, 1, mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithEventList(1, mContext.getOpPackageName(),
                 mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
         processAllMessages();
         assertEquals(RADIO_POWER_UNAVAILABLE, mRadioPowerState);
@@ -486,285 +374,6 @@
     }
 
     /**
-     * Test {@link TelephonyCallback.DataConnectionStateListener}
-     */
-    @Test
-    public void testDataConnectionStateChanged() {
-        final int subId = 1;
-        int[] events = {TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED};
-        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
-        doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
-
-        assertEquals(TelephonyManager.DATA_UNKNOWN, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, mNetworkType);
-
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*phoneId*/ 0, subId,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_CONNECTED)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
-                                .setApnName("default")
-                                .setEntryName("default")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-        mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
-                mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
-
-        assertEquals(TelephonyManager.DATA_CONNECTED, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mNetworkType);
-
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*phoneId*/ 0, subId,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_DISCONNECTING)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
-                                .setApnName("default")
-                                .setEntryName("default")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-
-        assertEquals(TelephonyManager.DATA_DISCONNECTING, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mNetworkType);
-
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*phoneId*/ 0, subId,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_DISCONNECTED)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
-                                .setApnName("default")
-                                .setEntryName("default")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-
-        assertEquals(TelephonyManager.DATA_DISCONNECTED, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mNetworkType);
-    }
-
-    /**
-     * Test the scenario that multiple PDNs support default type APN scenario. Make sure it reports
-     * aggregate data connection state.
-     */
-    @Test
-    public void testDataConnectionStateChangedMultipleInternet() {
-        final int subId = 1;
-        int[] events = {TelephonyCallback.EVENT_DATA_CONNECTION_STATE_CHANGED};
-        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
-        doReturn(0/*slotIndex*/).when(mMockSubInfo).getSimSlotIndex();
-
-        assertEquals(TelephonyManager.DATA_UNKNOWN, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, mNetworkType);
-
-        mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
-                mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
-
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*phoneId*/ 0, subId,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_CONNECTED)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
-                                .setApnName("default")
-                                .setEntryName("default")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-
-        assertEquals(TelephonyManager.DATA_CONNECTED, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mNetworkType);
-
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*phoneId*/ 0, subId,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_CONNECTING)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
-                                .setApnName("default+mms")
-                                .setEntryName("default+mms")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-
-        assertEquals(TelephonyManager.DATA_CONNECTED, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mNetworkType);
-
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*phoneId*/ 0, subId,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_DISCONNECTING)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
-                                .setApnName("default+mms")
-                                .setEntryName("default+mms")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-        assertEquals(TelephonyManager.DATA_CONNECTED, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mNetworkType);
-
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*phoneId*/ 0, subId,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_DISCONNECTED)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
-                                .setApnName("default+mms")
-                                .setEntryName("default+mms")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-        assertEquals(TelephonyManager.DATA_CONNECTED, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mNetworkType);
-
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*phoneId*/ 0, subId,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_CONNECTING)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
-                                .setApnName("default+mms")
-                                .setEntryName("default+mms")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-
-        assertEquals(TelephonyManager.DATA_CONNECTED, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mNetworkType);
-
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*phoneId*/ 0, subId,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_CONNECTED)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
-                                .setApnName("default+mms")
-                                .setEntryName("default+mms")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-
-        assertEquals(TelephonyManager.DATA_CONNECTED, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mNetworkType);
-
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*phoneId*/ 0, subId,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_DISCONNECTING)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
-                                .setApnName("default")
-                                .setEntryName("default")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-
-        assertEquals(TelephonyManager.DATA_CONNECTED, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mNetworkType);
-
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*phoneId*/ 0, subId,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_DISCONNECTING)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
-                                .setApnName("default+mms")
-                                .setEntryName("default+mms")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-
-        assertEquals(TelephonyManager.DATA_DISCONNECTING, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mNetworkType);
-
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*phoneId*/ 0, subId,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_DISCONNECTED)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
-                                .setApnName("default")
-                                .setEntryName("default")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-
-        assertEquals(TelephonyManager.DATA_DISCONNECTING, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mNetworkType);
-
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*phoneId*/ 0, subId,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_DISCONNECTED)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
-                                .setApnName("default+mms")
-                                .setEntryName("default+mms")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-
-        assertEquals(TelephonyManager.DATA_DISCONNECTED, mDataConnectionState);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mNetworkType);
-    }
-
-    /**
      * Test multi sim config change.
      */
     @Test
@@ -789,7 +398,7 @@
                         .setLinkProperties(new LinkProperties())
                         .setFailCause(0)
                         .build());
-        mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithEventList(subId, mContext.getOpPackageName(),
                 mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
         processAllMessages();
         // Verify that the PDCS is reported for the only APN
@@ -816,12 +425,12 @@
         assertEquals(mTelephonyCallback.invocationCount.get(), 2);
 
         // Unregister the listener
-        mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithEventList(subId, mContext.getOpPackageName(),
                 mContext.getAttributionTag(), mTelephonyCallback.callback, new int[0], true);
         processAllMessages();
 
         // Re-register the listener and ensure that both APN types are reported
-        mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithEventList(subId, mContext.getOpPackageName(),
                 mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
         processAllMessages();
         assertEquals(4, mTelephonyCallback.invocationCount.get());
@@ -866,7 +475,7 @@
         configs.add(config);
 
         mTelephonyRegistry.notifyPhysicalChannelConfigForSubscriber(0, subId, configs);
-        mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithEventList(subId, mContext.getOpPackageName(),
                 mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
         processAllMessages();
 
@@ -1005,7 +614,7 @@
                 .putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 0));
         processAllMessages();
         int[] events = {TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED};
-        mTelephonyRegistry.listenWithEventList(false, false, 2, mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithEventList(2, mContext.getOpPackageName(),
                 mContext.getAttributionTag(), mTelephonyCallback.callback, events, false);
         when(mMockConfigurationProvider.isDisplayInfoNrAdvancedSupported(
                 anyString(), any())).thenReturn(true);
@@ -1031,7 +640,7 @@
                 .putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 0));
         processAllMessages();
         int[] events = {TelephonyCallback.EVENT_DISPLAY_INFO_CHANGED};
-        mTelephonyRegistry.listenWithEventList(false, false, 2, mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithEventList(2, mContext.getOpPackageName(),
                 mContext.getAttributionTag(), mTelephonyCallback.callback, events, false);
         when(mMockConfigurationProvider.isDisplayInfoNrAdvancedSupported(
                 anyString(), any())).thenReturn(false);
@@ -1079,9 +688,9 @@
             }
         };
         telephonyCallback2.init(mSimpleExecutor2);
-        mTelephonyRegistry.listenWithEventList(false, false, 2, "pkg1",
+        mTelephonyRegistry.listenWithEventList(2, "pkg1",
                 mContext.getAttributionTag(), mTelephonyCallback.callback, events, false);
-        mTelephonyRegistry.listenWithEventList(false, false, 2, "pkg2",
+        mTelephonyRegistry.listenWithEventList(2, "pkg2",
                 mContext.getAttributionTag(), telephonyCallback2.callback, events, false);
         when(mMockConfigurationProvider.isDisplayInfoNrAdvancedSupported(
                 eq("pkg1"), any())).thenReturn(false);
@@ -1125,7 +734,7 @@
 
         // Listen to EVENT_CELL_LOCATION_CHANGED for the current user Id.
         int[] events = {TelephonyCallback.EVENT_CELL_LOCATION_CHANGED};
-        mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithEventList(subId, mContext.getOpPackageName(),
                 mContext.getAttributionTag(), mTelephonyCallback.callback, events, false);
 
         // Broadcast ACTION_USER_SWITCHED for USER_SYSTEM. Callback should be triggered.
@@ -1149,9 +758,8 @@
     private void assertSecurityExceptionThrown(int[] event) {
         try {
             mTelephonyRegistry.listenWithEventList(
-                    false, false, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
-                    mContext.getOpPackageName(), mContext.getAttributionTag(),
-                    mTelephonyCallback.callback, event, true);
+                    SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, mContext.getOpPackageName(),
+                    mContext.getAttributionTag(), mTelephonyCallback.callback, event, true);
             fail("SecurityException should throw without permission");
         } catch (SecurityException expected) {
         }
@@ -1160,9 +768,8 @@
     private void assertSecurityExceptionNotThrown(int[] event) {
         try {
             mTelephonyRegistry.listenWithEventList(
-                    false, false, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
-                    mContext.getOpPackageName(), mContext.getAttributionTag(),
-                    mTelephonyCallback.callback, event, true);
+                    SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, mContext.getOpPackageName(),
+                    mContext.getAttributionTag(), mTelephonyCallback.callback, event, true);
         } catch (SecurityException unexpected) {
             fail("SecurityException thrown with permission");
         }
@@ -1175,7 +782,7 @@
                 .putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 0));
         processAllMessages();
         int[] events = {TelephonyCallback.EVENT_LINK_CAPACITY_ESTIMATE_CHANGED};
-        mTelephonyRegistry.listenWithEventList(false, false, 2, mContext.getOpPackageName(),
+        mTelephonyRegistry.listenWithEventList(2, mContext.getOpPackageName(),
                 mContext.getAttributionTag(), mTelephonyCallback.callback,
                 events, false);
 
@@ -1197,67 +804,4 @@
         processAllMessages();
         assertEquals(lceList, mLinkCapacityEstimateList);
     }
-
-    @Test
-    public void testPreciseDataConnectionStateChangedForInvalidSubId() {
-        //set dual sim
-        doReturn(2).when(mTelephonyManager).getActiveModemCount();
-        mContext.sendBroadcast(new Intent(ACTION_MULTI_SIM_CONFIG_CHANGED));
-        // set default slot
-        mContext.sendBroadcast(new Intent(ACTION_DEFAULT_SUBSCRIPTION_CHANGED)
-                .putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, 2)
-                .putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 0));
-        processAllMessages();
-
-        final int subId = 1;
-        int[] events = {TelephonyCallback.EVENT_PRECISE_DATA_CONNECTION_STATE_CHANGED};
-        doReturn(mMockSubInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
-        doReturn(1).when(mMockSubInfo).getSimSlotIndex();
-
-        mTelephonyRegistry.listenWithEventList(false, false, subId, mContext.getOpPackageName(),
-                mContext.getAttributionTag(), mTelephonyCallback.callback, events, true);
-        processAllMessages();
-
-        // notify data connection with invalid sub id and default phone id
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*default phoneId*/ 0, /*invalid subId*/ -1,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(1)
-                        .setState(TelephonyManager.DATA_CONNECTED)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_IMS)
-                                .setApnName("ims")
-                                .setEntryName("ims")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-
-        processAllMessages();
-
-        assertEquals(0, mTelephonyCallback.invocationCount.get());
-
-        // notify data connection with invalid sub id and default phone id
-        mTelephonyRegistry.notifyDataConnectionForSubscriber(
-                /*target phoneId*/ 1, /*invalid subId*/ -1,
-                new PreciseDataConnectionState.Builder()
-                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setId(2)
-                        .setState(TelephonyManager.DATA_SUSPENDED)
-                        .setNetworkType(TelephonyManager.NETWORK_TYPE_LTE)
-                        .setApnSetting(new ApnSetting.Builder()
-                                .setApnTypeBitmask(ApnSetting.TYPE_IMS)
-                                .setApnName("ims")
-                                .setEntryName("ims")
-                                .build())
-                        .setLinkProperties(new LinkProperties())
-                        .setFailCause(0)
-                        .build());
-
-        processAllMessages();
-
-        assertEquals(1, mTelephonyCallback.invocationCount.get());
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
index 9b54b19..2242d55 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java
@@ -27,27 +27,23 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.spy;
 
 import android.app.ActivityManager;
 import android.app.AppOpsManager;
 import android.app.IActivityManager;
 import android.app.KeyguardManager;
 import android.app.usage.NetworkStatsManager;
-import android.content.ContentProvider;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.IIntentSender;
 import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.location.LocationManager;
 import android.net.ConnectivityManager;
 import android.net.NetworkCapabilities;
-import android.net.NetworkPolicyManager;
 import android.net.vcn.VcnManager;
 import android.net.vcn.VcnNetworkPolicyResult;
 import android.net.wifi.WifiInfo;
@@ -61,13 +57,11 @@
 import android.os.MessageQueue;
 import android.os.RegistrantList;
 import android.os.ServiceManager;
-import android.os.StrictMode;
 import android.os.UserManager;
 import android.permission.LegacyPermissionManager;
 import android.provider.BlockedNumberContract;
 import android.provider.DeviceConfig;
 import android.provider.Settings;
-import android.provider.Telephony;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.CarrierConfigManager;
 import android.telephony.CellIdentity;
@@ -76,7 +70,6 @@
 import android.telephony.ServiceState;
 import android.telephony.SignalStrength;
 import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyDisplayInfo;
 import android.telephony.TelephonyManager;
 import android.telephony.TelephonyRegistryManager;
 import android.telephony.emergency.EmergencyNumber;
@@ -93,19 +86,12 @@
 import com.android.ims.ImsManager;
 import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
 import com.android.internal.telephony.cdma.EriManager;
-import com.android.internal.telephony.data.AccessNetworksManager;
-import com.android.internal.telephony.data.CellularNetworkValidator;
-import com.android.internal.telephony.data.DataConfigManager;
-import com.android.internal.telephony.data.DataEnabledOverride;
-import com.android.internal.telephony.data.DataNetworkController;
-import com.android.internal.telephony.data.DataProfileManager;
-import com.android.internal.telephony.data.DataRetryManager;
-import com.android.internal.telephony.data.DataServiceManager;
-import com.android.internal.telephony.data.DataSettingsManager;
-import com.android.internal.telephony.data.LinkBandwidthEstimator;
+import com.android.internal.telephony.dataconnection.DataEnabledOverride;
 import com.android.internal.telephony.dataconnection.DataEnabledSettings;
 import com.android.internal.telephony.dataconnection.DataThrottler;
 import com.android.internal.telephony.dataconnection.DcTracker;
+import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator;
+import com.android.internal.telephony.dataconnection.TransportManager;
 import com.android.internal.telephony.emergency.EmergencyNumberTracker;
 import com.android.internal.telephony.imsphone.ImsExternalCallTracker;
 import com.android.internal.telephony.imsphone.ImsPhone;
@@ -126,12 +112,14 @@
 import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccCardApplication;
 import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UiccProfile;
 import com.android.internal.telephony.uicc.UiccSlot;
+import com.android.server.pm.PackageManagerService;
 import com.android.server.pm.permission.LegacyPermissionManagerService;
 
+import org.mockito.Mock;
 import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
@@ -176,98 +164,175 @@
         }
     }
 
-    // Mocked classes
+    @Mock
     protected GsmCdmaPhone mPhone;
+    @Mock
     protected ImsPhone mImsPhone;
+    @Mock
     protected ServiceStateTracker mSST;
+    @Mock
     protected EmergencyNumberTracker mEmergencyNumberTracker;
+    @Mock
     protected GsmCdmaCallTracker mCT;
+    @Mock
     protected ImsPhoneCallTracker mImsCT;
+    @Mock
     protected UiccController mUiccController;
+    @Mock
     protected UiccProfile mUiccProfile;
+    @Mock
     protected CallManager mCallManager;
+    @Mock
     protected PhoneNotifier mNotifier;
+    @Mock
     protected TelephonyComponentFactory mTelephonyComponentFactory;
+    @Mock
     protected CdmaSubscriptionSourceManager mCdmaSSM;
+    @Mock
     protected RegistrantList mRegistrantList;
+    @Mock
     protected IccPhoneBookInterfaceManager mIccPhoneBookIntManager;
+    @Mock
     protected ImsManager mImsManager;
+    @Mock
     protected DcTracker mDcTracker;
-    protected DataNetworkController mDataNetworkController;
-    protected DataRetryManager mDataRetryManager;
-    protected DataSettingsManager mDataSettingsManager;
-    protected DataConfigManager mDataConfigManager;
-    protected DataProfileManager mDataProfileManager;
+    @Mock
     protected DisplayInfoController mDisplayInfoController;
+    @Mock
     protected GsmCdmaCall mGsmCdmaCall;
+    @Mock
     protected ImsCall mImsCall;
+    @Mock
     protected ImsEcbm mImsEcbm;
+    @Mock
     protected SubscriptionController mSubscriptionController;
+    @Mock
     protected ServiceState mServiceState;
-    protected IPackageManager.Stub mMockPackageManager;
+    @Mock
+    protected PackageManagerService mMockPackageManager;
+    @Mock
     protected LegacyPermissionManagerService mMockLegacyPermissionManager;
-    protected SimulatedCommandsVerifier mSimulatedCommandsVerifier;
-    protected InboundSmsHandler mInboundSmsHandler;
-    protected WspTypeDecoder mWspTypeDecoder;
-    protected UiccCardApplication mUiccCardApplication3gpp;
-    protected UiccCardApplication mUiccCardApplication3gpp2;
-    protected UiccCardApplication mUiccCardApplicationIms;
-    protected SIMRecords mSimRecords;
-    protected RuimRecords mRuimRecords;
-    protected IsimUiccRecords mIsimUiccRecords;
-    protected ProxyController mProxyController;
-    protected Singleton<IActivityManager> mIActivityManagerSingleton;
-    protected IActivityManager mIActivityManager;
-    protected IIntentSender mIIntentSender;
-    protected IBinder mIBinder;
-    protected SmsStorageMonitor mSmsStorageMonitor;
-    protected SmsUsageMonitor mSmsUsageMonitor;
-    protected PackageInfo mPackageInfo;
-    protected ApplicationInfo mApplicationInfo;
-    protected EriManager mEriManager;
-    protected IBinder mConnMetLoggerBinder;
-    protected CarrierSignalAgent mCarrierSignalAgent;
-    protected CarrierActionAgent mCarrierActionAgent;
-    protected ImsExternalCallTracker mImsExternalCallTracker;
-    protected AppSmsManager mAppSmsManager;
-    protected IccSmsInterfaceManager mIccSmsInterfaceManager;
-    protected SmsDispatchersController mSmsDispatchersController;
-    protected DeviceStateMonitor mDeviceStateMonitor;
-    protected AccessNetworksManager mAccessNetworksManager;
-    protected IntentBroadcaster mIntentBroadcaster;
-    protected NitzStateMachine mNitzStateMachine;
-    protected RadioConfig mMockRadioConfig;
-    protected SubscriptionInfoUpdater mSubInfoRecordUpdater;
-    protected LocaleTracker mLocaleTracker;
-    protected RestrictedState mRestrictedState;
-    protected DataEnabledSettings mDataEnabledSettings;
-    protected DataEnabledOverride mDataEnabledOverride;
-    protected PhoneConfigurationManager mPhoneConfigurationManager;
-    protected CellularNetworkValidator mCellularNetworkValidator;
-    protected UiccCard mUiccCard;
-    protected UiccPort mUiccPort;
-    protected MultiSimSettingController mMultiSimSettingController;
-    protected IccCard mIccCard;
-    protected NetworkStatsManager mStatsManager;
-    protected CarrierPrivilegesTracker mCarrierPrivilegesTracker;
-    protected VoiceCallSessionStats mVoiceCallSessionStats;
-    protected PersistAtomsStorage mPersistAtomsStorage;
-    protected MetricsCollector mMetricsCollector;
-    protected SmsStats mSmsStats;
-    protected DataThrottler mDataThrottler;
-    protected SignalStrength mSignalStrength;
-    protected WifiManager mWifiManager;
-    protected WifiInfo mWifiInfo;
-    protected ImsStats mImsStats;
-    protected LinkBandwidthEstimator mLinkBandwidthEstimator;
-    protected PinStorage mPinStorage;
-    protected LocationManager mLocationManager;
-    protected CellIdentity mCellIdentity;
-    protected CellLocation mCellLocation;
-    protected DataServiceManager mMockedWwanDataServiceManager;
-    protected DataServiceManager mMockedWlanDataServiceManager;
 
-    // Initialized classes
+    protected NetworkRegistrationInfo mNetworkRegistrationInfo =
+            new NetworkRegistrationInfo.Builder()
+            .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
+            .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
+            .build();
+    @Mock
+    protected SimulatedCommandsVerifier mSimulatedCommandsVerifier;
+    @Mock
+    protected InboundSmsHandler mInboundSmsHandler;
+    @Mock
+    protected WspTypeDecoder mWspTypeDecoder;
+    @Mock
+    protected UiccCardApplication mUiccCardApplication3gpp;
+    @Mock
+    protected UiccCardApplication mUiccCardApplication3gpp2;
+    @Mock
+    protected UiccCardApplication mUiccCardApplicationIms;
+    @Mock
+    protected SIMRecords mSimRecords;
+    @Mock
+    protected RuimRecords mRuimRecords;
+    @Mock
+    protected IsimUiccRecords mIsimUiccRecords;
+    @Mock
+    protected ProxyController mProxyController;
+    @Mock
+    protected Singleton<IActivityManager> mIActivityManagerSingleton;
+    @Mock
+    protected IActivityManager mIActivityManager;
+    @Mock
+    protected IIntentSender mIIntentSender;
+    @Mock
+    protected IBinder mIBinder;
+    @Mock
+    protected SmsStorageMonitor mSmsStorageMonitor;
+    @Mock
+    protected SmsUsageMonitor mSmsUsageMonitor;
+    @Mock
+    protected PackageInfo mPackageInfo;
+    @Mock
+    protected ApplicationInfo mApplicationInfo;
+    @Mock
+    protected EriManager mEriManager;
+    @Mock
+    protected IBinder mConnMetLoggerBinder;
+    @Mock
+    protected CarrierSignalAgent mCarrierSignalAgent;
+    @Mock
+    protected CarrierActionAgent mCarrierActionAgent;
+    @Mock
+    protected ImsExternalCallTracker mImsExternalCallTracker;
+    @Mock
+    protected AppSmsManager mAppSmsManager;
+    @Mock
+    protected IccSmsInterfaceManager mIccSmsInterfaceManager;
+    @Mock
+    protected SmsDispatchersController mSmsDispatchersController;
+    @Mock
+    protected DeviceStateMonitor mDeviceStateMonitor;
+    @Mock
+    protected TransportManager mTransportManager;
+    @Mock
+    protected IntentBroadcaster mIntentBroadcaster;
+    @Mock
+    protected NitzStateMachine mNitzStateMachine;
+    @Mock
+    protected RadioConfig mMockRadioConfig;
+    @Mock
+    protected SubscriptionInfoUpdater mSubInfoRecordUpdater;
+    @Mock
+    protected LocaleTracker mLocaleTracker;
+    @Mock
+    protected RestrictedState mRestrictedState;
+    @Mock
+    protected DataEnabledSettings mDataEnabledSettings;
+    @Mock
+    protected DataEnabledOverride mDataEnabledOverride;
+    @Mock
+    protected PhoneConfigurationManager mPhoneConfigurationManager;
+    @Mock
+    protected CellularNetworkValidator mCellularNetworkValidator;
+    @Mock
+    protected UiccCard mUiccCard;
+    @Mock
+    protected MultiSimSettingController mMultiSimSettingController;
+    @Mock
+    protected IccCard mIccCard;
+    @Mock
+    protected NetworkStatsManager mStatsManager;
+    @Mock
+    protected CarrierPrivilegesTracker mCarrierPrivilegesTracker;
+    @Mock
+    protected VoiceCallSessionStats mVoiceCallSessionStats;
+    @Mock
+    protected PersistAtomsStorage mPersistAtomsStorage;
+    @Mock
+    protected MetricsCollector mMetricsCollector;
+    @Mock
+    protected SmsStats mSmsStats;
+    @Mock
+    protected DataThrottler mDataThrottler;
+    @Mock
+    protected SignalStrength mSignalStrength;
+    @Mock
+    protected WifiManager mWifiManager;
+    @Mock
+    protected WifiInfo mWifiInfo;
+    @Mock
+    protected ImsStats mImsStats;
+    @Mock
+    protected LinkBandwidthEstimator mLinkBandwidthEstimator;
+    @Mock
+    protected PinStorage mPinStorage;
+    @Mock
+    protected LocationManager mLocationManager;
+    @Mock
+    protected CellIdentity mCellIdentity;
+    @Mock
+    protected CellLocation mCellLocation;
+
     protected ActivityManager mActivityManager;
     protected ImsCallProfile mImsCallProfile;
     protected TelephonyManager mTelephonyManager;
@@ -281,27 +346,20 @@
     protected UserManager mUserManager;
     protected KeyguardManager mKeyguardManager;
     protected VcnManager mVcnManager;
-    protected NetworkPolicyManager mNetworkPolicyManager;
     protected SimulatedCommands mSimulatedCommands;
     protected ContextFixture mContextFixture;
     protected Context mContext;
     protected FakeBlockedNumberContentProvider mFakeBlockedNumberContentProvider;
-    private final ContentProvider mContentProvider = spy(new ContextFixture.FakeContentProvider());
     private Object mLock = new Object();
     private boolean mReady;
     protected HashMap<String, IBinder> mServiceManagerMockedServices = new HashMap<>();
     protected Phone[] mPhones;
-    protected NetworkRegistrationInfo mNetworkRegistrationInfo =
-            new NetworkRegistrationInfo.Builder()
-                    .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
-                    .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                    .build();
     protected List<TestableLooper> mTestableLoopers = new ArrayList<>();
     protected TestableLooper mTestableLooper;
 
-    private final HashMap<InstanceKey, Object> mOldInstances = new HashMap<>();
+    private HashMap<InstanceKey, Object> mOldInstances = new HashMap<InstanceKey, Object>();
 
-    private final LinkedList<InstanceKey> mInstanceKeys = new LinkedList<>();
+    private LinkedList<InstanceKey> mInstanceKeys = new LinkedList<InstanceKey>();
 
     private class InstanceKey {
         public final Class mClass;
@@ -392,114 +450,9 @@
         mOldInstances.clear();
     }
 
-    // TODO: Unit tests that do not extend TelephonyTest or ImsTestBase should enable strict mode
-    //   by calling this method.
-    public static void enableStrictMode() {
-        StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
-                .detectLeakedSqlLiteObjects()
-                .detectLeakedClosableObjects()
-                .detectIncorrectContextUse()
-                .detectLeakedRegistrationObjects()
-                .detectUnsafeIntentLaunch()
-                .detectActivityLeaks()
-                .penaltyLog()
-                .penaltyDeath()
-                .build());
-    }
-
     protected void setUp(String tag) throws Exception {
         TAG = tag;
-        enableStrictMode();
-        mPhone = Mockito.mock(GsmCdmaPhone.class);
-        mImsPhone = Mockito.mock(ImsPhone.class);
-        mSST = Mockito.mock(ServiceStateTracker.class);
-        mEmergencyNumberTracker = Mockito.mock(EmergencyNumberTracker.class);
-        mCT = Mockito.mock(GsmCdmaCallTracker.class);
-        mImsCT = Mockito.mock(ImsPhoneCallTracker.class);
-        mUiccController = Mockito.mock(UiccController.class);
-        mUiccProfile = Mockito.mock(UiccProfile.class);
-        mCallManager = Mockito.mock(CallManager.class);
-        mNotifier = Mockito.mock(PhoneNotifier.class);
-        mTelephonyComponentFactory = Mockito.mock(TelephonyComponentFactory.class);
-        mCdmaSSM = Mockito.mock(CdmaSubscriptionSourceManager.class);
-        mRegistrantList = Mockito.mock(RegistrantList.class);
-        mIccPhoneBookIntManager = Mockito.mock(IccPhoneBookInterfaceManager.class);
-        mImsManager = Mockito.mock(ImsManager.class);
-        mDcTracker = Mockito.mock(DcTracker.class);
-        mDataNetworkController = Mockito.mock(DataNetworkController.class);
-        mDataRetryManager = Mockito.mock(DataRetryManager.class);
-        mDataSettingsManager = Mockito.mock(DataSettingsManager.class);
-        mDataConfigManager = Mockito.mock(DataConfigManager.class);
-        mDataProfileManager = Mockito.mock(DataProfileManager.class);
-        mDisplayInfoController = Mockito.mock(DisplayInfoController.class);
-        mGsmCdmaCall = Mockito.mock(GsmCdmaCall.class);
-        mImsCall = Mockito.mock(ImsCall.class);
-        mImsEcbm = Mockito.mock(ImsEcbm.class);
-        mSubscriptionController = Mockito.mock(SubscriptionController.class);
-        mServiceState = Mockito.mock(ServiceState.class);
-        mMockPackageManager = Mockito.mock(IPackageManager.Stub.class);
-        mMockLegacyPermissionManager = Mockito.mock(LegacyPermissionManagerService.class);
-        mSimulatedCommandsVerifier = Mockito.mock(SimulatedCommandsVerifier.class);
-        mInboundSmsHandler = Mockito.mock(InboundSmsHandler.class);
-        mWspTypeDecoder = Mockito.mock(WspTypeDecoder.class);
-        mUiccCardApplication3gpp = Mockito.mock(UiccCardApplication.class);
-        mUiccCardApplication3gpp2 = Mockito.mock(UiccCardApplication.class);
-        mUiccCardApplicationIms = Mockito.mock(UiccCardApplication.class);
-        mSimRecords = Mockito.mock(SIMRecords.class);
-        mRuimRecords = Mockito.mock(RuimRecords.class);
-        mIsimUiccRecords = Mockito.mock(IsimUiccRecords.class);
-        mProxyController = Mockito.mock(ProxyController.class);
-        mIActivityManagerSingleton = Mockito.mock(Singleton.class);
-        mIActivityManager = Mockito.mock(IActivityManager.class);
-        mIIntentSender = Mockito.mock(IIntentSender.class);
-        mIBinder = Mockito.mock(IBinder.class);
-        mSmsStorageMonitor = Mockito.mock(SmsStorageMonitor.class);
-        mSmsUsageMonitor = Mockito.mock(SmsUsageMonitor.class);
-        mPackageInfo = Mockito.mock(PackageInfo.class);
-        mApplicationInfo = Mockito.mock(ApplicationInfo.class);
-        mEriManager = Mockito.mock(EriManager.class);
-        mConnMetLoggerBinder = Mockito.mock(IBinder.class);
-        mCarrierSignalAgent = Mockito.mock(CarrierSignalAgent.class);
-        mCarrierActionAgent = Mockito.mock(CarrierActionAgent.class);
-        mImsExternalCallTracker = Mockito.mock(ImsExternalCallTracker.class);
-        mAppSmsManager = Mockito.mock(AppSmsManager.class);
-        mIccSmsInterfaceManager = Mockito.mock(IccSmsInterfaceManager.class);
-        mSmsDispatchersController = Mockito.mock(SmsDispatchersController.class);
-        mDeviceStateMonitor = Mockito.mock(DeviceStateMonitor.class);
-        mAccessNetworksManager = Mockito.mock(AccessNetworksManager.class);
-        mIntentBroadcaster = Mockito.mock(IntentBroadcaster.class);
-        mNitzStateMachine = Mockito.mock(NitzStateMachine.class);
-        mMockRadioConfig = Mockito.mock(RadioConfig.class);
-        mSubInfoRecordUpdater = Mockito.mock(SubscriptionInfoUpdater.class);
-        mLocaleTracker = Mockito.mock(LocaleTracker.class);
-        mRestrictedState = Mockito.mock(RestrictedState.class);
-        mDataEnabledSettings = Mockito.mock(DataEnabledSettings.class);
-        mDataEnabledOverride = Mockito.mock(DataEnabledOverride.class);
-        mPhoneConfigurationManager = Mockito.mock(PhoneConfigurationManager.class);
-        mCellularNetworkValidator = Mockito.mock(CellularNetworkValidator.class);
-        mUiccCard = Mockito.mock(UiccCard.class);
-        mUiccPort = Mockito.mock(UiccPort.class);
-        mMultiSimSettingController = Mockito.mock(MultiSimSettingController.class);
-        mIccCard = Mockito.mock(IccCard.class);
-        mStatsManager = Mockito.mock(NetworkStatsManager.class);
-        mCarrierPrivilegesTracker = Mockito.mock(CarrierPrivilegesTracker.class);
-        mVoiceCallSessionStats = Mockito.mock(VoiceCallSessionStats.class);
-        mPersistAtomsStorage = Mockito.mock(PersistAtomsStorage.class);
-        mMetricsCollector = Mockito.mock(MetricsCollector.class);
-        mSmsStats = Mockito.mock(SmsStats.class);
-        mDataThrottler = Mockito.mock(DataThrottler.class);
-        mSignalStrength = Mockito.mock(SignalStrength.class);
-        mWifiManager = Mockito.mock(WifiManager.class);
-        mWifiInfo = Mockito.mock(WifiInfo.class);
-        mImsStats = Mockito.mock(ImsStats.class);
-        mLinkBandwidthEstimator = Mockito.mock(LinkBandwidthEstimator.class);
-        mPinStorage = Mockito.mock(PinStorage.class);
-        mLocationManager = Mockito.mock(LocationManager.class);
-        mCellIdentity = Mockito.mock(CellIdentity.class);
-        mCellLocation = Mockito.mock(CellLocation.class);
-        mMockedWwanDataServiceManager = Mockito.mock(DataServiceManager.class);
-        mMockedWlanDataServiceManager = Mockito.mock(DataServiceManager.class);
-
+        MockitoAnnotations.initMocks(this);
         TelephonyManager.disableServiceHandleCaching();
         SubscriptionController.disableCaching();
         // For testing do not allow Log.WTF as it can cause test process to crash
@@ -516,19 +469,10 @@
         mFakeBlockedNumberContentProvider = new FakeBlockedNumberContentProvider();
         ((MockContentResolver)mContext.getContentResolver()).addProvider(
                 BlockedNumberContract.AUTHORITY, mFakeBlockedNumberContentProvider);
-        ((MockContentResolver) mContext.getContentResolver()).addProvider(
-                Settings.AUTHORITY, mContentProvider);
-        ((MockContentResolver) mContext.getContentResolver()).addProvider(
-                Telephony.ServiceStateTable.AUTHORITY, mContentProvider);
-        replaceContentProvider(mContentProvider);
-
-        Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0);
-
         mPhone.mCi = mSimulatedCommands;
         mCT.mCi = mSimulatedCommands;
         doReturn(mUiccCard).when(mPhone).getUiccCard();
-        doReturn(mUiccPort).when(mPhone).getUiccPort();
-        doReturn(mUiccProfile).when(mUiccPort).getUiccProfile();
+        doReturn(mUiccProfile).when(mUiccCard).getUiccProfile();
 
         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
         mActivityManager = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
@@ -546,7 +490,6 @@
         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
         mKeyguardManager = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
         mVcnManager = mContext.getSystemService(VcnManager.class);
-        mNetworkPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
         mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
 
         //mTelephonyComponentFactory
@@ -589,8 +532,8 @@
                 .makeCarrierActionAgent(nullable(Phone.class));
         doReturn(mDeviceStateMonitor).when(mTelephonyComponentFactory)
                 .makeDeviceStateMonitor(nullable(Phone.class));
-        doReturn(mAccessNetworksManager).when(mTelephonyComponentFactory)
-                .makeAccessNetworksManager(nullable(Phone.class), any(Looper.class));
+        doReturn(mTransportManager).when(mTelephonyComponentFactory)
+                .makeTransportManager(nullable(Phone.class));
         doReturn(mNitzStateMachine).when(mTelephonyComponentFactory)
                 .makeNitzStateMachine(nullable(GsmCdmaPhone.class));
         doReturn(mLocaleTracker).when(mTelephonyComponentFactory)
@@ -602,10 +545,6 @@
                 .makeEriManager(nullable(Phone.class), anyInt());
         doReturn(mLinkBandwidthEstimator).when(mTelephonyComponentFactory)
                 .makeLinkBandwidthEstimator(nullable(Phone.class));
-        doReturn(mDataProfileManager).when(mTelephonyComponentFactory)
-                .makeDataProfileManager(any(Phone.class), any(DataNetworkController.class),
-                        any(DataServiceManager.class), any(Looper.class),
-                        any(DataProfileManager.DataProfileManagerCallback.class));
 
         //mPhone
         doReturn(mContext).when(mPhone).getContext();
@@ -626,12 +565,9 @@
         doReturn(mCarrierActionAgent).when(mPhone).getCarrierActionAgent();
         doReturn(mAppSmsManager).when(mPhone).getAppSmsManager();
         doReturn(mIccSmsInterfaceManager).when(mPhone).getIccSmsInterfaceManager();
-        doReturn(mAccessNetworksManager).when(mPhone).getAccessNetworksManager();
+        doReturn(mTransportManager).when(mPhone).getTransportManager();
         doReturn(mDataEnabledSettings).when(mPhone).getDataEnabledSettings();
         doReturn(mDcTracker).when(mPhone).getDcTracker(anyInt());
-        doReturn(mDataSettingsManager).when(mDataNetworkController).getDataSettingsManager();
-        doReturn(mDataNetworkController).when(mPhone).getDataNetworkController();
-        doReturn(mDataSettingsManager).when(mPhone).getDataSettingsManager();
         doReturn(mCarrierPrivilegesTracker).when(mPhone).getCarrierPrivilegesTracker();
         doReturn(mSignalStrength).when(mPhone).getSignalStrength();
         doReturn(mVoiceCallSessionStats).when(mPhone).getVoiceCallSessionStats();
@@ -642,12 +578,6 @@
         doReturn(mLinkBandwidthEstimator).when(mPhone).getLinkBandwidthEstimator();
         doReturn(mCellIdentity).when(mPhone).getCurrentCellIdentity();
         doReturn(mCellLocation).when(mCellIdentity).asCellLocation();
-        doReturn(mDataConfigManager).when(mDataNetworkController).getDataConfigManager();
-        doReturn(mDataProfileManager).when(mDataNetworkController).getDataProfileManager();
-        doReturn(mDataRetryManager).when(mDataNetworkController).getDataRetryManager();
-        doReturn(mCarrierPrivilegesTracker).when(mPhone).getCarrierPrivilegesTracker();
-        doReturn(true).when(mPhone).isUsingNewDataStack();
-        doReturn(0).when(mPhone).getPhoneId();
 
         //mUiccController
         doReturn(mUiccCardApplication3gpp).when(mUiccController).getUiccCardApplication(anyInt(),
@@ -657,7 +587,6 @@
         doReturn(mUiccCardApplicationIms).when(mUiccController).getUiccCardApplication(anyInt(),
                 eq(UiccController.APP_FAM_IMS));
         doReturn(mUiccCard).when(mUiccController).getUiccCard(anyInt());
-        doReturn(mUiccPort).when(mUiccController).getUiccPort(anyInt());
 
         doAnswer(new Answer<IccRecords>() {
             public IccRecords answer(InvocationOnMock invocation) {
@@ -706,11 +635,8 @@
                 anyInt(), anyBoolean());
 
         //Misc
-        doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_LTE).when(mServiceState)
-                .getRilDataRadioTechnology();
-        doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
-                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE))
-                .when(mDisplayInfoController).getTelephonyDisplayInfo();
+        doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS).when(mServiceState).
+                getRilDataRadioTechnology();
         doReturn(mPhone).when(mCT).getPhone();
         doReturn(mImsEcbm).when(mImsManager).getEcbmInterface();
         doReturn(mPhone).when(mInboundSmsHandler).getPhone();
@@ -733,19 +659,15 @@
         logd("mMockLegacyPermissionManager replaced");
         doReturn(new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                 AccessNetworkConstants.TRANSPORT_TYPE_WLAN})
-                .when(mAccessNetworksManager).getAvailableTransports();
-        doReturn(new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN})
-                .when(mAccessNetworksManager).getAvailableTransports();
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
+                .when(mTransportManager).getAvailableTransports();
+        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mTransportManager)
                 .getCurrentTransport(anyInt());
         doReturn(true).when(mDataEnabledSettings).isDataEnabled();
         doReturn(true).when(mDataEnabledSettings).isDataEnabled(anyInt());
         doReturn(true).when(mDataEnabledSettings).isInternalDataEnabled();
-        doReturn(true).when(mDataSettingsManager).isDataEnabled();
         doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
                 anyInt(), anyInt());
-        doReturn(RIL.RADIO_HAL_VERSION_2_0).when(mPhone).getHalVersion();
+        doReturn(new HalVersion(1, 4)).when(mPhone).getHalVersion();
         doReturn(2).when(mSignalStrength).getLevel();
 
         // WiFi
@@ -776,43 +698,9 @@
         Settings.Global.putInt(resolver, Settings.Global.DEVICE_PROVISIONED, 1);
         Settings.Global.putInt(resolver,
                 Settings.Global.DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, 1);
-        Settings.Global.putInt(resolver, Settings.Global.DATA_ROAMING, 0);
         doReturn(mDataThrottler).when(mDcTracker).getDataThrottler();
         doReturn(-1L).when(mDataThrottler).getRetryTime(anyInt());
 
-        doReturn(90).when(mDataConfigManager).getNetworkCapabilityPriority(
-                eq(NetworkCapabilities.NET_CAPABILITY_EIMS));
-        doReturn(80).when(mDataConfigManager).getNetworkCapabilityPriority(
-                eq(NetworkCapabilities.NET_CAPABILITY_SUPL));
-        doReturn(70).when(mDataConfigManager).getNetworkCapabilityPriority(
-                eq(NetworkCapabilities.NET_CAPABILITY_MMS));
-        doReturn(70).when(mDataConfigManager).getNetworkCapabilityPriority(
-                eq(NetworkCapabilities.NET_CAPABILITY_XCAP));
-        doReturn(50).when(mDataConfigManager).getNetworkCapabilityPriority(
-                eq(NetworkCapabilities.NET_CAPABILITY_CBS));
-        doReturn(50).when(mDataConfigManager).getNetworkCapabilityPriority(
-                eq(NetworkCapabilities.NET_CAPABILITY_MCX));
-        doReturn(50).when(mDataConfigManager).getNetworkCapabilityPriority(
-                eq(NetworkCapabilities.NET_CAPABILITY_FOTA));
-        doReturn(40).when(mDataConfigManager).getNetworkCapabilityPriority(
-                eq(NetworkCapabilities.NET_CAPABILITY_IMS));
-        doReturn(30).when(mDataConfigManager).getNetworkCapabilityPriority(
-                eq(NetworkCapabilities.NET_CAPABILITY_DUN));
-        doReturn(20).when(mDataConfigManager).getNetworkCapabilityPriority(
-                eq(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
-        doReturn(20).when(mDataConfigManager).getNetworkCapabilityPriority(
-                eq(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        doReturn(60000).when(mDataConfigManager).getAnomalyNetworkConnectingTimeoutMs();
-        doReturn(60000).when(mDataConfigManager)
-                .getAnomalyNetworkDisconnectingTimeoutMs();
-        doReturn(60000).when(mDataConfigManager).getNetworkHandoverTimeoutMs();
-        doReturn(new DataConfigManager.EventFrequency(300000, 12))
-                .when(mDataConfigManager).getAnomalySetupDataCallThreshold();
-        doReturn(new DataConfigManager.EventFrequency(0, 2))
-                .when(mDataConfigManager).getAnomalyImsReleaseRequestThreshold();
-        doReturn(new DataConfigManager.EventFrequency(300000, 12))
-                .when(mDataConfigManager).getAnomalyNetworkUnwantedThreshold();
-
         // CellularNetworkValidator
         doReturn(SubscriptionManager.INVALID_PHONE_INDEX)
                 .when(mCellularNetworkValidator).getSubIdInValidation();
@@ -871,12 +759,6 @@
     }
 
     protected void tearDown() throws Exception {
-        // Clear all remaining messages
-        if (!mTestableLoopers.isEmpty()) {
-            for (TestableLooper looper : mTestableLoopers) {
-                looper.getLooper().quit();
-            }
-        }
         // Ensure there are no references to handlers between tests.
         PhoneConfigurationManager.unregisterAllMultiSimConfigChangeRegistrants();
         // unmonitor TestableLooper for TelephonyTest class
@@ -889,43 +771,13 @@
         }
         TestableLooper.remove(TelephonyTest.this);
 
-        if (mSimulatedCommands != null) {
-            mSimulatedCommands.dispose();
-        }
-        if (mContext != null) {
-            SharedPreferences sharedPreferences = mContext.getSharedPreferences((String) null, 0);
-            sharedPreferences.edit().clear().commit();
-        }
+        mSimulatedCommands.dispose();
+        SharedPreferences sharedPreferences = mContext.getSharedPreferences((String) null, 0);
+        sharedPreferences.edit().clear().commit();
+
         restoreInstances();
         TelephonyManager.enableServiceHandleCaching();
         SubscriptionController.enableCaching();
-
-        mNetworkRegistrationInfo = null;
-        mActivityManager = null;
-        mImsCallProfile = null;
-        mTelephonyManager = null;
-        mTelephonyRegistryManager = null;
-        mSubscriptionManager = null;
-        mEuiccManager = null;
-        mPackageManager = null;
-        mConnectivityManager = null;
-        mAppOpsManager = null;
-        mCarrierConfigManager = null;
-        mUserManager = null;
-        mKeyguardManager = null;
-        mVcnManager = null;
-        mNetworkPolicyManager = null;
-        mSimulatedCommands = null;
-        mContextFixture = null;
-        mContext = null;
-        mFakeBlockedNumberContentProvider = null;
-        mLock = null;
-        mServiceManagerMockedServices.clear();
-        mServiceManagerMockedServices = null;
-        mPhone = null;
-        mTestableLoopers.clear();
-        mTestableLoopers = null;
-        mTestableLooper = null;
     }
 
     protected static void logd(String s) {
@@ -1033,10 +885,6 @@
         // restrictions should be enabled; this results in a NPE when DeviceConfig uses
         // Activity.currentActivity.getContentResolver as the resolver for Settings.Config.getString
         // since the IContentProvider in the NameValueCache's provider holder is null.
-        replaceContentProvider(new FakeSettingsConfigProvider());
-    }
-
-    private void replaceContentProvider(ContentProvider contentProvider) throws Exception {
         Class c = Class.forName("android.provider.Settings$Config");
         Field field = c.getDeclaredField("sNameValueCache");
         field.setAccessible(true);
@@ -1047,9 +895,10 @@
         field.setAccessible(true);
         Object providerHolder = field.get(cache);
 
+        FakeSettingsConfigProvider fakeSettingsProvider = new FakeSettingsConfigProvider();
         field = MockContentProvider.class.getDeclaredField("mIContentProvider");
         field.setAccessible(true);
-        Object iContentProvider = field.get(contentProvider);
+        Object iContentProvider = field.get(fakeSettingsProvider);
 
         replaceInstance(Class.forName("android.provider.Settings$ContentProviderHolder"),
                 "mContentProvider", providerHolder, iContentProvider);
@@ -1182,52 +1031,6 @@
     }
 
     /**
-     * @return The longest delay from all the message queues.
-     */
-    private long getLongestDelay() {
-        long delay = 0;
-        for (TestableLooper looper : mTestableLoopers) {
-            MessageQueue queue = looper.getLooper().getQueue();
-            try {
-                Message msg = (Message) MESSAGE_QUEUE_FIELD.get(queue);
-                while (msg != null) {
-                    delay = Math.max(msg.getWhen(), delay);
-                    msg = (Message) MESSAGE_NEXT_FIELD.get(msg);
-                }
-            } catch (IllegalAccessException e) {
-                throw new RuntimeException("Access failed in TelephonyTest", e);
-            }
-        }
-        return delay;
-    }
-
-    /**
-     * @return {@code true} if there are any messages in the queue.
-     */
-    private boolean messagesExist() {
-        for (TestableLooper looper : mTestableLoopers) {
-            MessageQueue queue = looper.getLooper().getQueue();
-            try {
-                Message msg = (Message) MESSAGE_QUEUE_FIELD.get(queue);
-                if (msg != null) return true;
-            } catch (IllegalAccessException e) {
-                throw new RuntimeException("Access failed in TelephonyTest", e);
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Handle all messages including the delayed messages.
-     */
-    public void processAllFutureMessages() {
-        while (messagesExist()) {
-            moveTimeForward(getLongestDelay());
-            processAllMessages();
-        }
-    }
-
-    /**
      * Check if there are any messages to be processed in any monitored TestableLooper
      * Delayed messages to be handled at a later time will be ignored
      * @return true if there are no messages that can be handled at the current time
diff --git a/tests/telephonytests/src/com/android/internal/telephony/VisualVoicemailSmsFilterTest.java b/tests/telephonytests/src/com/android/internal/telephony/VisualVoicemailSmsFilterTest.java
index f09c94e..a2be8c7 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/VisualVoicemailSmsFilterTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/VisualVoicemailSmsFilterTest.java
@@ -30,8 +30,6 @@
 
 import junit.framework.TestCase;
 
-import org.junit.After;
-import org.junit.Before;
 import org.mockito.Mockito;
 
 import java.util.Arrays;
@@ -83,7 +81,7 @@
     private Context mContext;
     private TelephonyManager mTelephonyManager;
 
-    @Before
+    @Override
     public void setUp() throws Exception {
         super.setUp();
         mContext = Mockito.mock(Context.class);
@@ -104,11 +102,9 @@
                 });
     }
 
-    @After
+    @Override
     public void tearDown() throws Exception {
         VisualVoicemailSmsFilter.setPhoneAccountHandleConverterForTest(null);
-        mContext = null;
-        mTelephonyManager = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/WapPushOverSmsTest.java b/tests/telephonytests/src/com/android/internal/telephony/WapPushOverSmsTest.java
index 8e40271..ca1fca8 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/WapPushOverSmsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/WapPushOverSmsTest.java
@@ -24,7 +24,6 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.isNull;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -40,17 +39,18 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+
 
 public class WapPushOverSmsTest extends TelephonyTest {
-    // Mocked classes
+    @Mock
     protected ISms.Stub mISmsStub;
 
     private WapPushOverSms mWapPushOverSmsUT;
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mISmsStub = mock(ISms.Stub.class);
+        super.setUp("WapPushOverSmsTest");
 
         // Note that this replaces only cached services in ServiceManager. If a service is not found
         // in the cache, a real instance is used.
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
index f86dd4b..68831f6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaInboundSmsHandlerTest.java
@@ -28,7 +28,6 @@
 import static org.mockito.Mockito.anyBoolean;
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -63,6 +62,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -70,17 +70,19 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class CdmaInboundSmsHandlerTest extends TelephonyTest {
-    // Mocked classes
+    @Mock
     private SmsStorageMonitor mSmsStorageMonitor;
+    @Mock
     private android.telephony.SmsMessage mSmsMessage;
+    @Mock
     private SmsMessage mCdmaSmsMessage;
 
     private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
     private SmsEnvelope mSmsEnvelope = new SmsEnvelope();
     private FakeSmsContentProvider mContentProvider;
     private InboundSmsTracker mInboundSmsTracker;
-    private final byte[] mSmsPdu = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
-    private final int mSubId0 = 0;
+    private byte[] mSmsPdu = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+    private int mSubId0 = 0;
 
     private IState getCurrentState() {
         try {
@@ -95,10 +97,7 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mSmsStorageMonitor = mock(SmsStorageMonitor.class);
-        mSmsMessage = mock(android.telephony.SmsMessage.class);
-        mCdmaSmsMessage = mock(SmsMessage.class);
+        super.setUp("CdmaInboundSmsHandlerTest");
 
         Field field = SmsMessage.class.getDeclaredField("mEnvelope");
         field.setAccessible(true);
@@ -168,12 +167,8 @@
             i++;
         }
         assertFalse(mCdmaInboundSmsHandler.getWakeLock().isHeld());
-        mCdmaInboundSmsHandler.quit();
         mCdmaInboundSmsHandler = null;
         mContentProvider.shutdown();
-        mContentProvider = null;
-        mSmsEnvelope = null;
-        mInboundSmsTracker = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java
index c9a16f5..0dc9647 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsCbTest.java
@@ -26,7 +26,6 @@
 import androidx.test.filters.FlakyTest;
 
 import com.android.internal.telephony.GsmAlphabet;
-import com.android.internal.telephony.RILUtils;
 import com.android.internal.telephony.cdma.sms.BearerData;
 import com.android.internal.telephony.cdma.sms.CdmaSmsAddress;
 import com.android.internal.telephony.cdma.sms.SmsEnvelope;
@@ -121,7 +120,7 @@
         for (byte b : bearerData) {
             msg.bearerData.add(b);
         }
-        SmsMessage message = RILUtils.convertHalCdmaSmsMessage(msg);
+        SmsMessage message = SmsMessageConverter.newCdmaSmsMessageFromRil(msg);
         return message;
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsDispatcherTest.java
index 0315776..c49ce60 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/cdma/CdmaSmsDispatcherTest.java
@@ -29,10 +29,16 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 
 public class CdmaSmsDispatcherTest extends TelephonyTest {
-    // Mocked classes
+    @Mock
+    private android.telephony.SmsMessage mSmsMessage;
+    @Mock
+    private SmsMessage mCdmaSmsMessage;
+    @Mock
     private SmsDispatchersController mSmsDispatchersController;
+    @Mock
     private SMSDispatcher.SmsTracker mSmsTracker;
 
     private CdmaSMSDispatcher mCdmaSmsDispatcher;
@@ -53,9 +59,7 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mSmsDispatchersController = mock(SmsDispatchersController.class);
-        mSmsTracker = mock(SMSDispatcher.SmsTracker.class);
+        super.setUp(this.getClass().getSimpleName());
 
         setupMockPackagePermissionChecks();
         doReturn(mSmsUsageMonitor).when(mSmsDispatchersController).getUsageMonitor();
@@ -66,10 +70,9 @@
 
     @After
     public void tearDown() throws Exception {
+        mCdmaSmsDispatcher = null;
         mCdmaSmsDispatcherTestHandler.quit();
         mCdmaSmsDispatcherTestHandler.join();
-        mCdmaSmsDispatcherTestHandler = null;
-        mCdmaSmsDispatcher = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/d2d/CommunicatorTest.java b/tests/telephonytests/src/com/android/internal/telephony/d2d/CommunicatorTest.java
index 4681dbc..5681dc4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/d2d/CommunicatorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/d2d/CommunicatorTest.java
@@ -30,12 +30,14 @@
 
 import androidx.test.runner.AndroidJUnit4;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
 import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -47,29 +49,20 @@
     private List<TransportProtocol> mTransportProtocols = new ArrayList<>();
     private TransportProtocol.Callback mCallback;
     private Communicator mCommunicator;
-
-    // Mocked classes
-    private ArgumentCaptor<Set<Communicator.Message>> mMessagesCaptor;
+    @Mock
     private Communicator.Callback mCommunicatorCallback;
+    @Captor
+    private ArgumentCaptor<Set<Communicator.Message>> mMessagesCaptor;
 
     @Before
     public void setUp() throws Exception {
-        mMessagesCaptor = ArgumentCaptor.forClass(Set.class);
-        mCommunicatorCallback = Mockito.mock(Communicator.Callback.class);
+        MockitoAnnotations.initMocks(this);
         TransportProtocol protocol1 = getMockTransportProtocol();
         TransportProtocol protocol2 = getMockTransportProtocol();
         mTransportProtocols.add(protocol1);
         mTransportProtocols.add(protocol2);
     }
 
-    @After
-    public void tearDown() {
-        mTransportProtocols.clear();
-        mTransportProtocols = null;
-        mCallback = null;
-        mCommunicator = null;
-    }
-
     /**
      * Verifies that we can setup the communicator and negotiate a transport.
      */
diff --git a/tests/telephonytests/src/com/android/internal/telephony/d2d/DtmfTransportConversionTest.java b/tests/telephonytests/src/com/android/internal/telephony/d2d/DtmfTransportConversionTest.java
index 5bc382f..6662bbd 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/d2d/DtmfTransportConversionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/d2d/DtmfTransportConversionTest.java
@@ -17,20 +17,21 @@
 package com.android.internal.telephony.d2d;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertTrue;
 
 import static org.junit.Assert.assertArrayEquals;
-import static org.mockito.Mockito.mock;
 
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Pair;
 
 import com.android.internal.telephony.TestExecutorService;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -62,13 +63,15 @@
         }
     }
 
-    // Mocked classes
+    @Mock
     private DtmfAdapter mDtmfAdapter;
+    @Mock
     private TransportProtocol.Callback mCallback;
+    @Mock
     private Timeouts.Adapter mTimeouts;
-
     private TestExecutorService mScheduledExecutorService = new TestExecutorService();
-    private TestParams mParams;
+
+    private final TestParams mParams;
     private DtmfTransport mDtmfTransport;
 
     public DtmfTransportConversionTest(DtmfTransportConversionTest.TestParams params) {
@@ -77,20 +80,11 @@
 
     @Before
     public void setUp() throws Exception {
-        mDtmfAdapter = mock(DtmfAdapter.class);
-        mCallback = mock(TransportProtocol.Callback.class);
-        mTimeouts = mock(Timeouts.Adapter.class);
+        MockitoAnnotations.initMocks(this);
         mDtmfTransport = new DtmfTransport(mDtmfAdapter, mTimeouts, mScheduledExecutorService);
         mDtmfTransport.setCallback(mCallback);
     }
 
-    @After
-    public void tearDown() {
-        mScheduledExecutorService = null;
-        mParams = null;
-        mDtmfTransport = null;
-    }
-
     /**
      * Setup the test cases.
      *
diff --git a/tests/telephonytests/src/com/android/internal/telephony/d2d/DtmfTransportTest.java b/tests/telephonytests/src/com/android/internal/telephony/d2d/DtmfTransportTest.java
index 68ddd23..a35abd1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/d2d/DtmfTransportTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/d2d/DtmfTransportTest.java
@@ -20,7 +20,6 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -33,11 +32,13 @@
 
 import com.android.internal.telephony.TestExecutorService;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -49,11 +50,15 @@
     private static final long NEGOTIATION_TIMEOUT_MILLIS = 2000L;
     private static final String EXPECTED_PROBE = "AAD";
 
-    // Mocked classes
+    @Mock
     private DtmfAdapter mDtmfAdapter;
+    @Mock
     private TransportProtocol.Callback mCallback;
+    @Mock
     private Timeouts.Adapter mTimeouts;
+    @Captor
     private ArgumentCaptor<Set<Communicator.Message>> mMessagesCaptor;
+    @Captor
     private ArgumentCaptor<Character> mDigitsCaptor;
 
     private TestExecutorService mTestExecutorService = new TestExecutorService();
@@ -61,11 +66,7 @@
 
     @Before
     public void setUp() throws Exception {
-        mDtmfAdapter = mock(DtmfAdapter.class);
-        mCallback = mock(TransportProtocol.Callback.class);
-        mTimeouts = mock(Timeouts.Adapter.class);
-        mMessagesCaptor = ArgumentCaptor.forClass(Set.class);
-        mDigitsCaptor = ArgumentCaptor.forClass(Character.class);
+        MockitoAnnotations.initMocks(this);
         when(mTimeouts.getDtmfMinimumIntervalMillis()).thenReturn(DIGIT_INTERVAL_MILLIS);
         when(mTimeouts.getMaxDurationOfDtmfMessageMillis()).thenReturn(MSG_TIMEOUT_MILLIS);
         when(mTimeouts.getDtmfNegotiationTimeoutMillis()).thenReturn(NEGOTIATION_TIMEOUT_MILLIS);
@@ -75,12 +76,6 @@
         mDtmfTransport.setCallback(mCallback);
     }
 
-    @After
-    public void tearDown() {
-        mTestExecutorService = null;
-        mDtmfTransport = null;
-    }
-
     /**
      * Verify starting state when newly initialized.
      */
diff --git a/tests/telephonytests/src/com/android/internal/telephony/d2d/RtpTransportConversionTest.java b/tests/telephonytests/src/com/android/internal/telephony/d2d/RtpTransportConversionTest.java
index 545507b..0c251a0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/d2d/RtpTransportConversionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/d2d/RtpTransportConversionTest.java
@@ -20,7 +20,6 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -30,12 +29,14 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.ArraySet;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -67,15 +68,13 @@
     private static final int DEVICE_STATE_LOCAL_IDENTIFIER = 2;
 
     private RtpTransport mRtpTransport;
-    private TestParams mParams;
-
-    // Mocked classes
-    private Timeouts.Adapter mTimeoutsAdapter;
-    private RtpAdapter mRtpAdapter;
-    private Handler mHandler;
-    private TransportProtocol.Callback mCallback;
-    private ArgumentCaptor<Set<RtpHeaderExtension>> mHeaderExtensionCaptor;
-    private ArgumentCaptor<Set<Communicator.Message>> mMessagesCaptor;
+    @Mock private Timeouts.Adapter mTimeoutsAdapter;
+    @Mock private RtpAdapter mRtpAdapter;
+    @Mock private Handler mHandler;
+    @Mock private TransportProtocol.Callback mCallback;
+    @Captor private ArgumentCaptor<Set<RtpHeaderExtension>> mHeaderExtensionCaptor;
+    @Captor private ArgumentCaptor<Set<Communicator.Message>> mMessagesCaptor;
+    private final TestParams mParams;
 
     public RtpTransportConversionTest(TestParams params) {
         mParams = params;
@@ -83,12 +82,7 @@
 
     @Before
     public void setUp() throws Exception {
-        mTimeoutsAdapter = mock(Timeouts.Adapter.class);
-        mRtpAdapter = mock(RtpAdapter.class);
-        mHandler = mock(Handler.class);
-        mCallback = mock(TransportProtocol.Callback.class);
-        mHeaderExtensionCaptor = ArgumentCaptor.forClass(Set.class);
-        mMessagesCaptor = ArgumentCaptor.forClass(Set.class);
+        MockitoAnnotations.initMocks(this);
         mRtpTransport = new RtpTransport(mRtpAdapter, mTimeoutsAdapter, mHandler, true /* sdp */);
         mRtpTransport.setCallback(mCallback);
 
@@ -99,12 +93,6 @@
         verify(mCallback, never()).onNegotiationFailed(any());
     }
 
-    @After
-    public void tearDown() {
-        mRtpTransport = null;
-        mParams = null;
-    }
-
     /**
      * Setup the test cases.
      * @return the test cases
diff --git a/tests/telephonytests/src/com/android/internal/telephony/d2d/RtpTransportTest.java b/tests/telephonytests/src/com/android/internal/telephony/d2d/RtpTransportTest.java
index 55559eb..c241cf2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/d2d/RtpTransportTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/d2d/RtpTransportTest.java
@@ -17,7 +17,6 @@
 package com.android.internal.telephony.d2d;
 
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -31,11 +30,13 @@
 import androidx.test.runner.AndroidJUnit4;
 
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.util.Set;
 
@@ -56,32 +57,20 @@
             new ArraySet<>();
 
     private RtpTransport mRtpTransport;
-
-    // Mocked classes
-    private ArgumentCaptor<Set<RtpHeaderExtension>> mHeaderExtensionCaptor;
-    private ArgumentCaptor<Set<Communicator.Message>> mMessagesCaptor;
-    private Timeouts.Adapter mTimeoutsAdapter;
-    private RtpAdapter mRtpAdapter;
-    private Handler mHandler;
-    private TransportProtocol.Callback mCallback;
+    @Mock private Timeouts.Adapter mTimeoutsAdapter;
+    @Mock private RtpAdapter mRtpAdapter;
+    @Mock private Handler mHandler;
+    @Mock private TransportProtocol.Callback mCallback;
+    @Captor private ArgumentCaptor<Set<RtpHeaderExtension>> mHeaderExtensionCaptor;
+    @Captor private ArgumentCaptor<Set<Communicator.Message>> mMessagesCaptor;
 
     @Before
     public void setUp() throws Exception {
-        mHeaderExtensionCaptor = ArgumentCaptor.forClass(Set.class);
-        mMessagesCaptor = ArgumentCaptor.forClass(Set.class);
-        mTimeoutsAdapter = mock(Timeouts.Adapter.class);
-        mRtpAdapter = mock(RtpAdapter.class);
-        mHandler = mock(Handler.class);
-        mCallback = mock(TransportProtocol.Callback.class);
+        MockitoAnnotations.initMocks(this);
         mRtpTransport = new RtpTransport(mRtpAdapter, mTimeoutsAdapter, mHandler, true /* sdp */);
         mRtpTransport.setCallback(mCallback);
     }
 
-    @After
-    public void tearDown() {
-        mRtpTransport = null;
-    }
-
     /**
      * Nominal case; assume the remote side accepted all RTP header extension types we need for D2D
      * communications.  The should get an instant negotiation success.
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/AccessNetworksManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/AccessNetworksManagerTest.java
deleted file mode 100644
index 19234ff..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/AccessNetworksManagerTest.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assume.assumeFalse;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.content.ComponentName;
-import android.content.IntentFilter;
-import android.content.pm.ServiceInfo;
-import android.net.NetworkCapabilities;
-import android.os.IBinder;
-import android.os.Looper;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.NetworkService;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.IQualifiedNetworksService;
-import android.telephony.data.IQualifiedNetworksServiceCallback;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.data.AccessNetworksManager.AccessNetworksManagerCallback;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class AccessNetworksManagerTest extends TelephonyTest {
-    private AccessNetworksManager mAccessNetworksManager;
-
-    // Mocked classes
-    private IQualifiedNetworksService mMockedQns;
-    private IBinder mMockedIBinder;
-    private AccessNetworksManagerCallback mMockedCallback;
-
-    // The real callback passed created by AccessNetworksManager.
-    private IQualifiedNetworksServiceCallback.Stub mQnsCallback;
-
-    private void addQnsService() throws Exception {
-        ServiceInfo QnsInfo = new ServiceInfo();
-        QnsInfo.packageName = "fake.qns";
-        QnsInfo.name = "QualifiedNetworksService";
-        QnsInfo.permission = "android.permission.BIND_TELEPHONY_NETWORK_SERVICE";
-        IntentFilter qnsIntentfilter = new IntentFilter();
-        doReturn(mMockedIBinder).when(mMockedQns).asBinder();
-        doReturn(mMockedQns).when(mMockedIBinder).queryLocalInterface(anyString());
-
-        doAnswer(invocation -> {
-            mQnsCallback = (IQualifiedNetworksServiceCallback.Stub) invocation.getArguments()[1];
-            return null;
-        }).when(mMockedQns).createNetworkAvailabilityProvider(anyInt(),
-                any(IQualifiedNetworksServiceCallback.Stub.class));
-        mContextFixture.addService(
-                NetworkService.SERVICE_INTERFACE,
-                new ComponentName("fake.qns",
-                        "fake.qns"),
-                "fake.qns",
-                mMockedQns,
-                QnsInfo,
-                qnsIntentfilter);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mMockedQns = mock(IQualifiedNetworksService.class);
-        mMockedIBinder = mock(IBinder.class);
-
-        addQnsService();
-        mContextFixture.putResource(
-                com.android.internal.R.string.config_qualified_networks_service_package,
-                "fake.qns");
-
-        mMockedCallback = Mockito.mock(AccessNetworksManagerCallback.class);
-        doAnswer(invocation -> {
-            ((Runnable) invocation.getArguments()[0]).run();
-            return null;
-        }).when(mMockedCallback).invokeFromExecutor(any(Runnable.class));
-
-        mAccessNetworksManager = new AccessNetworksManager(mPhone, Looper.myLooper());
-        processAllMessages();
-        assumeFalse(mAccessNetworksManager.isInLegacyMode());
-        logd("-setUp");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mAccessNetworksManager = null;
-        super.tearDown();
-    }
-
-    @Test
-    public void testBindService() {
-        assertThat(mQnsCallback).isNotNull();
-    }
-
-    @Test
-    public void testQualifiedNetworkTypesChanged() throws Exception {
-        assertThat(mQnsCallback).isNotNull();
-        assertThat(mAccessNetworksManager.isAnyApnOnIwlan()).isFalse();
-        assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_IMS))
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_MMS))
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(mAccessNetworksManager.isAnyApnOnIwlan()).isFalse();
-
-        mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS,
-                new int[]{AccessNetworkType.IWLAN});
-        processAllMessages();
-
-        assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_IMS))
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_MMS))
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        assertThat(mAccessNetworksManager.isAnyApnOnIwlan()).isTrue();
-    }
-
-    @Test
-    public void testEmptyNetworkTypes() throws Exception {
-        testQualifiedNetworkTypesChanged();
-
-        mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS,
-                new int[0]);
-        processAllMessages();
-
-        assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_IMS))
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_MMS))
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(mAccessNetworksManager.isAnyApnOnIwlan()).isFalse();
-    }
-
-    @Test
-    public void testInvalidNetworkTypes() throws Exception {
-        testQualifiedNetworkTypesChanged();
-
-        // Input unknown would become a no-op
-        mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS,
-                new int[]{AccessNetworkType.EUTRAN, AccessNetworkType.UNKNOWN});
-        processAllMessages();
-
-        // There shouldn't be any changes.
-        assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_IMS))
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_MMS))
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        assertThat(mAccessNetworksManager.isAnyApnOnIwlan()).isTrue();
-    }
-
-    @Test
-    public void testEmptyList() throws Exception {
-        testQualifiedNetworkTypesChanged();
-
-        // Empty list input
-        mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS,
-                new int[0]);
-        processAllMessages();
-
-        assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_IMS))
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(mAccessNetworksManager.getPreferredTransport(ApnSetting.TYPE_MMS))
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(mAccessNetworksManager.isAnyApnOnIwlan()).isFalse();
-    }
-
-    @Test
-    public void testCallback() throws Exception {
-        mAccessNetworksManager.registerCallback(mMockedCallback);
-
-        mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS,
-                new int[]{AccessNetworkType.IWLAN});
-        processAllMessages();
-
-        verify(mMockedCallback).onPreferredTransportChanged(
-                eq(NetworkCapabilities.NET_CAPABILITY_MMS));
-        verify(mMockedCallback).onPreferredTransportChanged(
-                eq(NetworkCapabilities.NET_CAPABILITY_IMS));
-        Mockito.clearInvocations(mMockedCallback);
-        assertThat(mAccessNetworksManager.getPreferredTransportByNetworkCapability(
-                NetworkCapabilities.NET_CAPABILITY_MMS)).isEqualTo(
-                        AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        assertThat(mAccessNetworksManager.getPreferredTransportByNetworkCapability(
-                NetworkCapabilities.NET_CAPABILITY_IMS)).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
-        mQnsCallback.onQualifiedNetworkTypesChanged(ApnSetting.TYPE_XCAP,
-                new int[]{AccessNetworkType.IWLAN});
-        processAllMessages();
-
-        verify(mMockedCallback).onPreferredTransportChanged(
-                eq(NetworkCapabilities.NET_CAPABILITY_XCAP));
-        Mockito.clearInvocations(mMockedCallback);
-        assertThat(mAccessNetworksManager.getPreferredTransportByNetworkCapability(
-                NetworkCapabilities.NET_CAPABILITY_XCAP)).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
-        mQnsCallback.onQualifiedNetworkTypesChanged(
-                ApnSetting.TYPE_XCAP | ApnSetting.TYPE_IMS | ApnSetting.TYPE_MMS,
-                new int[]{});
-        verify(mMockedCallback).onPreferredTransportChanged(
-                eq(NetworkCapabilities.NET_CAPABILITY_IMS));
-        verify(mMockedCallback).onPreferredTransportChanged(
-                eq(NetworkCapabilities.NET_CAPABILITY_MMS));
-        verify(mMockedCallback).onPreferredTransportChanged(
-                eq(NetworkCapabilities.NET_CAPABILITY_XCAP));
-        assertThat(mAccessNetworksManager.getPreferredTransportByNetworkCapability(
-                NetworkCapabilities.NET_CAPABILITY_IMS)).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(mAccessNetworksManager.getPreferredTransportByNetworkCapability(
-                NetworkCapabilities.NET_CAPABILITY_MMS)).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(mAccessNetworksManager.getPreferredTransportByNetworkCapability(
-                NetworkCapabilities.NET_CAPABILITY_XCAP)).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataConfigManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataConfigManagerTest.java
deleted file mode 100644
index 7b0443f..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataConfigManagerTest.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Looper;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import com.android.internal.telephony.TelephonyTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class DataConfigManagerTest extends TelephonyTest {
-    private DataConfigManager mDataConfigManagerUT;
-
-    @Before
-    public void setUp() throws Exception {
-        logd("DataConfigManagerTest +Setup!");
-        super.setUp(getClass().getSimpleName());
-        mDataConfigManagerUT = new DataConfigManager(mPhone, Looper.myLooper());
-        logd("DataConfigManagerTest -Setup!");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        logd("tearDown");
-        mDataConfigManagerUT = null;
-        super.tearDown();
-    }
-
-    @Test
-    public void testParseSlidingWindowCounterThreshold() {
-        long defaultTimeWindow = 0;
-        int defaultOccurrence = 2;
-        DataConfigManager.EventFrequency defaultValue = new DataConfigManager.EventFrequency(0, 2);
-
-        DataConfigManager.EventFrequency normal =
-                mDataConfigManagerUT.parseSlidingWindowCounterThreshold(Long.MAX_VALUE + ","
-                        + Integer.MAX_VALUE, defaultTimeWindow, defaultOccurrence);
-        DataConfigManager.EventFrequency expected =
-                new DataConfigManager.EventFrequency(Long.MAX_VALUE, Integer.MAX_VALUE);
-        assertThat(normal.timeWindow).isEqualTo(expected.timeWindow);
-        assertThat(normal.eventNumOccurrence).isEqualTo(expected.eventNumOccurrence);
-
-        //allow " time , occurrences ," as we can infer even though format is not strictly valid
-        DataConfigManager.EventFrequency invalidFormat = mDataConfigManagerUT
-                .parseSlidingWindowCounterThreshold(
-                        Long.MAX_VALUE + "," + Integer.MAX_VALUE + " ,",
-                        defaultTimeWindow, defaultOccurrence);
-        assertThat(invalidFormat.timeWindow).isEqualTo(Long.MAX_VALUE);
-        assertThat(invalidFormat.eventNumOccurrence).isEqualTo(Integer.MAX_VALUE);
-
-        DataConfigManager.EventFrequency invalidRange = mDataConfigManagerUT
-                .parseSlidingWindowCounterThreshold(
-                        Long.MAX_VALUE + "," + Long.MAX_VALUE, defaultTimeWindow,
-                        defaultOccurrence);
-        assertThat(invalidRange.timeWindow).isEqualTo(defaultValue.timeWindow);
-        assertThat(invalidRange.eventNumOccurrence).isEqualTo(defaultValue.eventNumOccurrence);
-
-        DataConfigManager.EventFrequency invalidFormat2 = mDataConfigManagerUT
-                .parseSlidingWindowCounterThreshold("", defaultTimeWindow, defaultOccurrence);
-        assertThat(invalidFormat2.timeWindow).isEqualTo(defaultValue.timeWindow);
-        assertThat(invalidFormat2.eventNumOccurrence).isEqualTo(defaultValue.eventNumOccurrence);
-
-        DataConfigManager.EventFrequency invalidFormat3 = mDataConfigManagerUT
-                .parseSlidingWindowCounterThreshold(null, defaultTimeWindow, defaultOccurrence);
-        assertThat(invalidFormat3.timeWindow).isEqualTo(defaultValue.timeWindow);
-        assertThat(invalidFormat3.eventNumOccurrence).isEqualTo(defaultValue.eventNumOccurrence);
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataEvaluationTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataEvaluationTest.java
deleted file mode 100644
index 63f3e4f..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataEvaluationTest.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import com.android.internal.telephony.TelephonyTest;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class DataEvaluationTest extends TelephonyTest {
-    DataEvaluation mDataEvaluationUT;
-    @Before
-    public void setUp() throws Exception {
-        logd("DataEvaluationTest +Setup!");
-        super.setUp(getClass().getSimpleName());
-        logd("DataEvaluationTest -Setup!");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        logd("tearDown");
-        mDataEvaluationUT = null;
-        super.tearDown();
-    }
-
-    @Test
-    public void testModifyDataDisallowedReasonSet() {
-        mDataEvaluationUT = new DataEvaluation(DataEvaluation.DataEvaluationReason.DATA_RETRY);
-        mDataEvaluationUT.addDataDisallowedReason(
-                DataEvaluation.DataDisallowedReason.DATA_DISABLED);
-        mDataEvaluationUT.addDataDisallowedReason(
-                DataEvaluation.DataDisallowedReason.ROAMING_DISABLED);
-
-        assertThat(mDataEvaluationUT.getDataDisallowedReasons().size()).isEqualTo(2);
-
-        //remove nonexistent disallowed reason
-        mDataEvaluationUT.removeDataDisallowedReason(
-                DataEvaluation.DataDisallowedReason.DEFAULT_DATA_UNSELECTED);
-        assertThat(mDataEvaluationUT.getDataDisallowedReasons().size()).isEqualTo(2);
-
-        mDataEvaluationUT.removeDataDisallowedReason(
-                DataEvaluation.DataDisallowedReason.DATA_DISABLED);
-        assertThat(mDataEvaluationUT.getDataDisallowedReasons().size()).isEqualTo(1);
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
deleted file mode 100644
index 52b487a..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkControllerTest.java
+++ /dev/null
@@ -1,3149 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import static com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
-import static com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThrows;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.annotation.NonNull;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.InetAddresses;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NetworkCapabilities;
-import android.net.NetworkPolicyManager;
-import android.net.NetworkRequest;
-import android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener;
-import android.net.vcn.VcnNetworkPolicyResult;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.PersistableBundle;
-import android.os.RegistrantList;
-import android.provider.Telephony;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.Annotation.DataFailureCause;
-import android.telephony.Annotation.NetCapability;
-import android.telephony.Annotation.NetworkType;
-import android.telephony.CarrierConfigManager;
-import android.telephony.DataFailCause;
-import android.telephony.DataSpecificRegistrationInfo;
-import android.telephony.LteVopsSupportInfo;
-import android.telephony.NetworkRegistrationInfo;
-import android.telephony.NetworkRegistrationInfo.RegistrationState;
-import android.telephony.PreciseDataConnectionState;
-import android.telephony.ServiceState;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionPlan;
-import android.telephony.TelephonyDisplayInfo;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataCallResponse.LinkStatus;
-import android.telephony.data.DataProfile;
-import android.telephony.data.DataService;
-import android.telephony.data.DataServiceCallback;
-import android.telephony.data.ThrottleStatus;
-import android.telephony.data.TrafficDescriptor;
-import android.telephony.data.TrafficDescriptor.OsAppId;
-import android.telephony.ims.ImsManager;
-import android.telephony.ims.ImsMmTelManager;
-import android.telephony.ims.ImsRcsManager;
-import android.telephony.ims.ImsReasonInfo;
-import android.telephony.ims.ImsRegistrationAttributes;
-import android.telephony.ims.ImsStateCallback;
-import android.telephony.ims.RegistrationManager.RegistrationCallback;
-import android.telephony.ims.feature.ImsFeature;
-import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.util.ArraySet;
-import android.util.SparseArray;
-
-import com.android.internal.telephony.ISub;
-import com.android.internal.telephony.MultiSimSettingController;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.RIL;
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.data.AccessNetworksManager.AccessNetworksManagerCallback;
-import com.android.internal.telephony.data.DataEvaluation.DataDisallowedReason;
-import com.android.internal.telephony.data.DataNetworkController.HandoverRule;
-import com.android.internal.telephony.data.DataRetryManager.DataRetryManagerCallback;
-import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
-import com.android.internal.telephony.ims.ImsResolver;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-
-import java.lang.reflect.Field;
-import java.time.Period;
-import java.time.ZonedDateTime;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.Executor;
-import java.util.stream.Collectors;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class DataNetworkControllerTest extends TelephonyTest {
-    private static final String IPV4_ADDRESS = "10.0.2.15";
-    private static final String IPV6_ADDRESS = "2607:fb90:a620:651d:eabe:f8da:c107:44be";
-
-    private static final String FAKE_MMTEL_PACKAGE = "fake.mmtel.package";
-    private static final String FAKE_RCS_PACKAGE = "fake.rcs.package";
-
-    // Mocked classes
-    private PhoneSwitcher mMockedPhoneSwitcher;
-    protected ISub mMockedIsub;
-    private DataNetworkControllerCallback mMockedDataNetworkControllerCallback;
-    private DataRetryManagerCallback mMockedDataRetryManagerCallback;
-    private ImsResolver mMockedImsResolver;
-
-    private ImsManager mMockedImsManager;
-    private ImsMmTelManager mMockedImsMmTelManager;
-    private ImsRcsManager mMockedImsRcsManager;
-    private ImsStateCallback mMmtelStateCallback;
-    private ImsStateCallback mRcsStateCallback;
-    private RegistrationCallback mMmtelRegCallback;
-    private RegistrationCallback mRcsRegCallback;
-    private SubscriptionInfo mMockSubInfo;
-
-    private int mNetworkRequestId = 0;
-
-    private final SparseArray<DataServiceManager> mMockedDataServiceManagers = new SparseArray<>();
-    private final SparseArray<RegistrantList> mDataCallListChangedRegistrants = new SparseArray<>();
-    private DataNetworkController mDataNetworkControllerUT;
-    private PersistableBundle mCarrierConfig;
-
-    private AccessNetworksManagerCallback mAccessNetworksManagerCallback;
-    private LinkBandwidthEstimatorCallback mLinkBandwidthEstimatorCallback;
-
-    private final DataProfile mGeneralPurposeDataProfile = new DataProfile.Builder()
-            .setApnSetting(new ApnSetting.Builder()
-                    .setId(2163)
-                    .setOperatorNumeric("12345")
-                    .setEntryName("internet_supl_mms_apn")
-                    .setApnName("internet_supl_mms_apn")
-                    .setUser("user")
-                    .setPassword("passwd")
-                    .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL
-                            | ApnSetting.TYPE_MMS)
-                    .setProtocol(ApnSetting.PROTOCOL_IPV6)
-                    .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-                    .setCarrierEnabled(true)
-                    .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
-                            | TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN
-                            | TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT))
-                    .setLingeringNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
-                            | TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT
-                            | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS
-                            | TelephonyManager.NETWORK_TYPE_BITMASK_NR))
-                    .setProfileId(1234)
-                    .setMaxConns(321)
-                    .setWaitTime(456)
-                    .setMaxConnsTime(789)
-                    .build())
-            .setPreferred(false)
-            .build();
-
-    private final DataProfile mImsCellularDataProfile = new DataProfile.Builder()
-            .setApnSetting(new ApnSetting.Builder()
-                    .setId(2164)
-                    .setOperatorNumeric("12345")
-                    .setEntryName("ims_apn")
-                    .setApnName("ims_apn")
-                    .setUser("user")
-                    .setPassword("passwd")
-                    .setApnTypeBitmask(ApnSetting.TYPE_IMS)
-                    .setProtocol(ApnSetting.PROTOCOL_IPV6)
-                    .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-                    .setCarrierEnabled(true)
-                    .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
-                            | TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT))
-                    .setLingeringNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
-                            | TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN
-                            | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS
-                            | TelephonyManager.NETWORK_TYPE_BITMASK_NR))
-                    .setProfileId(1235)
-                    .setMaxConns(321)
-                    .setWaitTime(456)
-                    .setMaxConnsTime(789)
-                    .build())
-            .setPreferred(false)
-            .build();
-
-    private final DataProfile mImsIwlanDataProfile = new DataProfile.Builder()
-            .setApnSetting(new ApnSetting.Builder()
-                    .setId(2164)
-                    .setOperatorNumeric("12345")
-                    .setEntryName("ims_apn")
-                    .setApnName("ims_apn")
-                    .setUser("user")
-                    .setPassword("passwd")
-                    .setApnTypeBitmask(ApnSetting.TYPE_IMS)
-                    .setProtocol(ApnSetting.PROTOCOL_IPV6)
-                    .setRoamingProtocol(ApnSetting.PROTOCOL_IPV6)
-                    .setCarrierEnabled(true)
-                    .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_IWLAN))
-                    .setProfileId(1235)
-                    .setMaxConns(321)
-                    .setWaitTime(456)
-                    .setMaxConnsTime(789)
-                    .build())
-            .setPreferred(false)
-            .build();
-
-    private final DataProfile mEmergencyDataProfile = new DataProfile.Builder()
-            .setApnSetting(new ApnSetting.Builder()
-                    .setEntryName("DEFAULT EIMS")
-                    .setId(2165)
-                    .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
-                    .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
-                    .setApnName("sos")
-                    .setApnTypeBitmask(ApnSetting.TYPE_EMERGENCY)
-                    .setCarrierEnabled(true)
-                    .setApnSetId(Telephony.Carriers.MATCH_ALL_APN_SET_ID)
-                    .build())
-            .build();
-
-    private final DataProfile mFotaDataProfile = new DataProfile.Builder()
-            .setApnSetting(new ApnSetting.Builder()
-                    .setId(2166)
-                    .setOperatorNumeric("12345")
-                    .setEntryName("fota_apn")
-                    .setApnName("fota_apn")
-                    .setUser("user")
-                    .setPassword("passwd")
-                    .setApnTypeBitmask(ApnSetting.TYPE_FOTA)
-                    .setProtocol(ApnSetting.PROTOCOL_IPV6)
-                    .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-                    .setCarrierEnabled(true)
-                    .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE
-                            | (int) TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT)
-                    .setProfileId(1236)
-                    .setMaxConns(321)
-                    .setWaitTime(456)
-                    .setMaxConnsTime(789)
-                    .build())
-            .setPreferred(false)
-            .build();
-
-    private final DataProfile mTetheringDataProfile = new DataProfile.Builder()
-            .setApnSetting(new ApnSetting.Builder()
-                    .setId(2167)
-                    .setOperatorNumeric("12345")
-                    .setEntryName("dun_apn")
-                    .setApnName("dun_apn")
-                    .setUser("user")
-                    .setPassword("passwd")
-                    .setApnTypeBitmask(ApnSetting.TYPE_DUN)
-                    .setProtocol(ApnSetting.PROTOCOL_IPV6)
-                    .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-                    .setCarrierEnabled(true)
-                    .setNetworkTypeBitmask((int) TelephonyManager.NETWORK_TYPE_BITMASK_LTE
-                            | (int) TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT)
-                    .setProfileId(1236)
-                    .setMaxConns(321)
-                    .setWaitTime(456)
-                    .setMaxConnsTime(789)
-                    .build())
-            .setPreferred(false)
-            .build();
-
-    private final DataProfile mEnterpriseDataProfile = new DataProfile.Builder()
-            .setTrafficDescriptor(new TrafficDescriptor(null,
-                    new TrafficDescriptor.OsAppId(TrafficDescriptor.OsAppId.ANDROID_OS_ID,
-                            "ENTERPRISE", 1).getBytes()))
-            .build();
-
-    /** Data call response map. The first key is the transport type, the second key is the cid. */
-    private final Map<Integer, Map<Integer, DataCallResponse>> mDataCallResponses = new HashMap<>();
-
-    private @NonNull DataCallResponse createDataCallResponse(int cid, @LinkStatus int linkStatus) {
-        return createDataCallResponse(cid, linkStatus, Collections.emptyList());
-    }
-
-    private @NonNull DataCallResponse createDataCallResponse(int cid, @LinkStatus int linkStatus,
-            @NonNull List<TrafficDescriptor> tdList) {
-        return new DataCallResponse.Builder()
-                .setCause(0)
-                .setRetryDurationMillis(-1L)
-                .setId(cid)
-                .setLinkStatus(linkStatus)
-                .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
-                .setInterfaceName("ifname" + cid)
-                .setAddresses(Arrays.asList(
-                        new LinkAddress(InetAddresses.parseNumericAddress(IPV4_ADDRESS), 32),
-                        new LinkAddress(IPV6_ADDRESS + "/64")))
-                .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress("10.0.2.3"),
-                        InetAddresses.parseNumericAddress("fd00:976a::9")))
-                .setGatewayAddresses(Arrays.asList(
-                        InetAddresses.parseNumericAddress("10.0.2.15"),
-                        InetAddresses.parseNumericAddress("fe80::2")))
-                .setPcscfAddresses(Arrays.asList(
-                        InetAddresses.parseNumericAddress("fd00:976a:c305:1d::8"),
-                        InetAddresses.parseNumericAddress("fd00:976a:c202:1d::7"),
-                        InetAddresses.parseNumericAddress("fd00:976a:c305:1d::5")))
-                .setMtu(1500)
-                .setMtuV4(1500)
-                .setMtuV6(1500)
-                .setPduSessionId(1)
-                .setQosBearerSessions(new ArrayList<>())
-                .setTrafficDescriptors(tdList)
-                .build();
-    }
-
-    private void setFailedSetupDataResponse(DataServiceManager dsm, @DataFailureCause int cause,
-            long retryMillis, boolean forHandover) {
-        setFailedSetupDataResponse(dsm, cause, retryMillis, forHandover, 0);
-    }
-
-    private void setFailedSetupDataResponse(DataServiceManager dsm, @DataFailureCause int cause,
-            long retryMillis, boolean forHandover, long delay) {
-        doAnswer(invocation -> {
-            final Message msg = (Message) invocation.getArguments()[10];
-
-            DataCallResponse response = new DataCallResponse.Builder()
-                    .setCause(cause)
-                    .setRetryDurationMillis(retryMillis)
-                    .setHandoverFailureMode(
-                            DataCallResponse.HANDOVER_FAILURE_MODE_NO_FALLBACK_RETRY_HANDOVER)
-                    .build();
-            msg.getData().putParcelable("data_call_response", response);
-            msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
-            msg.getTarget().sendMessageDelayed(msg, delay);
-            return null;
-        }).when(dsm).setupDataCall(anyInt(), any(DataProfile.class), anyBoolean(),
-                anyBoolean(), forHandover ? eq(DataService.REQUEST_REASON_HANDOVER)
-                        : eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(), any(), any(),
-                anyBoolean(), any(Message.class));
-    }
-
-    private void setSuccessfulSetupDataResponse(DataServiceManager dsm, DataCallResponse response) {
-        doAnswer(invocation -> {
-            final Message msg = (Message) invocation.getArguments()[10];
-
-            int transport = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
-            if (dsm == mMockedWwanDataServiceManager) {
-                transport = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
-            } else if (dsm == mMockedWlanDataServiceManager) {
-                transport = AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
-            }
-            mDataCallResponses.computeIfAbsent(transport, v -> new HashMap<>());
-            mDataCallResponses.get(transport).put(response.getId(), response);
-            msg.getData().putParcelable("data_call_response", response);
-            msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
-            msg.sendToTarget();
-
-            mDataCallListChangedRegistrants.get(transport).notifyRegistrants(
-                    new AsyncResult(transport, new ArrayList<>(mDataCallResponses.get(
-                            transport).values()), null));
-            return null;
-        }).when(dsm).setupDataCall(anyInt(), any(DataProfile.class), anyBoolean(),
-                anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
-                any(Message.class));
-    }
-
-    private void setSuccessfulSetupDataResponse(DataServiceManager dsm, int cid) {
-        setSuccessfulSetupDataResponse(dsm, cid, 0L);
-    }
-
-    private void setSuccessfulSetupDataResponse(DataServiceManager dsm, int cid, long delay) {
-        doAnswer(invocation -> {
-            final Message msg = (Message) invocation.getArguments()[10];
-
-            DataCallResponse response = createDataCallResponse(cid,
-                    DataCallResponse.LINK_STATUS_ACTIVE);
-            int transport = AccessNetworkConstants.TRANSPORT_TYPE_INVALID;
-            if (dsm == mMockedWwanDataServiceManager) {
-                transport = AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
-            } else if (dsm == mMockedWlanDataServiceManager) {
-                transport = AccessNetworkConstants.TRANSPORT_TYPE_WLAN;
-            }
-            mDataCallResponses.computeIfAbsent(transport, v -> new HashMap<>());
-            mDataCallResponses.get(transport).put(cid, response);
-            msg.getData().putParcelable("data_call_response", response);
-            msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
-            msg.getTarget().sendMessageDelayed(msg, delay);
-
-            final int t = transport;
-            msg.getTarget().postDelayed(() -> {
-                mDataCallListChangedRegistrants.get(t).notifyRegistrants(
-                        new AsyncResult(t, new ArrayList<>(mDataCallResponses.get(
-                                t).values()), null));
-
-            }, delay + 100);
-            return null;
-        }).when(dsm).setupDataCall(anyInt(), any(DataProfile.class), anyBoolean(),
-                anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
-                any(Message.class));
-    }
-
-    private void clearCallbacks() throws Exception {
-        Field field = DataNetworkController.class
-                .getDeclaredField("mDataNetworkControllerCallbacks");
-        field.setAccessible(true);
-        ((Set<DataNetworkControllerCallback>) field.get(mDataNetworkControllerUT)).clear();
-    }
-
-    private void carrierConfigChanged() {
-        // Trigger carrier config reloading
-        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, 0);
-        mContext.sendBroadcast(intent);
-        processAllMessages();
-    }
-
-    private void setImsRegistered(boolean registered) {
-        if (registered) {
-            final ArraySet<String> features = new ArraySet<>();
-            features.add("feature1");
-            features.add("feature2");
-            ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(
-                    ImsRegistrationImplBase.REGISTRATION_TECH_LTE).setFeatureTags(features).build();
-
-            mMmtelRegCallback.onRegistered(attr);
-        } else {
-            ImsReasonInfo info = new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE, -1, "");
-            mMmtelRegCallback.onUnregistered(info);
-        }
-    }
-
-    private void setRcsRegistered(boolean registered) {
-        if (registered) {
-            final ArraySet<String> features = new ArraySet<>();
-            features.add("feature1");
-            features.add("feature2");
-            ImsRegistrationAttributes attr = new ImsRegistrationAttributes.Builder(
-                    ImsRegistrationImplBase.REGISTRATION_TECH_LTE).setFeatureTags(features).build();
-
-            mRcsRegCallback.onRegistered(attr);
-        } else {
-            ImsReasonInfo info = new ImsReasonInfo(ImsReasonInfo.CODE_LOCAL_ILLEGAL_STATE, -1, "");
-            mRcsRegCallback.onUnregistered(info);
-        }
-    }
-
-    private void serviceStateChanged(@NetworkType int networkType,
-            @RegistrationState int regState) {
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
-
-        serviceStateChanged(networkType, regState, dsri);
-    }
-
-    private void serviceStateChanged(@NetworkType int networkType,
-            @RegistrationState int regState, DataSpecificRegistrationInfo dsri) {
-        ServiceState ss = new ServiceState();
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(networkType)
-                .setRegistrationState(regState)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .setDataSpecificInfo(dsri)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(networkType)
-                .setRegistrationState(regState)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
-                .build());
-        ss.setDataRoamingFromRegistration(regState
-                == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
-        doReturn(ss).when(mSST).getServiceState();
-        doReturn(ss).when(mPhone).getServiceState();
-
-        mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
-        processAllMessages();
-    }
-
-    private void updateTransport(@NetCapability int capability, @TransportType int transport) {
-        doReturn(transport).when(mAccessNetworksManager)
-                .getPreferredTransportByNetworkCapability(capability);
-        mAccessNetworksManagerCallback.onPreferredTransportChanged(capability);
-        processAllMessages();
-    }
-
-    private void setVcnManagerPolicy(boolean vcnManaged, boolean shouldTearDown) {
-        doAnswer(invocation -> {
-            final NetworkCapabilities networkCapabilities =
-                    (NetworkCapabilities) invocation.getArguments()[0];
-            if (vcnManaged) {
-                networkCapabilities.removeCapability(
-                        NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
-            } else {
-                networkCapabilities.addCapability(
-                        NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED);
-            }
-            return new VcnNetworkPolicyResult(
-                    shouldTearDown, networkCapabilities);
-        }).when(mVcnManager).applyVcnNetworkPolicy(any(NetworkCapabilities.class),
-                any(LinkProperties.class));
-    }
-
-    private void initializeConfig() {
-        mCarrierConfig = mContextFixture.getCarrierConfigBundle();
-        mCarrierConfig.putStringArray(
-                CarrierConfigManager.KEY_TELEPHONY_NETWORK_CAPABILITY_PRIORITIES_STRING_ARRAY,
-                new String[]{
-                        "eims:90", "supl:80", "mms:70", "xcap:70", "cbs:50", "mcx:50", "fota:50",
-                        "ims:40", "dun:30", "enterprise:20", "internet:20"
-                });
-        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
-        mCarrierConfig.putStringArray(
-                CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
-                new String[]{"default", "mms", "dun", "supl"});
-        mCarrierConfig.putStringArray(
-                CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
-                new String[]{"default", "mms", "dun", "supl"});
-
-        mCarrierConfig.putStringArray(
-                CarrierConfigManager.KEY_TELEPHONY_DATA_SETUP_RETRY_RULES_STRING_ARRAY,
-                new String[]{
-                        "capabilities=eims, retry_interval=1000, maximum_retries=20",
-                        "fail_causes=8|27|28|29|30|32|33|35|50|51|111|-5|-6|65537|65538|-3|2253|"
-                                + "2254, maximum_retries=0", // No retry for those causes
-                        "capabilities=mms|supl|cbs, retry_interval=2000",
-                        "capabilities=internet|enterprise|dun|ims|fota, retry_interval=2500|3000|"
-                                + "5000|10000|15000|20000|40000|60000|120000|240000|"
-                                + "600000|1200000|1800000, maximum_retries=20"
-                });
-        mCarrierConfig.putStringArray(
-                CarrierConfigManager.KEY_TELEPHONY_DATA_HANDOVER_RETRY_RULES_STRING_ARRAY,
-                new String[] {"retry_interval=1000|2000|4000|8000|16000, maximum_retries=5"
-                });
-
-        mCarrierConfig.putInt(CarrierConfigManager.KEY_NR_ADVANCED_CAPABLE_PCO_ID_INT, 1234);
-
-        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_NETWORK_TEMP_NOT_METERED_SUPPORTED_BOOL,
-                true);
-
-        mCarrierConfig.putIntArray(CarrierConfigManager.KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY,
-                new int[]{TelephonyManager.NETWORK_TYPE_CDMA, TelephonyManager.NETWORK_TYPE_1xRTT,
-                        TelephonyManager.NETWORK_TYPE_EVDO_0, TelephonyManager.NETWORK_TYPE_EVDO_A,
-                        TelephonyManager.NETWORK_TYPE_EVDO_B});
-
-        mContextFixture.putResource(com.android.internal.R.string.config_bandwidthEstimateSource,
-                "bandwidth_estimator");
-
-        mContextFixture.putIntResource(com.android.internal.R.integer
-                        .config_delay_for_ims_dereg_millis, 3000);
-        mContextFixture.putBooleanResource(com.android.internal.R.bool
-                .config_enable_iwlan_handover_policy, true);
-        mContextFixture.putBooleanResource(com.android.internal.R.bool
-                .config_enhanced_iwlan_handover_check, true);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        logd("DataNetworkControllerTest +Setup!");
-        super.setUp(getClass().getSimpleName());
-        mMockedPhoneSwitcher = Mockito.mock(PhoneSwitcher.class);
-        mMockedIsub = Mockito.mock(ISub.class);
-        mMockedImsManager = mContext.getSystemService(ImsManager.class);
-        mMockedImsMmTelManager = Mockito.mock(ImsMmTelManager.class);
-        mMockedImsRcsManager = Mockito.mock(ImsRcsManager.class);
-        mMockedImsResolver = Mockito.mock(ImsResolver.class);
-        mMockedDataNetworkControllerCallback = Mockito.mock(DataNetworkControllerCallback.class);
-        mMockedDataRetryManagerCallback = Mockito.mock(DataRetryManagerCallback.class);
-        mMockSubInfo = Mockito.mock(SubscriptionInfo.class);
-        when(mTelephonyComponentFactory.makeDataSettingsManager(any(Phone.class),
-                any(DataNetworkController.class), any(Looper.class),
-                any(DataSettingsManager.DataSettingsManagerCallback.class))).thenCallRealMethod();
-        doReturn(mMockedImsMmTelManager).when(mMockedImsManager).getImsMmTelManager(anyInt());
-        doReturn(mMockedImsRcsManager).when(mMockedImsManager).getImsRcsManager(anyInt());
-
-        initializeConfig();
-        mMockedDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                mMockedWwanDataServiceManager);
-        mMockedDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
-                mMockedWlanDataServiceManager);
-
-        replaceInstance(PhoneSwitcher.class, "sPhoneSwitcher", null, mMockedPhoneSwitcher);
-        doReturn(1).when(mMockedIsub).getDefaultDataSubId();
-        doReturn(mMockedIsub).when(mIBinder).queryLocalInterface(anyString());
-        doReturn(mPhone).when(mPhone).getImsPhone();
-        mServiceManagerMockedServices.put("isub", mIBinder);
-        doReturn(new SubscriptionPlan[]{}).when(mNetworkPolicyManager)
-                .getSubscriptionPlans(anyInt(), any());
-        doReturn(true).when(mSST).getDesiredPowerState();
-        doReturn(true).when(mSST).getPowerStateFromCarrier();
-        doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed();
-        doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
-        doReturn("").when(mSubscriptionController).getDataEnabledOverrideRules(anyInt());
-        doReturn(true).when(mSubscriptionController).setDataEnabledOverrideRules(
-                anyInt(), anyString());
-
-        List<SubscriptionInfo> infoList = new ArrayList<>();
-        infoList.add(mMockSubInfo);
-        doReturn(infoList).when(mSubscriptionController).getSubscriptionsInGroup(
-                any(), any(), any());
-        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
-        doReturn(0).when(mSubscriptionController).getPhoneId(anyInt());
-
-        for (int transport : new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN}) {
-            mDataCallListChangedRegistrants.put(transport, new RegistrantList());
-            setSuccessfulSetupDataResponse(mMockedDataServiceManagers.get(transport), 1);
-            doAnswer(invocation -> {
-                int cid = (int) invocation.getArguments()[0];
-                Message msg = (Message) invocation.getArguments()[2];
-                msg.sendToTarget();
-                mDataCallResponses.get(transport).remove(cid);
-                mDataCallListChangedRegistrants.get(transport).notifyRegistrants(
-                        new AsyncResult(transport, new ArrayList<>(mDataCallResponses.get(
-                                transport).values()), null));
-                return null;
-            }).when(mMockedDataServiceManagers.get(transport)).deactivateDataCall(
-                    anyInt(), anyInt(), any(Message.class));
-
-            doAnswer(invocation -> {
-                Handler h = (Handler) invocation.getArguments()[0];
-                int what = (int) invocation.getArguments()[1];
-                mDataCallListChangedRegistrants.get(transport).addUnique(h, what, transport);
-                return null;
-            }).when(mMockedDataServiceManagers.get(transport)).registerForDataCallListChanged(any(
-                    Handler.class), anyInt());
-        }
-
-        doReturn(-1).when(mPhone).getSubId();
-
-        // Note that creating a "real" data network controller will also result in creating
-        // real DataRetryManager, DataConfigManager, etc...Normally in unit test we should isolate
-        // other modules and make them mocked, but only focusing on testing the unit we would like
-        // to test, in this case, DataNetworkController. But since there are too many interactions
-        // between DataNetworkController and its sub-modules, we intend to make those modules "real"
-        // as well, except some modules below we replaced with mocks.
-        mDataNetworkControllerUT = new DataNetworkController(mPhone, Looper.myLooper());
-        doReturn(mDataNetworkControllerUT).when(mPhone).getDataNetworkController();
-
-        doReturn(1).when(mPhone).getSubId();
-        mDataNetworkControllerUT.obtainMessage(15/*EVENT_SUBSCRIPTION_CHANGED*/).sendToTarget();
-
-        processAllMessages();
-        // Clear the callbacks created by the real sub-modules created by DataNetworkController.
-        clearCallbacks();
-        SparseArray<DataServiceManager> dataServiceManagers = new SparseArray<>();
-        dataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                mMockedWwanDataServiceManager);
-        dataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
-                mMockedWlanDataServiceManager);
-        replaceInstance(DataNetworkController.class, "mDataServiceManagers",
-                mDataNetworkControllerUT, dataServiceManagers);
-        replaceInstance(DataNetworkController.class, "mDataProfileManager",
-                mDataNetworkControllerUT, mDataProfileManager);
-        replaceInstance(DataNetworkController.class, "mAccessNetworksManager",
-                mDataNetworkControllerUT, mAccessNetworksManager);
-        replaceInstance(ImsResolver.class, "sInstance", null, mMockedImsResolver);
-
-        ArgumentCaptor<AccessNetworksManagerCallback> callbackCaptor =
-                ArgumentCaptor.forClass(AccessNetworksManagerCallback.class);
-        verify(mAccessNetworksManager).registerCallback(callbackCaptor.capture());
-        mAccessNetworksManagerCallback = callbackCaptor.getValue();
-
-        ArgumentCaptor<LinkBandwidthEstimatorCallback> linkBandwidthEstimatorCallbackCaptor =
-                ArgumentCaptor.forClass(LinkBandwidthEstimatorCallback.class);
-        verify(mLinkBandwidthEstimator).registerCallback(
-                linkBandwidthEstimatorCallbackCaptor.capture());
-        mLinkBandwidthEstimatorCallback = linkBandwidthEstimatorCallbackCaptor.getValue();
-
-        List<DataProfile> profiles = List.of(mGeneralPurposeDataProfile,
-                mImsCellularDataProfile,
-                mImsIwlanDataProfile, mEmergencyDataProfile, mFotaDataProfile,
-                mTetheringDataProfile);
-
-        doAnswer(invocation -> {
-            TelephonyNetworkRequest networkRequest =
-                    (TelephonyNetworkRequest) invocation.getArguments()[0];
-            int networkType = (int) invocation.getArguments()[1];
-
-            for (DataProfile dataProfile : profiles) {
-                if (dataProfile.canSatisfy(networkRequest.getCapabilities())
-                        && (dataProfile.getApnSetting().getNetworkTypeBitmask() == 0
-                        || (dataProfile.getApnSetting().getNetworkTypeBitmask()
-                        & ServiceState.getBitmaskForTech(networkType)) != 0)) {
-                    return dataProfile;
-                }
-            }
-            logd("Cannot find data profile to satisfy " + networkRequest + ", network type="
-                    + TelephonyManager.getNetworkTypeName(networkType));
-            return null;
-        }).when(mDataProfileManager).getDataProfileForNetworkRequest(
-                any(TelephonyNetworkRequest.class), anyInt());
-
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
-                .getPreferredTransportByNetworkCapability(anyInt());
-        doReturn(true).when(mDataProfileManager).isDataProfilePreferred(any(DataProfile.class));
-        doAnswer(invocation -> {
-            String apnName = (String) invocation.getArguments()[0];
-            TrafficDescriptor td = (TrafficDescriptor) invocation.getArguments()[1];
-
-            List<DataProfile> dps = profiles;
-
-            if (td != null) {
-                dps = dps.stream()
-                        .filter(dp -> td.equals(dp.getTrafficDescriptor()))
-                        .collect(Collectors.toList());
-            }
-
-            if (apnName != null) {
-                dps = dps.stream()
-                        .filter(dp -> dp.getApnSetting() != null)
-                        .filter(dp -> apnName.equals(dp.getApnSetting().getApnName()))
-                        .collect(Collectors.toList());
-            }
-
-            return dps.isEmpty() ? null : dps.get(0);
-        }).when(mDataProfileManager).getDataProfile(anyString(), any());
-
-        doAnswer(invocation -> {
-            ((Runnable) invocation.getArguments()[0]).run();
-            return null;
-        }).when(mMockedDataNetworkControllerCallback).invokeFromExecutor(any(Runnable.class));
-        doAnswer(invocation -> {
-            ((Runnable) invocation.getArguments()[0]).run();
-            return null;
-        }).when(mMockedDataRetryManagerCallback).invokeFromExecutor(any(Runnable.class));
-
-        mDataNetworkControllerUT.registerDataNetworkControllerCallback(
-                mMockedDataNetworkControllerCallback);
-
-        mDataNetworkControllerUT.obtainMessage(9/*EVENT_SIM_STATE_CHANGED*/,
-                10/*SIM_STATE_LOADED*/, 0).sendToTarget();
-        mDataNetworkControllerUT.obtainMessage(8/*EVENT_DATA_SERVICE_BINDING_CHANGED*/,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, true, null))
-                .sendToTarget();
-        mDataNetworkControllerUT.obtainMessage(8/*EVENT_DATA_SERVICE_BINDING_CHANGED*/,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, true, null))
-                .sendToTarget();
-
-        ArgumentCaptor<ImsStateCallback> imsCallbackCaptor =
-                ArgumentCaptor.forClass(ImsStateCallback.class);
-        verify(mMockedImsMmTelManager).registerImsStateCallback(any(Executor.class),
-                imsCallbackCaptor.capture());
-        mMmtelStateCallback = imsCallbackCaptor.getValue();
-
-        verify(mMockedImsRcsManager).registerImsStateCallback(any(Executor.class),
-                imsCallbackCaptor.capture());
-        mRcsStateCallback = imsCallbackCaptor.getValue();
-
-        carrierConfigChanged();
-
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-
-        // IMS registration
-        doReturn(FAKE_MMTEL_PACKAGE).when(mMockedImsResolver).getConfiguredImsServicePackageName(
-                anyInt(), eq(ImsFeature.FEATURE_MMTEL));
-        doReturn(FAKE_RCS_PACKAGE).when(mMockedImsResolver).getConfiguredImsServicePackageName(
-                anyInt(), eq(ImsFeature.FEATURE_RCS));
-
-        mMmtelStateCallback.onAvailable();
-        mRcsStateCallback.onAvailable();
-
-        ArgumentCaptor<RegistrationCallback> regCallbackCaptor =
-                ArgumentCaptor.forClass(RegistrationCallback.class);
-
-        verify(mMockedImsMmTelManager).registerImsRegistrationCallback(any(Executor.class),
-                regCallbackCaptor.capture());
-        mMmtelRegCallback = regCallbackCaptor.getValue();
-
-        verify(mMockedImsRcsManager).registerImsRegistrationCallback(any(Executor.class),
-                regCallbackCaptor.capture());
-        mRcsRegCallback = regCallbackCaptor.getValue();
-
-        processAllMessages();
-
-        logd("DataNetworkControllerTest -Setup!");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        logd("tearDown");
-        mMockedDataServiceManagers.clear();
-        mDataCallListChangedRegistrants.clear();
-        mDataNetworkControllerUT = null;
-        mCarrierConfig = null;
-        super.tearDown();
-    }
-
-    private @NonNull TelephonyNetworkRequest createNetworkRequest(Integer... capabilities) {
-        NetworkCapabilities netCaps = new NetworkCapabilities();
-        for (int networkCapability : capabilities) {
-            netCaps.addCapability(networkCapability);
-        }
-
-        NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
-                ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId, NetworkRequest.Type.REQUEST);
-
-        return new TelephonyNetworkRequest(nativeNetworkRequest, mPhone);
-    }
-
-    // The purpose of this test is to make sure the network request insertion/removal works as
-    // expected, and make sure it is always sorted.
-    @Test
-    public void testNetworkRequestList() {
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-
-        TelephonyNetworkRequest internetNetworkRequest = createNetworkRequest(
-                NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        TelephonyNetworkRequest eimsNetworkRequest = createNetworkRequest(
-                NetworkCapabilities.NET_CAPABILITY_EIMS);
-        TelephonyNetworkRequest mmsNetworkRequest = createNetworkRequest(
-                NetworkCapabilities.NET_CAPABILITY_MMS);
-        networkRequestList.add(internetNetworkRequest);
-        networkRequestList.add(eimsNetworkRequest);
-        networkRequestList.add(mmsNetworkRequest);
-
-        // Check if emergency has the highest priority, then mms, then internet.
-        assertThat(networkRequestList.get(0).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_EIMS);
-        assertThat(networkRequestList.get(1).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_MMS);
-        assertThat(networkRequestList.get(2).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        // Add IMS
-        TelephonyNetworkRequest imsNetworkRequest = createNetworkRequest(
-                NetworkCapabilities.NET_CAPABILITY_IMS);
-        assertThat(networkRequestList.add(imsNetworkRequest)).isTrue();
-
-        assertThat(networkRequestList.get(0).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_EIMS);
-        assertThat(networkRequestList.get(1).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_MMS);
-        assertThat(networkRequestList.get(2).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_IMS);
-        assertThat(networkRequestList.get(3).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        // Add IMS again
-        assertThat(networkRequestList.add(imsNetworkRequest)).isFalse();
-        assertThat(networkRequestList.size()).isEqualTo(4);
-
-        // Remove MMS
-        assertThat(networkRequestList.remove(mmsNetworkRequest)).isTrue();
-        assertThat(networkRequestList.get(0).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_EIMS);
-        assertThat(networkRequestList.get(1).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_IMS);
-        assertThat(networkRequestList.get(2).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        // Remove EIMS
-        assertThat(networkRequestList.remove(eimsNetworkRequest)).isTrue();
-        assertThat(networkRequestList.get(0).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_IMS);
-        assertThat(networkRequestList.get(1).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        // Remove Internet
-        assertThat(networkRequestList.remove(internetNetworkRequest)).isTrue();
-        assertThat(networkRequestList.get(0).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_IMS);
-
-        // Remove XCAP (which does not exist)
-        assertThat(networkRequestList.remove(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_XCAP))).isFalse();
-        assertThat(networkRequestList.get(0).getCapabilities()[0])
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_IMS);
-
-        // Remove IMS
-        assertThat(networkRequestList.remove(imsNetworkRequest)).isTrue();
-        assertThat(networkRequestList).isEmpty();
-    }
-
-    private @NonNull List<DataNetwork> getDataNetworks() throws Exception {
-        Field field = DataNetworkController.class.getDeclaredField("mDataNetworkList");
-        field.setAccessible(true);
-        return (List<DataNetwork>) field.get(mDataNetworkControllerUT);
-    }
-
-    private void verifyInternetConnected() throws Exception {
-        verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkConnected(any());
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-    }
-
-    private void verifyConnectedNetworkHasCapabilities(@NetCapability int... networkCapabilities)
-            throws Exception {
-        List<DataNetwork> dataNetworkList = getDataNetworks();
-        for (DataNetwork dataNetwork : getDataNetworks()) {
-            if (dataNetwork.isConnected() && Arrays.stream(networkCapabilities).boxed()
-                    .allMatch(dataNetwork.getNetworkCapabilities()::hasCapability)) {
-                return;
-            }
-        }
-        fail("No network with " + DataUtils.networkCapabilitiesToString(networkCapabilities)
-                + " is connected. dataNetworkList=" + dataNetworkList);
-    }
-
-    private void verifyNoConnectedNetworkHasCapability(@NetCapability int networkCapability)
-            throws Exception {
-        for (DataNetwork dataNetwork : getDataNetworks()) {
-            assertWithMessage("Network " + dataNetwork + " should not be connected.")
-                    .that(dataNetwork.isConnected() && dataNetwork.getNetworkCapabilities()
-                            .hasCapability(networkCapability)).isFalse();
-        }
-    }
-
-    private void verifyConnectedNetworkHasDataProfile(@NonNull DataProfile dataProfile)
-            throws Exception {
-        List<DataNetwork> dataNetworkList = getDataNetworks();
-        for (DataNetwork dataNetwork : getDataNetworks()) {
-            if (dataNetwork.isConnected() && dataNetwork.getDataProfile().equals(dataProfile)) {
-                return;
-            }
-        }
-        fail("No network with " + dataProfile + " is connected. dataNetworkList="
-                + dataNetworkList);
-    }
-
-    private void verifyAllDataDisconnected() throws Exception {
-        List<DataNetwork> dataNetworkList = getDataNetworks();
-        assertWithMessage("All data should be disconnected but it's not. " + dataNetworkList)
-                .that(dataNetworkList).isEmpty();
-    }
-
-    // To test the basic data setup. Copy this as example for other tests.
-    @Test
-    public void testSetupDataNetwork() throws Exception {
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllMessages();
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
-
-        List<DataNetwork> dataNetworkList = getDataNetworks();
-        assertThat(dataNetworkList).hasSize(1);
-        DataNetwork dataNetwork = dataNetworkList.get(0);
-        assertThat(dataNetworkList.get(0).getLinkProperties().getAddresses()).containsExactly(
-                InetAddresses.parseNumericAddress(IPV4_ADDRESS),
-                InetAddresses.parseNumericAddress(IPV6_ADDRESS));
-
-        verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkConnected(any());
-    }
-
-    @Test
-    public void testSetupImsDataNetwork() throws Exception {
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS,
-                        NetworkCapabilities.NET_CAPABILITY_MMTEL));
-        processAllMessages();
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-        verifyConnectedNetworkHasDataProfile(mImsCellularDataProfile);
-        List<DataNetwork> dataNetworkList = getDataNetworks();
-        assertThat(dataNetworkList.get(0).getLinkProperties().getAddresses()).containsExactly(
-                InetAddresses.parseNumericAddress(IPV4_ADDRESS),
-                InetAddresses.parseNumericAddress(IPV6_ADDRESS));
-    }
-
-    @Test
-    public void testSetupEnterpriseDataNetwork() throws Exception {
-        List<TrafficDescriptor> tdList = new ArrayList<>();
-        tdList.add(new TrafficDescriptor.Builder()
-                .setOsAppId(new OsAppId(OsAppId.ANDROID_OS_ID, "ENTERPRISE", 1).getBytes())
-                .build());
-        setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager,
-                createDataCallResponse(1, DataCallResponse.LINK_STATUS_ACTIVE, tdList));
-        doReturn(mEnterpriseDataProfile).when(mDataProfileManager)
-                .getDataProfileForNetworkRequest(any(TelephonyNetworkRequest.class), anyInt());
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE));
-        processAllMessages();
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE);
-        List<DataNetwork> dataNetworkList = getDataNetworks();
-        assertThat(dataNetworkList.get(0).getLinkProperties().getAddresses()).containsExactly(
-                InetAddresses.parseNumericAddress(IPV4_ADDRESS),
-                InetAddresses.parseNumericAddress(IPV6_ADDRESS));
-    }
-
-    @Test
-    public void testDataNetworkControllerCallback() throws Exception {
-        mDataNetworkControllerUT.registerDataNetworkControllerCallback(
-                mMockedDataNetworkControllerCallback);
-        processAllMessages();
-        testSetupDataNetwork();
-        verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(true));
-        verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkConnected(any());
-
-        mDataNetworkControllerUT.unregisterDataNetworkControllerCallback(
-                mMockedDataNetworkControllerCallback);
-        processAllMessages();
-    }
-
-    @Test
-    public void testSimRemovalDataTearDown() throws Exception {
-        testSetupDataNetwork();
-
-        mDataNetworkControllerUT.obtainMessage(9/*EVENT_SIM_STATE_CHANGED*/,
-                TelephonyManager.SIM_STATE_ABSENT, 0).sendToTarget();
-        processAllMessages();
-        verifyAllDataDisconnected();
-        verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
-        verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkDisconnected();
-    }
-
-    @Test
-    public void testSimRemovalAndThenInserted() throws Exception {
-        testSimRemovalDataTearDown();
-        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
-
-        // Insert the SIM again.
-        mDataNetworkControllerUT.obtainMessage(9/*EVENT_SIM_STATE_CHANGED*/,
-                TelephonyManager.SIM_STATE_LOADED, 0).sendToTarget();
-        processAllMessages();
-
-        verifyInternetConnected();
-    }
-
-    @Test
-    public void testDuplicateInterface() throws Exception {
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllMessages();
-
-        // The fota network request would result in duplicate interface.
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_FOTA));
-        processAllFutureMessages();
-
-        // There should be only one network.
-        List<DataNetwork> dataNetworkList = getDataNetworks();
-        assertThat(dataNetworkList).hasSize(1);
-        assertThat(dataNetworkList.get(0).getDataProfile()).isEqualTo(mGeneralPurposeDataProfile);
-        verifyInternetConnected();
-        // Fota should not be connected.
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
-
-        // There should be exactly 2 setup data call requests.
-        verify(mMockedWwanDataServiceManager, times(2)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-    }
-
-    @Test
-    public void testMovingFromNoServiceToInService() throws Exception {
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING);
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllMessages();
-
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        // Network becomes in-service.
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-
-        verifyInternetConnected();
-    }
-
-    @Test
-    public void testMovingFromInServiceToNoService() throws Exception {
-        testSetupDataNetwork();
-
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING);
-        // Verify we don't tear down the data network.
-        verifyInternetConnected();
-
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_UNKNOWN,
-                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING);
-        // Verify we don't tear down the data network.
-        verifyInternetConnected();
-    }
-
-    @Test
-    public void testPsRestrictedAndLifted() throws Exception {
-        testSetupDataNetwork();
-        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
-
-        // PS restricted, existing PDN should stay.
-        mDataNetworkControllerUT.obtainMessage(6/*EVENT_PS_RESTRICT_ENABLED*/).sendToTarget();
-        processAllMessages();
-
-        List<DataNetwork> dataNetworkList = getDataNetworks();
-        assertThat(dataNetworkList).hasSize(1);
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        // PS restricted, new setup NOT allowed
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS,
-                        NetworkCapabilities.NET_CAPABILITY_MMTEL));
-        setSuccessfulSetupDataResponse(mMockedDataServiceManagers
-                .get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), 2);
-        processAllMessages();
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-
-        // PS unrestricted, new setup is allowed
-        mDataNetworkControllerUT.obtainMessage(7/*EVENT_PS_RESTRICT_DISABLED*/).sendToTarget();
-        processAllMessages();
-
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-    }
-
-    @Test
-    public void testRatChanges() throws Exception {
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-
-        testSetupDataNetwork();
-
-        // Now RAT changes from LTE to UMTS, make sure the network is lingered.
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_UMTS,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-        verifyInternetConnected();
-
-        // Now RAT changes from UMTS to GSM
-        doReturn(null).when(mDataProfileManager).getDataProfileForNetworkRequest(
-                any(TelephonyNetworkRequest.class), eq(TelephonyManager.NETWORK_TYPE_GSM));
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_GSM,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-        verifyAllDataDisconnected();
-        verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
-        verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkDisconnected();
-
-
-        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
-        // Now RAT changes from GSM to UMTS
-        doReturn(null).when(mDataProfileManager).getDataProfileForNetworkRequest(
-                any(TelephonyNetworkRequest.class), eq(TelephonyManager.NETWORK_TYPE_UMTS));
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_UMTS,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        doReturn(mGeneralPurposeDataProfile).when(mDataProfileManager)
-                .getDataProfileForNetworkRequest(any(TelephonyNetworkRequest.class), anyInt());
-        // Now RAT changes from UMTS to LTE
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-        verifyInternetConnected();
-    }
-
-    @Test
-    public void testRatChangesLingeringNotSet() throws Exception {
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-        TelephonyNetworkRequest fotaRequest = createNetworkRequest(
-                NetworkCapabilities.NET_CAPABILITY_FOTA);
-        mDataNetworkControllerUT.addNetworkRequest(fotaRequest);
-        processAllMessages();
-
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_FOTA);
-
-        // Now RAT changes from LTE to UMTS, since FOTA APN does not have lingering set, only
-        // network type bitmask should be used. Fota network should be torn down.
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_UMTS,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-        processAllMessages();
-
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
-        verifyAllDataDisconnected();
-    }
-
-    @Test
-    public void testVoiceCallEndedOnVoiceDataNonConcurrentNetwork() throws Exception {
-        doReturn(false).when(mSST).isConcurrentVoiceAndDataAllowed();
-        doReturn(PhoneConstants.State.OFFHOOK).when(mCT).getState();
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllMessages();
-
-        // Data should not be allowed when voice/data concurrent is not supported.
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        // Call ended.
-        doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
-        mDataNetworkControllerUT.obtainMessage(18/*EVENT_VOICE_CALL_ENDED*/).sendToTarget();
-        processAllMessages();
-
-        // It should have no internet setup at the beginning.
-        verifyAllDataDisconnected();
-
-        // But after some delays data should be restored.
-        moveTimeForward(500);
-        processAllMessages();
-        verifyInternetConnected();
-    }
-
-    @Test
-    public void testEcbmChanged() throws Exception {
-        doReturn(true).when(mPhone).isInCdmaEcm();
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllMessages();
-
-        // Data should not be allowed when the device is in ECBM.
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        // Exit ECBM
-        doReturn(false).when(mPhone).isInCdmaEcm();
-        mDataNetworkControllerUT.obtainMessage(20/*EVENT_EMERGENCY_CALL_CHANGED*/).sendToTarget();
-        processAllMessages();
-
-        // Verify data is restored.
-        verifyInternetConnected();
-    }
-
-    @Test
-    public void testRoamingDataChanged() throws Exception {
-        doReturn(true).when(mServiceState).getDataRoaming();
-
-        // Roaming data disabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(false);
-        processAllMessages();
-
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllMessages();
-
-        // Data should not be allowed when roaming data is disabled.
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
-
-        // Roaming data enabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(true);
-        processAllMessages();
-
-        // Verify data is restored.
-        verifyInternetConnected();
-        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
-
-        // Roaming data disabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(false);
-        processAllMessages();
-
-        // Verify data is torn down.
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-    }
-
-    @Test
-    public void testDataEnabledChanged() throws Exception {
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, false, mContext.getOpPackageName());
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllMessages();
-
-        // Data should not be allowed when user data is disabled.
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
-
-        // User data enabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, true, mContext.getOpPackageName());
-        processAllMessages();
-
-        // Verify data is restored.
-        verifyInternetConnected();
-        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
-
-        // User data disabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, false, mContext.getOpPackageName());
-        processAllMessages();
-
-        // Verify data is torn down.
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-    }
-
-    @Test
-    public void testNotifyWhenSetDataEnabled() throws Exception {
-        // Set a valid sub id, DEFAULT_SUBSCRIPTION_ID
-        int subId = Integer.MAX_VALUE;
-        Field field = DataSettingsManager.class.getDeclaredField("mSubId");
-        field.setAccessible(true);
-        field.setInt(mDataNetworkControllerUT.getDataSettingsManager(), subId);
-        boolean isDataEnabled = mDataNetworkControllerUT.getDataSettingsManager().isDataEnabled();
-        doReturn(mDataNetworkControllerUT.getDataSettingsManager())
-                .when(mPhone).getDataSettingsManager();
-        MultiSimSettingController instance = MultiSimSettingController.getInstance();
-        MultiSimSettingController controller = Mockito.spy(
-                new MultiSimSettingController(mContext, mSubscriptionController));
-        doReturn(true).when(controller).isCarrierConfigLoadedForAllSub();
-        replaceInstance(MultiSimSettingController.class, "sInstance", null, controller);
-
-        controller.notifyAllSubscriptionLoaded();
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, !isDataEnabled,
-                mContext.getOpPackageName());
-        processAllMessages();
-
-        // Verify not to notify MultiSimSettingController
-        verify(controller, never()).notifyUserDataEnabled(anyInt(), anyBoolean());
-
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, isDataEnabled,
-                mContext.getOpPackageName());
-        processAllMessages();
-
-        // Verify not to notify MultiSimSettingController
-        verify(controller, never()).notifyUserDataEnabled(anyInt(), anyBoolean());
-
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, !isDataEnabled, "com.android.settings");
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, isDataEnabled, "com.android.settings");
-        processAllMessages();
-
-        // Verify to notify MultiSimSettingController exactly 2 times
-        verify(controller, times(2)).notifyUserDataEnabled(anyInt(), anyBoolean());
-    }
-
-    @Test
-    public void testMmsAlwaysAllowedDataDisabled() throws Exception {
-        // Data disabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, false, mContext.getOpPackageName());
-        // Always allow MMS
-        mDataNetworkControllerUT.getDataSettingsManager().setAlwaysAllowMmsData(true);
-        processAllMessages();
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_MMS));
-        processAllMessages();
-
-        // Make sure MMS is the only capability advertised, but not internet or SUPL.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_MMS);
-        verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
-
-        // Remove MMS data enabled override
-        mDataNetworkControllerUT.getDataSettingsManager().setAlwaysAllowMmsData(false);
-        processAllMessages();
-
-        // Make sure MMS is torn down when the override is disabled.
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
-    }
-
-    @Test
-    public void testMmsAlwaysAllowedRoamingDisabled() throws Exception {
-        // Data roaming disabled
-        doReturn(true).when(mServiceState).getDataRoaming();
-        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(false);
-        processAllMessages();
-
-        // Device is roaming
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
-        // Always allow MMS
-        mDataNetworkControllerUT.getDataSettingsManager().setAlwaysAllowMmsData(true);
-        processAllMessages();
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_MMS));
-        processAllMessages();
-
-        // Make sure MMS is not allowed. MMS always allowed should be only applicable to data
-        // disabled case.
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
-    }
-
-    @Test
-    public void testUnmeteredRequestPreferredOnIwlan() throws Exception {
-        // Preferred on cellular
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
-                .getPreferredTransportByNetworkCapability(anyInt());
-        // Data disabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, false, mContext.getOpPackageName());
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllMessages();
-
-        // Data should not be allowed when roaming + user data are disabled (soft failure reasons)
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        // Set transport to WLAN (unmetered)
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
-                .getPreferredTransportByNetworkCapability(
-                        eq(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        // Data remain disabled, but trigger the preference evaluation.
-        mDataNetworkControllerUT.obtainMessage(21 /*EVENT_EVALUATE_PREFERRED_TRANSPORT*/,
-                NetworkCapabilities.NET_CAPABILITY_INTERNET, 0).sendToTarget();
-        mDataNetworkControllerUT.obtainMessage(5 /*EVENT_REEVALUATE_UNSATISFIED_NETWORK_REQUESTS*/,
-                DataEvaluation.DataEvaluationReason.PREFERRED_TRANSPORT_CHANGED).sendToTarget();
-        processAllMessages();
-
-        // Verify data is allowed even if data is disabled.
-        verifyInternetConnected();
-    }
-
-    @Test
-    public void testUnmeteredRequestDataRoamingDisabled() throws Exception {
-        // Data roaming disabled
-        doReturn(true).when(mServiceState).getDataRoaming();
-        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(false);
-        processAllMessages();
-
-        // MMS is unmetered
-        mCarrierConfig.putStringArray(
-                CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
-                new String[]{"default", "dun", "supl"});
-        carrierConfigChanged();
-        // Manually set data roaming to false in case ro.com.android.dataroaming is true.
-        // TODO(b/232575718): Figure out a way to mock ro.com.android.dataroaming for tests.
-        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(false);
-        // Device is roaming
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_MMS));
-        processAllMessages();
-
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_MMS);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-    }
-
-    @Test
-    public void testUnmeteredRequestDataDisabled() throws Exception {
-        // MMS is unmetered
-        mCarrierConfig.putStringArray(
-                CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
-                new String[]{"default", "dun", "supl"});
-        carrierConfigChanged();
-
-        // Data disabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, false, mContext.getOpPackageName());
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_MMS));
-
-        processAllMessages();
-
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_MMS);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-    }
-
-    @Test
-    public void testEmergencyRequest() throws Exception {
-        // Data disabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, false, mContext.getOpPackageName());
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_EIMS));
-        processAllMessages();
-
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_EIMS);
-        verifyConnectedNetworkHasDataProfile(mEmergencyDataProfile);
-    }
-
-    @Test
-    public void testHandoverRuleFromString() {
-        HandoverRule handoverRule = new HandoverRule("source=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN, "
-                + "target=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN, type=allowed");
-        assertThat(handoverRule.sourceAccessNetworks).containsExactly(AccessNetworkType.GERAN,
-                AccessNetworkType.UTRAN, AccessNetworkType.EUTRAN, AccessNetworkType.NGRAN,
-                AccessNetworkType.IWLAN);
-        assertThat(handoverRule.targetAccessNetworks).containsExactly(AccessNetworkType.GERAN,
-                AccessNetworkType.UTRAN, AccessNetworkType.EUTRAN, AccessNetworkType.NGRAN,
-                AccessNetworkType.IWLAN);
-        assertThat(handoverRule.type).isEqualTo(HandoverRule.RULE_TYPE_ALLOWED);
-        assertThat(handoverRule.isOnlyForRoaming).isFalse();
-        assertThat(handoverRule.networkCapabilities).isEmpty();
-
-        handoverRule = new HandoverRule("source=   NGRAN|     IWLAN, "
-                + "target  =    EUTRAN,    type  =    disallowed ");
-        assertThat(handoverRule.sourceAccessNetworks).containsExactly(AccessNetworkType.NGRAN,
-                AccessNetworkType.IWLAN);
-        assertThat(handoverRule.targetAccessNetworks).containsExactly(AccessNetworkType.EUTRAN);
-        assertThat(handoverRule.type).isEqualTo(HandoverRule.RULE_TYPE_DISALLOWED);
-        assertThat(handoverRule.isOnlyForRoaming).isFalse();
-        assertThat(handoverRule.networkCapabilities).isEmpty();
-
-        handoverRule = new HandoverRule("source=   IWLAN, "
-                + "target  =    EUTRAN,    type  =    disallowed, roaming = true,"
-                + " capabilities = IMS | EIMS ");
-        assertThat(handoverRule.sourceAccessNetworks).containsExactly(AccessNetworkType.IWLAN);
-        assertThat(handoverRule.targetAccessNetworks).containsExactly(AccessNetworkType.EUTRAN);
-        assertThat(handoverRule.type).isEqualTo(HandoverRule.RULE_TYPE_DISALLOWED);
-        assertThat(handoverRule.networkCapabilities).containsExactly(
-                NetworkCapabilities.NET_CAPABILITY_IMS, NetworkCapabilities.NET_CAPABILITY_EIMS);
-        assertThat(handoverRule.isOnlyForRoaming).isTrue();
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new HandoverRule("V2hhdCBUaGUgRnVjayBpcyB0aGlzIQ=="));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new HandoverRule("target=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN, type=allowed"));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new HandoverRule("source=GERAN|UTRAN|EUTRAN|NGRAN|IWLAN, type=allowed"));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new HandoverRule("source=GERAN, target=IWLAN, type=wtf"));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new HandoverRule("source=GERAN, target=NGRAN, type=allowed"));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new HandoverRule("source=IWLAN, target=WTFRAN, type=allowed"));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new HandoverRule("source=IWLAN, target=|, type=allowed"));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new HandoverRule("source=GERAN, target=IWLAN, type=allowed, capabilities=|"));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new HandoverRule("source=GERAN, target=IWLAN, type=allowed, capabilities="));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new HandoverRule("source=GERAN, target=IWLAN, type=allowed, "
-                        + "capabilities=wtf"));
-    }
-
-    @Test
-    public void testIsNetworkTypeCongested() throws Exception {
-        Set<Integer> congestedNetworkTypes = new ArraySet<>();
-        doReturn(congestedNetworkTypes).when(mDataNetworkController)
-                .getCongestedOverrideNetworkTypes();
-        testSetupDataNetwork();
-        DataNetwork dataNetwork = getDataNetworks().get(0);
-
-        // Set 5G unmetered
-        congestedNetworkTypes.add(TelephonyManager.NETWORK_TYPE_NR);
-        mDataNetworkControllerUT.obtainMessage(23/*EVENT_SUBSCRIPTION_OVERRIDE*/,
-                NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED,
-                NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED,
-                new int[]{TelephonyManager.NETWORK_TYPE_NR}).sendToTarget();
-        dataNetwork.sendMessage(16/*EVENT_SUBSCRIPTION_PLAN_OVERRIDE*/);
-        processAllMessages();
-        assertEquals(congestedNetworkTypes,
-                mDataNetworkControllerUT.getCongestedOverrideNetworkTypes());
-        assertTrue(dataNetwork.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED));
-
-        // Change data network type to NR
-        doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_NR,
-                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE))
-                .when(mDisplayInfoController).getTelephonyDisplayInfo();
-        dataNetwork.sendMessage(13/*EVENT_DISPLAY_INFO_CHANGED*/);
-        processAllMessages();
-        assertFalse(dataNetwork.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED));
-
-        // Set all network types metered
-        congestedNetworkTypes.clear();
-        mDataNetworkControllerUT.obtainMessage(23/*EVENT_SUBSCRIPTION_OVERRIDE*/,
-                NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_CONGESTED, 0,
-                TelephonyManager.getAllNetworkTypes()).sendToTarget();
-        dataNetwork.sendMessage(16/*EVENT_SUBSCRIPTION_PLAN_OVERRIDE*/);
-        processAllMessages();
-        assertTrue(mDataNetworkControllerUT.getCongestedOverrideNetworkTypes().isEmpty());
-        assertTrue(dataNetwork.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_CONGESTED));
-    }
-
-    @Test
-    public void testIsNetworkTypeUnmeteredViaSubscriptionOverride() throws Exception {
-        Set<Integer> unmeteredNetworkTypes = new ArraySet<>();
-        doReturn(unmeteredNetworkTypes).when(mDataNetworkController)
-                .getUnmeteredOverrideNetworkTypes();
-        testSetupDataNetwork();
-        DataNetwork dataNetwork = getDataNetworks().get(0);
-
-        // Set 5G unmetered
-        unmeteredNetworkTypes.add(TelephonyManager.NETWORK_TYPE_NR);
-        mDataNetworkControllerUT.obtainMessage(23/*EVENT_SUBSCRIPTION_OVERRIDE*/,
-                NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED,
-                NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED,
-                new int[]{TelephonyManager.NETWORK_TYPE_NR}).sendToTarget();
-        dataNetwork.sendMessage(16/*EVENT_SUBSCRIPTION_PLAN_OVERRIDE*/);
-        processAllMessages();
-        assertEquals(unmeteredNetworkTypes,
-                mDataNetworkControllerUT.getUnmeteredOverrideNetworkTypes());
-        assertFalse(dataNetwork.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED));
-        assertThat(mDataNetworkControllerUT.isInternetUnmetered()).isFalse();
-
-        // Change data network type to NR
-        doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_NR,
-                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE))
-                .when(mDisplayInfoController).getTelephonyDisplayInfo();
-        dataNetwork.sendMessage(13/*EVENT_DISPLAY_INFO_CHANGED*/);
-        processAllMessages();
-        assertTrue(dataNetwork.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED));
-        assertThat(mDataNetworkControllerUT.isInternetUnmetered()).isTrue();
-
-        // Set all network types metered
-        unmeteredNetworkTypes.clear();
-        mDataNetworkControllerUT.obtainMessage(23/*EVENT_SUBSCRIPTION_OVERRIDE*/,
-                NetworkPolicyManager.SUBSCRIPTION_OVERRIDE_UNMETERED, 0,
-                TelephonyManager.getAllNetworkTypes()).sendToTarget();
-        dataNetwork.sendMessage(16/*EVENT_SUBSCRIPTION_PLAN_OVERRIDE*/);
-        processAllMessages();
-        assertTrue(mDataNetworkControllerUT.getUnmeteredOverrideNetworkTypes().isEmpty());
-        assertFalse(dataNetwork.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED));
-        assertThat(mDataNetworkControllerUT.isInternetUnmetered()).isFalse();
-    }
-
-    @Test
-    public void testIsNetworkTypeUnmeteredViaSubscriptionPlans() throws Exception {
-        List<SubscriptionPlan> subscriptionPlans = new ArrayList<>();
-        doReturn(subscriptionPlans).when(mDataNetworkController).getSubscriptionPlans();
-        testSetupDataNetwork();
-        DataNetwork dataNetwork = getDataNetworks().get(0);
-
-        // Set 5G unmetered
-        SubscriptionPlan unmetered5GPlan = SubscriptionPlan.Builder
-                .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"),
-                        Period.ofMonths(1))
-                .setDataLimit(SubscriptionPlan.BYTES_UNLIMITED,
-                        SubscriptionPlan.LIMIT_BEHAVIOR_THROTTLED)
-                .setNetworkTypes(new int[]{TelephonyManager.NETWORK_TYPE_NR})
-                .build();
-        SubscriptionPlan generalMeteredPlan = SubscriptionPlan.Builder
-                .createRecurring(ZonedDateTime.parse("2007-03-14T00:00:00.000Z"),
-                        Period.ofMonths(1))
-                .setDataLimit(1_000_000_000, SubscriptionPlan.LIMIT_BEHAVIOR_DISABLED)
-                .setDataUsage(500_000_000, System.currentTimeMillis())
-                .build();
-        subscriptionPlans.add(generalMeteredPlan);
-        subscriptionPlans.add(unmetered5GPlan);
-        mDataNetworkControllerUT.obtainMessage(22/*EVENT_SUBSCRIPTION_PLANS_CHANGED*/,
-                new SubscriptionPlan[]{generalMeteredPlan, unmetered5GPlan}).sendToTarget();
-        dataNetwork.sendMessage(16/*EVENT_SUBSCRIPTION_PLAN_OVERRIDE*/);
-        processAllMessages();
-        assertEquals(subscriptionPlans, mDataNetworkControllerUT.getSubscriptionPlans());
-        assertFalse(dataNetwork.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED));
-        assertThat(mDataNetworkControllerUT.isInternetUnmetered()).isFalse();
-
-
-        // Change data network type to NR
-        doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_NR,
-                TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE))
-                .when(mDisplayInfoController).getTelephonyDisplayInfo();
-        dataNetwork.sendMessage(13/*EVENT_DISPLAY_INFO_CHANGED*/);
-        processAllMessages();
-        assertTrue(dataNetwork.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED));
-        assertThat(mDataNetworkControllerUT.isInternetUnmetered()).isTrue();
-
-        // Set all network types metered
-        subscriptionPlans.clear();
-        mDataNetworkControllerUT.obtainMessage(22/*EVENT_SUBSCRIPTION_PLANS_CHANGED*/,
-                new SubscriptionPlan[]{}).sendToTarget();
-        dataNetwork.sendMessage(16/*EVENT_SUBSCRIPTION_PLAN_OVERRIDE*/);
-        processAllMessages();
-        assertTrue(mDataNetworkControllerUT.getSubscriptionPlans().isEmpty());
-        assertFalse(dataNetwork.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED));
-        assertThat(mDataNetworkControllerUT.isInternetUnmetered()).isFalse();
-    }
-
-    @Test
-    public void testOnSinglePdnArbitrationExemptIms() throws Exception {
-        // On CDMA network, only one data network is allowed.
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_1xRTT,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-        // Preferred on cellular
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
-                .getPreferredTransportByNetworkCapability(anyInt());
-        // Add IMS
-        TelephonyNetworkRequest ims = createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-        mDataNetworkControllerUT.addNetworkRequest(ims);
-        processAllMessages();
-
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-
-        // Add internet, should be compatible with
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        setSuccessfulSetupDataResponse(mMockedDataServiceManagers
-                .get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), 2);
-        processAllMessages();
-
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-
-        // Add MMS, whose priority > internet, internet should be town down, IMS left untouched
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_MMS));
-        setSuccessfulSetupDataResponse(mMockedDataServiceManagers
-                .get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), 3);
-        processAllMessages();
-
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_MMS);
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-
-        // Temporarily remove IMS
-        mDataNetworkControllerUT.removeNetworkRequest(ims);
-        processAllMessages();
-        List<DataNetwork> dataNetworks = getDataNetworks();
-        dataNetworks.get(0).tearDown(DataNetwork.TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED);
-        processAllMessages();
-
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-
-        // Add IMS, should be compatible with the existing internet
-        setSuccessfulSetupDataResponse(mMockedDataServiceManagers
-                .get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN), 4);
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS));
-        processAllMessages();
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-    }
-
-    @Test
-    public void testLinkStatusChanged() throws Exception {
-        testSetupDataNetwork();
-        verify(mMockedDataNetworkControllerCallback).onPhysicalLinkStatusChanged(
-                eq(DataCallResponse.LINK_STATUS_ACTIVE));
-
-        DataNetwork dataNetwork = getDataNetworks().get(0);
-
-        DataCallResponse response = createDataCallResponse(1, DataCallResponse.LINK_STATUS_DORMANT);
-        dataNetwork.obtainMessage(8 /*EVENT_DATA_STATE_CHANGED */,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                        List.of(response), null)).sendToTarget();
-
-        processAllMessages();
-        verify(mMockedDataNetworkControllerCallback).onPhysicalLinkStatusChanged(
-                eq(DataCallResponse.LINK_STATUS_DORMANT));
-        assertThat(mDataNetworkControllerUT.getDataActivity()).isEqualTo(
-                TelephonyManager.DATA_ACTIVITY_DORMANT);
-    }
-
-    @Test
-    public void testHandoverDataNetwork() throws Exception {
-        testSetupImsDataNetwork();
-
-        DataNetwork dataNetwork = getDataNetworks().get(0);
-        // Before handover the data profile is the cellular IMS data profile
-        verifyConnectedNetworkHasDataProfile(mImsCellularDataProfile);
-
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
-        // Verify that IWLAN handover succeeded.
-        assertThat(dataNetwork.getTransport()).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
-        // After handover the data profile is the IWLAN IMS data profile
-        verifyConnectedNetworkHasDataProfile(mImsIwlanDataProfile);
-    }
-
-    @Test
-    public void testHandoverDataNetworkBackToBackPreferenceChanged() throws Exception {
-        testSetupImsDataNetwork();
-
-        Mockito.reset(mMockedWlanDataServiceManager);
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
-        // Capture the message for setup data call response. We want to delay it.
-        ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
-        verify(mMockedWlanDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class),
-                anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
-                messageCaptor.capture());
-
-        // Before setup data call response, change the preference back to cellular.
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-
-
-        // Before setup data call response, change the preference back to IWLAN.
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
-        // Finally handover is completed.
-        Message msg = messageCaptor.getValue();
-        DataCallResponse response = new DataCallResponse.Builder()
-                .setCause(DataFailCause.NONE)
-                .build();
-        msg.getData().putParcelable("data_call_response", response);
-        msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
-        msg.sendToTarget();
-        processAllMessages();
-
-        // Make sure handover request is only sent once.
-        verify(mMockedWlanDataServiceManager, times(1)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), messageCaptor.capture());
-    }
-
-    @Test
-    public void testHandoverDataNetworkNotAllowedByPolicy() throws Exception {
-        mCarrierConfig.putStringArray(CarrierConfigManager.KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY,
-                new String[]{"source=EUTRAN, target=IWLAN, type=disallowed, capabilities=MMS|IMS",
-                        "source=IWLAN, target=EUTRAN, type=disallowed, capabilities=MMS"});
-        // Force data config manager to reload the carrier config.
-        mDataNetworkControllerUT.getDataConfigManager().obtainMessage(
-                1/*EVENT_CARRIER_CONFIG_CHANGED*/).sendToTarget();
-        processAllMessages();
-
-        testSetupImsDataNetwork();
-
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        // After this, IMS data network should be disconnected, and DNC should attempt to
-        // establish a new one on IWLAN
-
-        // Verify all data disconnected.
-        verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
-
-        // A new data network should be connected on IWLAN
-        List<DataNetwork> dataNetworkList = getDataNetworks();
-        assertThat(dataNetworkList).hasSize(1);
-        assertThat(dataNetworkList.get(0).isConnected()).isTrue();
-        assertThat(dataNetworkList.get(0).getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_IMS)).isTrue();
-        assertThat(dataNetworkList.get(0).getTransport())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
-        // test IWLAN -> EUTRAN no need to tear down because the disallowed rule only applies to MMS
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
-                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-        mDataNetworkControllerUT.obtainMessage(21/*EVENT_PREFERRED_TRANSPORT_CHANGED*/,
-                NetworkCapabilities.NET_CAPABILITY_IMS, 0).sendToTarget();
-        Mockito.clearInvocations(mMockedWwanDataServiceManager);
-        processAllMessages();
-        // Verify that IWWAN handover succeeded.
-        assertThat(getDataNetworks().get(0).getTransport()).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        verify(mMockedWwanDataServiceManager, times(1)).setupDataCall(
-                anyInt(), any(), anyBoolean(), anyBoolean(),
-                eq(DataService.REQUEST_REASON_HANDOVER), any(), anyInt(), any(), any(), eq(true),
-                any());
-    }
-
-    @Test
-    public void testHandoverDataNetworkNotAllowedByRoamingPolicy() throws Exception {
-        mCarrierConfig.putStringArray(CarrierConfigManager.KEY_IWLAN_HANDOVER_POLICY_STRING_ARRAY,
-                new String[]{"source=EUTRAN|NGRAN|IWLAN, target=EUTRAN|NGRAN|IWLAN, roaming=true, "
-                        + "type=disallowed, capabilities=IMS"});
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
-        // Force data config manager to reload the carrier config.
-        mDataNetworkControllerUT.getDataConfigManager().obtainMessage(
-                1/*EVENT_CARRIER_CONFIG_CHANGED*/).sendToTarget();
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
-                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-
-        processAllMessages();
-
-        // Bring up IMS PDN on IWLAN
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS));
-        processAllMessages();
-        verifyConnectedNetworkHasDataProfile(mImsIwlanDataProfile);
-
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-
-        // Verify IMS PDN is connected.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-
-        // After this, IMS data network should be disconnected, and DNC should attempt to
-        // establish a new one on cellular
-        processAllMessages();
-
-        // Verify all data disconnected.
-        verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
-
-        // Should setup a new one instead of handover.
-        verify(mMockedWwanDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class),
-                anyBoolean(), anyBoolean(), eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-
-
-        // A new data network should be connected on IWLAN
-        List<DataNetwork> dataNetworkList = getDataNetworks();
-        assertThat(dataNetworkList).hasSize(1);
-        assertThat(dataNetworkList.get(0).isConnected()).isTrue();
-        assertThat(dataNetworkList.get(0).getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_IMS)).isTrue();
-        assertThat(dataNetworkList.get(0).getTransport())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-    }
-
-    @Test
-    public void testHandoverDataNetworkRetry() throws Exception {
-        testSetupImsDataNetwork();
-
-        setFailedSetupDataResponse(mMockedWlanDataServiceManager,
-                DataFailCause.HANDOVER_FAILED, -1, true);
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
-        DataNetwork dataNetwork = getDataNetworks().get(0);
-        // Verify that data network is still on cellular
-        assertThat(dataNetwork.getTransport()).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-
-        setSuccessfulSetupDataResponse(mMockedWlanDataServiceManager, 1);
-
-        processAllFutureMessages();
-
-        dataNetwork = getDataNetworks().get(0);
-        // Verify that data network is handovered to IWLAN
-        assertThat(dataNetwork.getTransport()).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-    }
-
-    @Test
-    public void testHandoverDataNetworkRetryReachedMaximum() throws Exception {
-        testSetupImsDataNetwork();
-
-        setFailedSetupDataResponse(mMockedWlanDataServiceManager,
-                DataFailCause.HANDOVER_FAILED, -1, true);
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        processAllFutureMessages();
-
-        // Should retried 5 times, which is the maximum based on the retry config rules.
-        verify(mMockedWlanDataServiceManager, times(6)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(),
-                eq(DataService.REQUEST_REASON_HANDOVER), any(), anyInt(), any(), any(),
-                anyBoolean(), any(Message.class));
-
-        DataNetwork dataNetwork = getDataNetworks().get(0);
-        // Verify that data network is finally setup on IWLAN.
-        assertThat(dataNetwork.getTransport()).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
-        verify(mMockedWlanDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class),
-                anyBoolean(), anyBoolean(), eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-    }
-
-    @Test
-    public void testHandoverDataNetworkRetryReachedMaximumNetworkRequestRemoved() throws Exception {
-        TelephonyNetworkRequest networkRequest = createNetworkRequest(
-                NetworkCapabilities.NET_CAPABILITY_IMS);
-        mDataNetworkControllerUT.addNetworkRequest(networkRequest);
-        processAllMessages();
-
-        setFailedSetupDataResponse(mMockedWlanDataServiceManager,
-                DataFailCause.HANDOVER_FAILED, -1, true);
-        mDataNetworkControllerUT.removeNetworkRequest(networkRequest);
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        processAllMessages();
-
-        DataNetwork dataNetwork = getDataNetworks().get(0);
-        // Verify that data network should remain on cellular.
-        assertThat(dataNetwork.getTransport()).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-
-        // There shouldn't be any attempt to retry handover on IWLAN.
-        verify(mMockedWlanDataServiceManager, times(1)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(),
-                eq(DataService.REQUEST_REASON_HANDOVER), any(), anyInt(), any(), any(),
-                anyBoolean(), any(Message.class));
-
-        // There shouldn't be any attempt to bring up a new one on IWLAN as well.
-        verify(mMockedWlanDataServiceManager, never()).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(),
-                eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(), any(), any(),
-                anyBoolean(), any(Message.class));
-    }
-
-    @Test
-    public void testHandoverDataNetworkRetryReachedMaximumDelayImsTearDown() throws Exception {
-        // Voice call is ongoing
-        doReturn(PhoneConstants.State.OFFHOOK).when(mCT).getState();
-        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL,
-                true);
-        carrierConfigChanged();
-
-        testSetupImsDataNetwork();
-
-        setFailedSetupDataResponse(mMockedWlanDataServiceManager,
-                DataFailCause.HANDOVER_FAILED, -1, true);
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        processAllFutureMessages();
-
-        // Should retried 5 times, which is the maximum based on the retry config rules.
-        verify(mMockedWlanDataServiceManager, times(6)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(),
-                eq(DataService.REQUEST_REASON_HANDOVER), any(), anyInt(), any(), any(),
-                anyBoolean(), any(Message.class));
-
-        DataNetwork dataNetwork = getDataNetworks().get(0);
-        // Verify that data network is still on WWAN because voice call is still ongoing.
-        assertThat(dataNetwork.getTransport()).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-
-    }
-
-    // Test the device enters from 4G to 3G, and QNS switches the pref just before that happens.
-    // Make sure we don't tear down the network and let it handover to IWLAN successfully.
-    @Test
-    public void testHandoverDataNetworkWhileSwitchTo3G() throws Exception {
-        testSetupImsDataNetwork();
-
-        // Before handover the data profile is the cellular IMS data profile
-        verifyConnectedNetworkHasDataProfile(mImsCellularDataProfile);
-
-        // Long delay handover
-        setSuccessfulSetupDataResponse(mMockedWlanDataServiceManager, 1, 3000);
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
-                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-        mAccessNetworksManagerCallback.onPreferredTransportChanged(
-                NetworkCapabilities.NET_CAPABILITY_IMS);
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_UMTS,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-        processAllMessages();
-
-        // Move the time a little bit, handover still not responded.
-        moveTimeForward(500);
-        processAllMessages();
-        DataNetwork dataNetwork = getDataNetworks().get(0);
-        // Verify the network is still on cellular, waiting for handover, although already on 3G.
-        assertThat(dataNetwork.getTransport()).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-
-        // Now handover should complete.
-        moveTimeForward(5000);
-        processAllMessages();
-
-        dataNetwork = getDataNetworks().get(0);
-        // Verify that IWLAN handover succeeded.
-        assertThat(dataNetwork.getTransport()).isEqualTo(
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
-        // After handover the data profile is the IWLAN IMS data profile
-        verifyConnectedNetworkHasDataProfile(mImsIwlanDataProfile);
-    }
-
-
-    @Test
-    public void testSetupDataNetworkRetrySuggestedByNetwork() {
-        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
-                DataCallResponse.RETRY_DURATION_UNDEFINED, false);
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllFutureMessages();
-
-        // Should retried 20 times, which is the maximum based on the retry config rules.
-        verify(mMockedWwanDataServiceManager, times(21)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-    }
-
-    @Test
-    public void testSetupDataNetworkRetryFailed() {
-        mDataNetworkControllerUT.getDataRetryManager()
-                .registerCallback(mMockedDataRetryManagerCallback);
-        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
-                DataCallResponse.RETRY_DURATION_UNDEFINED, false);
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllMessages();
-
-        verify(mMockedWwanDataServiceManager, times(1)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-
-        // Process first retry
-        moveTimeForward(2500);
-        processAllMessages();
-        verify(mMockedWwanDataServiceManager, times(2)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-        ArgumentCaptor<DataRetryManager.DataSetupRetryEntry> retryEntry =
-                ArgumentCaptor.forClass(DataRetryManager.DataSetupRetryEntry.class);
-        verify(mMockedDataRetryManagerCallback, times(1))
-                .onDataNetworkSetupRetry(retryEntry.capture());
-        assertThat(retryEntry.getValue().getState()).isEqualTo(
-                DataRetryManager.DataRetryEntry.RETRY_STATE_FAILED);
-
-        // Cause data network setup failed due to RADIO_DISABLED_BY_CARRIER
-        doReturn(false).when(mSST).getPowerStateFromCarrier();
-
-        // Process second retry and ensure data network setup failed
-        moveTimeForward(3000);
-        processAllMessages();
-        verify(mMockedWwanDataServiceManager, times(2)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-        verify(mMockedDataRetryManagerCallback, times(2))
-                .onDataNetworkSetupRetry(retryEntry.capture());
-        assertThat(retryEntry.getValue().getState()).isEqualTo(
-                DataRetryManager.DataRetryEntry.RETRY_STATE_FAILED);
-
-        // Data network setup allowed again
-        doReturn(true).when(mSST).getPowerStateFromCarrier();
-
-        // Should not retry again after retry failure
-        processAllFutureMessages();
-        verify(mMockedWwanDataServiceManager, times(2)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-    }
-
-    @Test
-    public void testSetupDataNetworkRetryFailedNetworkRequestRemoved() {
-        mDataNetworkControllerUT.getDataRetryManager()
-                .registerCallback(mMockedDataRetryManagerCallback);
-        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
-                DataCallResponse.RETRY_DURATION_UNDEFINED, false);
-        TelephonyNetworkRequest tnr = createNetworkRequest(
-                NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        mDataNetworkControllerUT.addNetworkRequest(tnr);
-
-        processAllMessages();
-
-        verify(mMockedWwanDataServiceManager, times(1)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-        Mockito.clearInvocations(mMockedWwanDataServiceManager);
-
-        logd("Remove internet network request");
-        mDataNetworkControllerUT.removeNetworkRequest(tnr);
-
-        moveTimeForward(2500);
-        processAllMessages();
-
-        // There should be no retry since request has been removed.
-        verify(mMockedWwanDataServiceManager, never()).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-        Mockito.clearInvocations(mMockedWwanDataServiceManager);
-
-        // Now send another IMS request
-        tnr = createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS);
-        mDataNetworkControllerUT.addNetworkRequest(tnr);
-        processAllMessages();
-
-        verify(mMockedWwanDataServiceManager, times(1)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-        Mockito.clearInvocations(mMockedWwanDataServiceManager);
-
-        logd("Remove IMS network request");
-        mDataNetworkControllerUT.removeNetworkRequest(tnr);
-
-        // There should be no retry since request has been removed.
-        verify(mMockedWwanDataServiceManager, never()).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-    }
-
-    @Test
-    public void testSetupDataNetworkPermanentFailure() {
-        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.PROTOCOL_ERRORS,
-                DataCallResponse.RETRY_DURATION_UNDEFINED, false);
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllFutureMessages();
-
-        // There should be only one attempt, and no retry should happen because it's a permanent
-        // failure.
-        verify(mMockedWwanDataServiceManager, times(1)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-    }
-
-    @Test
-    public void testSetupDataNetworkNetworkSuggestedNeverRetry() {
-        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.PROTOCOL_ERRORS,
-                Long.MAX_VALUE, false);
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllFutureMessages();
-
-        // There should be only one attempt, and no retry should happen because it's a permanent
-        // failure.
-        verify(mMockedWwanDataServiceManager, times(1)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-    }
-
-    @Test
-    public void testSetupDataNetworkNetworkSuggestedRetryTimerDataThrottled() {
-        mDataNetworkControllerUT.getDataRetryManager()
-                .registerCallback(mMockedDataRetryManagerCallback);
-
-        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.PROTOCOL_ERRORS,
-                10000, false);
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS));
-        processAllMessages();
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS));
-        processAllMessages();
-
-        // There should be only one attempt, and no retry should happen because the second one
-        // was throttled.
-        verify(mMockedWwanDataServiceManager, times(1)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-
-        ArgumentCaptor<List<ThrottleStatus>> throttleStatusCaptor =
-                ArgumentCaptor.forClass(List.class);
-        verify(mMockedDataRetryManagerCallback)
-                .onThrottleStatusChanged(throttleStatusCaptor.capture());
-        assertThat(throttleStatusCaptor.getValue()).hasSize(1);
-        ThrottleStatus throttleStatus = throttleStatusCaptor.getValue().get(0);
-        assertThat(throttleStatus.getApnType()).isEqualTo(ApnSetting.TYPE_IMS);
-        assertThat(throttleStatus.getRetryType())
-                .isEqualTo(ThrottleStatus.RETRY_TYPE_NEW_CONNECTION);
-        assertThat(throttleStatus.getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-    }
-
-    @Test
-    public void testTacChangesClearThrottlingAndRetryHappens() throws Exception {
-        testSetupDataNetworkNetworkSuggestedRetryTimerDataThrottled();
-        processAllFutureMessages();
-
-        setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 1);
-        logd("Sending TAC_CHANGED event");
-        mDataNetworkControllerUT.obtainMessage(25/*EVENT_TAC_CHANGED*/).sendToTarget();
-        mDataNetworkControllerUT.getDataRetryManager().obtainMessage(10/*EVENT_TAC_CHANGED*/)
-                .sendToTarget();
-        processAllFutureMessages();
-
-        // TAC changes should clear the already-scheduled retry and throttling.
-        assertThat(mDataNetworkControllerUT.getDataRetryManager().isAnySetupRetryScheduled(
-                mImsCellularDataProfile, AccessNetworkConstants.TRANSPORT_TYPE_WWAN)).isFalse();
-
-        // But DNC should re-evaluate unsatisfied request and setup IMS again.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-    }
-
-    @Test
-    public void testNrAdvancedByPco() throws Exception {
-        testSetupDataNetwork();
-        verify(mMockedDataNetworkControllerCallback, never())
-                .onNrAdvancedCapableByPcoChanged(anyBoolean());
-        mSimulatedCommands.triggerPcoData(1, "IPV6", 1234, new byte[]{1});
-        processAllMessages();
-        verify(mMockedDataNetworkControllerCallback).onNrAdvancedCapableByPcoChanged(eq(true));
-
-        mSimulatedCommands.triggerPcoData(1, "IPV6", 1234, new byte[]{0});
-        processAllMessages();
-        verify(mMockedDataNetworkControllerCallback).onNrAdvancedCapableByPcoChanged(eq(false));
-    }
-
-    @Test
-    public void testSetupDataNetworkVcnManaged() throws Exception {
-        // VCN managed
-        setVcnManagerPolicy(true, false);
-        NetworkRequest request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
-
-        mDataNetworkControllerUT.addNetworkRequest(tnr);
-        processAllMessages();
-
-        // VCN managed network won't trigger onInternetDataNetworkConnected.
-        // DataNetwork.isInternetSupported() is false for VCN managed network.
-        verify(mMockedDataNetworkControllerCallback, never())
-                .onInternetDataNetworkConnected(any());
-        List<DataNetwork> dataNetworks = getDataNetworks();
-        assertThat(dataNetworks).hasSize(1);
-        assertThat(dataNetworks.get(0).getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)).isFalse();
-        assertThat(dataNetworks.get(0).isInternetSupported()).isFalse();
-        assertThat(dataNetworks.get(0).getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
-    }
-
-    @Test
-    public void testSetupDataNetworkVcnRequestedTeardown() throws Exception {
-        // VCN managed, tear down on setup.
-        setVcnManagerPolicy(true, true);
-        NetworkRequest request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
-
-        mDataNetworkControllerUT.addNetworkRequest(tnr);
-        processAllMessages();
-
-        // Should not be any data network created.
-        List<DataNetwork> dataNetworks = getDataNetworks();
-        assertThat(dataNetworks).hasSize(0);
-    }
-
-    @Test
-    public void testVcnManagedNetworkPolicyChanged() throws Exception {
-        testSetupDataNetworkVcnManaged();
-
-        setVcnManagerPolicy(true, true);
-        ArgumentCaptor<VcnNetworkPolicyChangeListener> listenerCaptor =
-                ArgumentCaptor.forClass(VcnNetworkPolicyChangeListener.class);
-        verify(mVcnManager).addVcnNetworkPolicyChangeListener(any(Executor.class),
-                listenerCaptor.capture());
-
-        // Trigger policy changed event
-        VcnNetworkPolicyChangeListener listener = listenerCaptor.getValue();
-        listener.onPolicyChanged();
-        processAllMessages();
-
-        List<DataNetwork> dataNetworks = getDataNetworks();
-        assertThat(dataNetworks).hasSize(0);
-    }
-
-    @Test
-    public void testDataDisableNotTearingDownUnmetered() throws Exception {
-        // User data enabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, true, mContext.getOpPackageName());
-        processAllMessages();
-
-        testSetupImsDataNetwork();
-        Mockito.clearInvocations(mMockedDataNetworkControllerCallback);
-
-        // User data disabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, false, mContext.getOpPackageName());
-        processAllMessages();
-
-        // There shouldn't be all data disconnected event.
-        verify(mMockedDataNetworkControllerCallback, never())
-                .onAnyDataNetworkExistingChanged(anyBoolean());
-
-        // Verify IMS is still alive.
-        List<DataNetwork> dataNetworkList = getDataNetworks();
-        assertThat(dataNetworkList).hasSize(1);
-        assertThat(dataNetworkList.get(0).getNetworkCapabilities()
-                .hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)).isTrue();
-        assertThat(dataNetworkList.get(0).isConnected()).isTrue();
-    }
-
-    @Test
-    public void testNonVoPSNoIMSSetup() throws Exception {
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED));
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS,
-                        NetworkCapabilities.NET_CAPABILITY_MMTEL));
-        processAllMessages();
-
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-        verifyAllDataDisconnected();
-    }
-
-    @Test
-    public void testNonVoPStoVoPSImsSetup() throws Exception {
-        // VOPS not supported
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED));
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS,
-                        NetworkCapabilities.NET_CAPABILITY_MMTEL));
-        processAllMessages();
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-
-        // VoPS supported
-        dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
-
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-    }
-
-    @Test
-    public void testDelayImsTearDownCsRequestsToTearDown() throws Exception {
-        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL,
-                true);
-        TelephonyNetworkRequest networkRequest = createNetworkRequest(
-                NetworkCapabilities.NET_CAPABILITY_IMS);
-        mDataNetworkControllerUT.addNetworkRequest(networkRequest);
-        processAllMessages();
-
-        // Call is ongoing
-        doReturn(PhoneConstants.State.OFFHOOK).when(mCT).getState();
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-        verifyConnectedNetworkHasDataProfile(mImsCellularDataProfile);
-        List<DataNetwork> dataNetworks = getDataNetworks();
-        assertThat(dataNetworks).hasSize(1);
-        dataNetworks.get(0).tearDown(DataNetwork.TEAR_DOWN_REASON_RAT_NOT_ALLOWED);
-        processAllMessages();
-
-        // Make sure IMS network is still connected.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-        verifyConnectedNetworkHasDataProfile(mImsCellularDataProfile);
-
-        // Now connectivity service requests to tear down the data network.
-        mDataNetworkControllerUT.removeNetworkRequest(networkRequest);
-        dataNetworks.get(0).tearDown(DataNetwork.TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED);
-        processAllMessages();
-
-        // All data (including IMS) should be torn down.
-        verifyAllDataDisconnected();
-    }
-
-    @Test
-    public void testUnmeteredMmsWhenDataDisabled() throws Exception {
-        mCarrierConfig.putStringArray(
-                CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
-                new String[]{"default", "dun", "supl"});
-        carrierConfigChanged();
-
-        // User data disabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, false, mContext.getOpPackageName());
-        processAllMessages();
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_MMS));
-        processAllMessages();
-
-        // Make sure MMS is the only capability advertised, but not internet or SUPL.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_MMS);
-        verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
-    }
-
-    @Test
-    public void testUnmeteredMmsWhenRoamingDisabled() throws Exception {
-        mCarrierConfig.putStringArray(
-                CarrierConfigManager.KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
-                new String[]{"default", "dun", "supl"});
-        carrierConfigChanged();
-
-        // Roaming data disabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataRoamingEnabled(false);
-        processAllMessages();
-
-        // Device is roaming
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_MMS));
-        processAllMessages();
-
-        // Make sure MMS is the only capability advertised, but not internet or SUPL.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_MMS);
-        verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
-    }
-
-    @Test
-    public void testRestrictedNetworkRequestDataDisabled() throws Exception {
-        // User data disabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, false, mContext.getOpPackageName());
-        processAllMessages();
-
-        // Create a restricted network request.
-        NetworkCapabilities netCaps = new NetworkCapabilities();
-        netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        netCaps.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
-
-        NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
-                ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId, NetworkRequest.Type.REQUEST);
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                new TelephonyNetworkRequest(nativeNetworkRequest, mPhone));
-        processAllMessages();
-
-        verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET,
-                NetworkCapabilities.NET_CAPABILITY_SUPL, NetworkCapabilities.NET_CAPABILITY_MMS);
-
-        List<DataNetwork> dataNetworks = getDataNetworks();
-        // Make sure the network is restricted.
-        assertThat(dataNetworks.get(0).getNetworkCapabilities()
-                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)).isFalse();
-    }
-
-    @Test
-    public void testRestrictedNetworkRequestDataEnabled() throws Exception {
-        // Create a restricted network request.
-        NetworkCapabilities netCaps = new NetworkCapabilities();
-        netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        netCaps.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
-
-        NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
-                ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId, NetworkRequest.Type.REQUEST);
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                new TelephonyNetworkRequest(nativeNetworkRequest, mPhone));
-        processAllMessages();
-
-        verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_INTERNET,
-                NetworkCapabilities.NET_CAPABILITY_SUPL, NetworkCapabilities.NET_CAPABILITY_MMS,
-                // Because data is enabled, even though the network request is restricted, the
-                // network should still be not-restricted.
-                NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
-    }
-
-    @Test
-    public void testSinglePdnArbitration() throws Exception {
-        // On old 1x network, only one data network is allowed.
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_1xRTT,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_DUN));
-        processAllMessages();
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_DUN);
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllFutureMessages();
-        // Lower priority network should not trump the higher priority network.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_DUN);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        // Now send a higher priority network request
-        TelephonyNetworkRequest fotaRequest = createNetworkRequest(
-                NetworkCapabilities.NET_CAPABILITY_FOTA);
-        mDataNetworkControllerUT.addNetworkRequest(fotaRequest);
-
-        processAllFutureMessages();
-        // The existing internet data network should be torn down.
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_DUN);
-        // The higher priority emergency data network should be established.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_FOTA);
-
-        // Now remove the fota request and tear down fota network.
-        mDataNetworkControllerUT.removeNetworkRequest(fotaRequest);
-        processAllMessages();
-        List<DataNetwork> dataNetworks = getDataNetworks();
-        dataNetworks.get(0).tearDown(DataNetwork.TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED);
-        processAllMessages();
-
-        // The tethering data network should come back since now it has the highest priority after
-        // fota is gone.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_DUN);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA);
-    }
-
-    @Test
-    public void testImsGracefulTearDown() throws Exception {
-        setImsRegistered(true);
-        setRcsRegistered(true);
-
-        NetworkCapabilities netCaps = new NetworkCapabilities();
-        netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-        netCaps.setRequestorPackageName(FAKE_MMTEL_PACKAGE);
-
-        NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
-                ConnectivityManager.TYPE_MOBILE, ++mNetworkRequestId, NetworkRequest.Type.REQUEST);
-        TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(
-                nativeNetworkRequest, mPhone);
-
-        mDataNetworkControllerUT.addNetworkRequest(networkRequest);
-
-        processAllMessages();
-        Mockito.clearInvocations(mPhone);
-
-        // SIM removal
-        mDataNetworkControllerUT.obtainMessage(9/*EVENT_SIM_STATE_CHANGED*/,
-                TelephonyManager.SIM_STATE_ABSENT, 0).sendToTarget();
-        processAllMessages();
-
-        // Make sure data network enters disconnecting state
-        ArgumentCaptor<PreciseDataConnectionState> pdcsCaptor =
-                ArgumentCaptor.forClass(PreciseDataConnectionState.class);
-        verify(mPhone).notifyDataConnection(pdcsCaptor.capture());
-        PreciseDataConnectionState pdcs = pdcsCaptor.getValue();
-        assertThat(pdcs.getState()).isEqualTo(TelephonyManager.DATA_DISCONNECTING);
-
-        // IMS de-registered. Now data network is safe to be torn down.
-        Mockito.clearInvocations(mPhone);
-        setImsRegistered(false);
-        setRcsRegistered(false);
-        processAllMessages();
-
-        // All data should be disconnected.
-        verifyAllDataDisconnected();
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-        verify(mPhone).notifyDataConnection(pdcsCaptor.capture());
-        pdcs = pdcsCaptor.getValue();
-        assertThat(pdcs.getState()).isEqualTo(TelephonyManager.DATA_DISCONNECTED);
-    }
-
-    @Test
-    public void testNetworkRequestRemovedBeforeRetry() {
-        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
-                DataCallResponse.RETRY_DURATION_UNDEFINED, false);
-        TelephonyNetworkRequest networkRequest = createNetworkRequest(
-                NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        mDataNetworkControllerUT.addNetworkRequest(networkRequest);
-        logd("Removing network request.");
-        mDataNetworkControllerUT.removeNetworkRequest(networkRequest);
-        processAllMessages();
-
-        // There should be only one invocation, which is the original setup data request. There
-        // shouldn't be more than 1 (i.e. should not retry).
-        verify(mMockedWwanDataServiceManager, times(1)).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-    }
-
-    @Test
-    public void testGetInternetDataDisallowedReasons() {
-        List<DataDisallowedReason> reasons = mDataNetworkControllerUT
-                .getInternetDataDisallowedReasons();
-        assertThat(reasons).isEmpty();
-
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_UNKNOWN,
-                NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING);
-
-        reasons = mDataNetworkControllerUT.getInternetDataDisallowedReasons();
-        assertThat(reasons).containsExactly(DataDisallowedReason.NOT_IN_SERVICE,
-                DataDisallowedReason.NO_SUITABLE_DATA_PROFILE);
-    }
-
-    @Test
-    public void testEmergencySuplDataDisabled() throws Exception {
-        // Data disabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, false, mContext.getOpPackageName());
-        processAllMessages();
-        doReturn(true).when(mPhone).isInEmergencyCall();
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_SUPL));
-        processAllMessages();
-
-        // Make sure SUPL is the only capability advertised, but not internet or MMS.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_SUPL);
-        verifyConnectedNetworkHasDataProfile(mGeneralPurposeDataProfile);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_MMS);
-    }
-
-    @Test
-    public void testEmergencyCallDataDisabled() throws Exception {
-        doReturn(true).when(mPhone).isInEmergencyCall();
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_INTERNET));
-        processAllMessages();
-
-        verifyInternetConnected();
-
-        // Data disabled
-        mDataNetworkControllerUT.getDataSettingsManager().setDataEnabled(
-                TelephonyManager.DATA_ENABLED_REASON_USER, false, mContext.getOpPackageName());
-        processAllMessages();
-
-        // Make sure internet is not connected. (Previously it has a bug due to incorrect logic
-        // to determine it's for emergency SUPL).
-        verifyAllDataDisconnected();
-    }
-
-    @Test
-    public void testDataActivity() {
-        doReturn(TelephonyManager.DATA_ACTIVITY_IN).when(mLinkBandwidthEstimator).getDataActivity();
-        mLinkBandwidthEstimatorCallback.onDataActivityChanged(TelephonyManager.DATA_ACTIVITY_IN);
-        processAllMessages();
-        assertThat(mDataNetworkControllerUT.getDataActivity()).isEqualTo(
-                TelephonyManager.DATA_ACTIVITY_IN);
-
-        doReturn(TelephonyManager.DATA_ACTIVITY_OUT).when(mLinkBandwidthEstimator)
-                .getDataActivity();
-        mLinkBandwidthEstimatorCallback.onDataActivityChanged(TelephonyManager.DATA_ACTIVITY_OUT);
-        processAllMessages();
-        assertThat(mDataNetworkControllerUT.getDataActivity()).isEqualTo(
-                TelephonyManager.DATA_ACTIVITY_OUT);
-
-        doReturn(TelephonyManager.DATA_ACTIVITY_INOUT).when(mLinkBandwidthEstimator)
-                .getDataActivity();
-        mLinkBandwidthEstimatorCallback.onDataActivityChanged(TelephonyManager.DATA_ACTIVITY_INOUT);
-        processAllMessages();
-        assertThat(mDataNetworkControllerUT.getDataActivity()).isEqualTo(
-                TelephonyManager.DATA_ACTIVITY_INOUT);
-
-        doReturn(TelephonyManager.DATA_ACTIVITY_NONE).when(mLinkBandwidthEstimator)
-                .getDataActivity();
-        mLinkBandwidthEstimatorCallback.onDataActivityChanged(TelephonyManager.DATA_ACTIVITY_NONE);
-        processAllMessages();
-        assertThat(mDataNetworkControllerUT.getDataActivity()).isEqualTo(
-                TelephonyManager.DATA_ACTIVITY_NONE);
-    }
-
-    @Test
-    public void testHandoverDataNetworkOos() throws Exception {
-        ServiceState ss = new ServiceState();
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
-                .setRegistrationState(
-                        NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
-                .build());
-        doReturn(ss).when(mSST).getServiceState();
-        doReturn(ss).when(mPhone).getServiceState();
-
-        mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
-        processAllMessages();
-
-        testSetupImsDataNetwork();
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
-        // Verify that handover is not performed.
-        verify(mMockedWlanDataServiceManager, never()).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(),
-                eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(), any(), any(), anyBoolean(),
-                any(Message.class));
-
-        // IMS network should be torn down.
-        verifyAllDataDisconnected();
-    }
-
-    @Test
-    public void testHandoverDataNetworkNonVops() throws Exception {
-        ServiceState ss = new ServiceState();
-
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED));
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .setDataSpecificInfo(dsri)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
-                .build());
-        doReturn(ss).when(mSST).getServiceState();
-        doReturn(ss).when(mPhone).getServiceState();
-
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
-                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-
-        mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
-        processAllMessages();
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS,
-                        NetworkCapabilities.NET_CAPABILITY_MMTEL));
-        processAllMessages();
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-
-        // Change the preference to cellular
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-
-        // Verify that handover is not performed.
-        verify(mMockedWwanDataServiceManager, never()).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-
-        // IMS network should be torn down.
-        verifyAllDataDisconnected();
-    }
-
-    @Test
-    public void testNonMmtelImsHandoverDataNetworkNonVops() throws Exception {
-        ServiceState ss = new ServiceState();
-
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED));
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .setDataSpecificInfo(dsri)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
-                .build());
-        doReturn(ss).when(mSST).getServiceState();
-        doReturn(ss).when(mPhone).getServiceState();
-
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
-                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-
-        mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
-        processAllMessages();
-
-        // Bring up the IMS network that does not require MMTEL
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS));
-        processAllMessages();
-
-        // Even though the network request does not have MMTEL, but the network support it, so
-        // the network capabilities should still have MMTEL.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-
-        // Change the preference to cellular
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-
-        // Verify that handover is performed
-        verify(mMockedWwanDataServiceManager).setupDataCall(anyInt(),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-
-        // The IMS network should still have IMS and MMTEL.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS);
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_MMTEL);
-    }
-
-    @Test
-    public void testMmtelImsDataNetworkMovingToNonVops() throws Exception {
-        ServiceState ss = new ServiceState();
-
-        // VoPS network
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .setDataSpecificInfo(dsri)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
-                .build());
-        doReturn(ss).when(mSST).getServiceState();
-        doReturn(ss).when(mPhone).getServiceState();
-
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
-                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-
-        mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
-        processAllMessages();
-
-        // Bring up the IMS network that does require MMTEL
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS,
-                        NetworkCapabilities.NET_CAPABILITY_MMTEL));
-        processAllMessages();
-
-        // the network capabilities should have IMS and MMTEL.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-
-        ss = new ServiceState();
-        // Non VoPS network
-        dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED));
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .setDataSpecificInfo(dsri)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
-                .build());
-        doReturn(ss).when(mSST).getServiceState();
-        doReturn(ss).when(mPhone).getServiceState();
-
-        mDataNetworkControllerUT.obtainMessage(17/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
-        processAllMessages();
-
-        // The IMS network should be torn down by data network controller.
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_MMTEL);
-    }
-
-    @Test
-    public void testVoPStoNonVoPSDelayImsTearDown() throws Exception {
-        mCarrierConfig.putBoolean(CarrierConfigManager.KEY_DELAY_IMS_TEAR_DOWN_UNTIL_CALL_END_BOOL,
-                true);
-        carrierConfigChanged();
-
-        // VoPS supported
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS,
-                        NetworkCapabilities.NET_CAPABILITY_MMTEL));
-        processAllMessages();
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS);
-
-        doReturn(PhoneConstants.State.OFFHOOK).when(mCT).getState();
-
-        dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED));
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
-
-        // Make sure IMS is still connected.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-
-        // Call ends
-        doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
-        mDataNetworkControllerUT.obtainMessage(18/*EVENT_VOICE_CALL_ENDED*/).sendToTarget();
-        processAllMessages();
-
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-    }
-
-    @Test
-    public void testDeactivateDataOnOldHal() throws Exception {
-        doAnswer(invocation -> {
-            // Only send the deactivation data response, no data call list changed event.
-            Message msg = (Message) invocation.getArguments()[2];
-            msg.sendToTarget();
-            return null;
-        }).when(mMockedWwanDataServiceManager).deactivateDataCall(
-                anyInt(), anyInt(), any(Message.class));
-        // Simulate old devices
-        doReturn(RIL.RADIO_HAL_VERSION_1_6).when(mPhone).getHalVersion();
-
-        testSetupDataNetwork();
-
-        mDataNetworkControllerUT.obtainMessage(9/*EVENT_SIM_STATE_CHANGED*/,
-                TelephonyManager.SIM_STATE_ABSENT, 0).sendToTarget();
-        processAllMessages();
-        verifyAllDataDisconnected();
-        verify(mMockedDataNetworkControllerCallback).onAnyDataNetworkExistingChanged(eq(false));
-        verify(mMockedDataNetworkControllerCallback).onInternetDataNetworkDisconnected();
-    }
-
-    @Test
-    public void testHandoverWhileSetupDataCallInProgress() throws Exception {
-        // Long delay setup failure
-        setFailedSetupDataResponse(mMockedWwanDataServiceManager, DataFailCause.CONGESTION,
-                DataCallResponse.RETRY_DURATION_UNDEFINED, false, 10000);
-
-        mDataNetworkControllerUT.addNetworkRequest(
-                createNetworkRequest(NetworkCapabilities.NET_CAPABILITY_IMS,
-                        NetworkCapabilities.NET_CAPABILITY_MMTEL));
-        processAllMessages();
-
-        // Change the preference to IWLAN while setup data is still ongoing.
-        updateTransport(NetworkCapabilities.NET_CAPABILITY_IMS,
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
-        // Data should not be connected.
-        verifyNoConnectedNetworkHasCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-
-        // There shouldn't be any attempt to bring up IMS on IWLAN even though the preference
-        // has already changed, because the previous setup is still ongoing.
-        verify(mMockedWlanDataServiceManager, never()).setupDataCall(eq(AccessNetworkType.IWLAN),
-                any(DataProfile.class), anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(),
-                any(), any(), anyBoolean(), any(Message.class));
-
-        processAllFutureMessages();
-
-        // Should setup a new one instead of handover.
-        verify(mMockedWlanDataServiceManager).setupDataCall(eq(AccessNetworkType.IWLAN),
-                any(DataProfile.class), anyBoolean(), anyBoolean(),
-                eq(DataService.REQUEST_REASON_NORMAL), any(), anyInt(), any(), any(), anyBoolean(),
-                any(Message.class));
-
-        // IMS should be connected.
-        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_MMTEL);
-    }
-
-    @Test
-    public void testRemoveNetworkRequest() throws Exception {
-        NetworkCapabilities netCaps = new NetworkCapabilities();
-        netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
-                ConnectivityManager.TYPE_MOBILE, 0, NetworkRequest.Type.REQUEST);
-
-        mDataNetworkControllerUT.addNetworkRequest(new TelephonyNetworkRequest(
-                nativeNetworkRequest, mPhone));
-        processAllMessages();
-
-        // Intentionally create a new telephony request with the original native network request.
-        TelephonyNetworkRequest request = new TelephonyNetworkRequest(nativeNetworkRequest, mPhone);
-
-        mDataNetworkControllerUT.removeNetworkRequest(request);
-        processAllFutureMessages();
-
-        List<DataNetwork> dataNetworkList = getDataNetworks();
-        // The data network should not be torn down after network request removal.
-        assertThat(dataNetworkList).hasSize(1);
-        // But should be detached from the data network.
-        assertThat(dataNetworkList.get(0).getAttachedNetworkRequestList()).isEmpty();
-        assertThat(dataNetworkList.get(0).isConnected()).isTrue();
-    }
-
-    @Test
-    public void testTempDdsSwitchTearDown() throws Exception {
-        TelephonyNetworkRequest request = createNetworkRequest(
-                NetworkCapabilities.NET_CAPABILITY_INTERNET);
-        mDataNetworkControllerUT.addNetworkRequest(request);
-        processAllMessages();
-
-        // Now DDS temporarily switched to phone 1
-        doReturn(1).when(mMockedPhoneSwitcher).getPreferredDataPhoneId();
-
-        // Simulate telephony network factory remove request due to switch.
-        mDataNetworkControllerUT.removeNetworkRequest(request);
-        processAllMessages();
-
-        // Data should be torn down on this non-preferred sub.
-        verifyAllDataDisconnected();
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
deleted file mode 100644
index f53298d..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataNetworkTest.java
+++ /dev/null
@@ -1,1594 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.nullable;
-import static org.mockito.Matchers.argThat;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.net.ConnectivityManager;
-import android.net.InetAddresses;
-import android.net.LinkAddress;
-import android.net.LinkProperties;
-import android.net.NetworkAgentConfig;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkRequest;
-import android.net.vcn.VcnManager.VcnNetworkPolicyChangeListener;
-import android.net.vcn.VcnNetworkPolicyResult;
-import android.os.AsyncResult;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.AccessNetworkConstants.AccessNetworkType;
-import android.telephony.AccessNetworkConstants.TransportType;
-import android.telephony.Annotation;
-import android.telephony.Annotation.DataFailureCause;
-import android.telephony.DataFailCause;
-import android.telephony.DataSpecificRegistrationInfo;
-import android.telephony.LteVopsSupportInfo;
-import android.telephony.NetworkRegistrationInfo;
-import android.telephony.PreciseDataConnectionState;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataProfile;
-import android.telephony.data.DataService;
-import android.telephony.data.DataServiceCallback;
-import android.telephony.data.NetworkSliceInfo;
-import android.telephony.data.TrafficDescriptor;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.util.Pair;
-import android.util.SparseArray;
-
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.data.DataEvaluation.DataAllowedReason;
-import com.android.internal.telephony.data.DataNetwork.DataNetworkCallback;
-import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
-import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
-import com.android.internal.telephony.metrics.DataCallSessionStats;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.Executor;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class DataNetworkTest extends TelephonyTest {
-    private static final String IPV4_ADDRESS = "10.0.2.15";
-    private static final String IPV4_ADDRESS1 = "10.0.2.16";
-    private static final String IPV6_ADDRESS = "2607:fb90:a620:651d:eabe:f8da:c107:44be";
-    private static final String IPV6_ADDRESS1 = "2607:fb90:a620:651d:eabe:f8da:c107:44bf";
-
-    private static final int ADMIN_UID1 = 1234;
-    private static final int ADMIN_UID2 = 5678;
-
-    private static final int DEFAULT_MTU = 1501;
-
-    private static final String FAKE_IMSI = "123456789";
-
-    private DataNetwork mDataNetworkUT;
-
-    private final SparseArray<DataServiceManager> mDataServiceManagers = new SparseArray<>();
-
-    private final ApnSetting mInternetApnSetting = new ApnSetting.Builder()
-            .setId(2163)
-            .setOperatorNumeric("12345")
-            .setEntryName("fake_apn")
-            .setApnName("fake_apn")
-            .setUser("user")
-            .setPassword("passwd")
-            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
-            .setProtocol(ApnSetting.PROTOCOL_IPV6)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .setNetworkTypeBitmask(0)
-            .setProfileId(1234)
-            .setMaxConns(321)
-            .setWaitTime(456)
-            .setMaxConnsTime(789)
-            .build();
-
-    private final ApnSetting mImsApnSetting = new ApnSetting.Builder()
-            .setId(2163)
-            .setOperatorNumeric("12345")
-            .setEntryName("fake_ims")
-            .setApnName("fake_ims")
-            .setUser("user")
-            .setPassword("passwd")
-            .setApnTypeBitmask(ApnSetting.TYPE_IMS)
-            .setProtocol(ApnSetting.PROTOCOL_IPV6)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .setNetworkTypeBitmask(0)
-            .setProfileId(1234)
-            .setMaxConns(321)
-            .setWaitTime(456)
-            .setMaxConnsTime(789)
-            .build();
-
-    private final DataProfile mInternetDataProfile = new DataProfile.Builder()
-            .setApnSetting(mInternetApnSetting)
-            .setTrafficDescriptor(new TrafficDescriptor("fake_apn", null))
-            .build();
-
-    private final DataProfile mImsDataProfile = new DataProfile.Builder()
-            .setApnSetting(mImsApnSetting)
-            .setTrafficDescriptor(new TrafficDescriptor("fake_apn", null))
-            .build();
-
-    private final DataProfile mEnterpriseDataProfile = new DataProfile.Builder()
-            .setTrafficDescriptor(new TrafficDescriptor(null,
-                    new TrafficDescriptor.OsAppId(TrafficDescriptor.OsAppId.ANDROID_OS_ID,
-                            "ENTERPRISE", 1).getBytes()))
-            .build();
-
-    private final DataProfile mUrlccDataProfile = new DataProfile.Builder()
-            .setTrafficDescriptor(new TrafficDescriptor(null,
-                    new TrafficDescriptor.OsAppId(TrafficDescriptor.OsAppId.ANDROID_OS_ID,
-                            "PRIORITIZE_LATENCY", 1).getBytes()))
-            .build();
-
-    private final DataProfile mEmbbDataProfile = new DataProfile.Builder()
-            .setTrafficDescriptor(new TrafficDescriptor(null,
-                    new TrafficDescriptor.OsAppId(TrafficDescriptor.OsAppId.ANDROID_OS_ID,
-                            "PRIORITIZE_BANDWIDTH", 1).getBytes()))
-            .build();
-
-    private final DataProfile mCbsDataProfile = new DataProfile.Builder()
-            .setTrafficDescriptor(new TrafficDescriptor(null,
-                    new TrafficDescriptor.OsAppId(TrafficDescriptor.OsAppId.ANDROID_OS_ID,
-                            "CBS", 1).getBytes()))
-            .build();
-
-    // Mocked classes
-    private DataNetworkCallback mDataNetworkCallback;
-    private DataCallSessionStats mDataCallSessionStats;
-    private PhoneSwitcher mMockedPhoneSwitcher;
-
-    private final NetworkRegistrationInfo mIwlanNetworkRegistrationInfo =
-            new NetworkRegistrationInfo.Builder()
-                    .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
-                    .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                    .build();
-
-    private void setSuccessfulSetupDataResponse(DataServiceManager dsm, int cid) {
-        setSuccessfulSetupDataResponse(dsm, cid, Collections.emptyList());
-    }
-
-    private void setSuccessfulSetupDataResponse(DataServiceManager dsm, int cid,
-            List<TrafficDescriptor> tds) {
-        doAnswer(invocation -> {
-            final Message msg = (Message) invocation.getArguments()[10];
-
-            DataCallResponse response = new DataCallResponse.Builder()
-                    .setCause(0)
-                    .setRetryDurationMillis(-1L)
-                    .setId(cid)
-                    .setLinkStatus(2)
-                    .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
-                    .setInterfaceName("ifname")
-                    .setAddresses(Arrays.asList(
-                            new LinkAddress(InetAddresses.parseNumericAddress(IPV4_ADDRESS), 32),
-                            new LinkAddress(IPV6_ADDRESS + "/64")))
-                    .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress("10.0.2.3"),
-                            InetAddresses.parseNumericAddress("fd00:976a::9")))
-                    .setGatewayAddresses(Arrays.asList(
-                            InetAddresses.parseNumericAddress("10.0.2.15"),
-                            InetAddresses.parseNumericAddress("fe80::2")))
-                    .setPcscfAddresses(Arrays.asList(
-                            InetAddresses.parseNumericAddress("fd00:976a:c305:1d::8"),
-                            InetAddresses.parseNumericAddress("fd00:976a:c202:1d::7"),
-                            InetAddresses.parseNumericAddress("fd00:976a:c305:1d::5")))
-                    .setMtuV4(1234)
-                    .setPduSessionId(1)
-                    .setQosBearerSessions(new ArrayList<>())
-                    .setTrafficDescriptors(tds)
-                    .build();
-            msg.getData().putParcelable("data_call_response", response);
-            msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
-            msg.sendToTarget();
-            return null;
-        }).when(dsm).setupDataCall(anyInt(), any(DataProfile.class), anyBoolean(),
-                anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
-                any(Message.class));
-    }
-
-    private void setFailedSetupDataResponse(DataServiceManager dsm,
-            @DataServiceCallback.ResultCode int resultCode) {
-        doAnswer(invocation -> {
-            final Message msg = (Message) invocation.getArguments()[10];
-            msg.arg1 = resultCode;
-            msg.sendToTarget();
-            return null;
-        }).when(dsm).setupDataCall(anyInt(), any(DataProfile.class), anyBoolean(),
-                anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
-                any(Message.class));
-    }
-
-    private void sendServiceStateChangedEvent(@ServiceState.RegState int dataRegState,
-            @ServiceState.RilRadioTechnology int rat) {
-        mDataNetworkUT.obtainMessage(9/*EVENT_SERVICE_STATE_CHANGED*/,
-                new AsyncResult(null, new Pair<>(dataRegState, rat), null)).sendToTarget();
-    }
-
-    private void serviceStateChanged(@Annotation.NetworkType int networkType,
-            @NetworkRegistrationInfo.RegistrationState int regState) {
-        serviceStateChanged(networkType, regState, null);
-    }
-
-    private void serviceStateChanged(@Annotation.NetworkType int networkType,
-            @NetworkRegistrationInfo.RegistrationState int regState,
-            DataSpecificRegistrationInfo dsri) {
-        ServiceState ss = new ServiceState();
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(networkType)
-                .setRegistrationState(regState)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .setDataSpecificInfo(dsri)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WLAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .build());
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(networkType)
-                .setRegistrationState(regState)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_CS)
-                .build());
-        ss.setDataRoamingFromRegistration(regState
-                == NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING);
-        doReturn(ss).when(mSST).getServiceState();
-        doReturn(ss).when(mPhone).getServiceState();
-
-        if (mDataNetworkUT != null) {
-            mDataNetworkUT.obtainMessage(9/*EVENT_SERVICE_STATE_CHANGED*/).sendToTarget();
-            processAllMessages();
-        }
-    }
-
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        doReturn(mImsPhone).when(mPhone).getImsPhone();
-        doReturn(mImsCT).when(mImsPhone).getCallTracker();
-        doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
-
-        mDataNetworkCallback = Mockito.mock(DataNetworkCallback.class);
-        mDataCallSessionStats = Mockito.mock(DataCallSessionStats.class);
-        mMockedPhoneSwitcher = Mockito.mock(PhoneSwitcher.class);
-        replaceInstance(PhoneSwitcher.class, "sPhoneSwitcher", null, mMockedPhoneSwitcher);
-        doAnswer(invocation -> {
-            ((Runnable) invocation.getArguments()[0]).run();
-            return null;
-        }).when(mDataNetworkCallback).invokeFromExecutor(any(Runnable.class));
-        mDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                mMockedWwanDataServiceManager);
-        mDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
-                mMockedWlanDataServiceManager);
-        doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed();
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
-                .getPreferredTransportByNetworkCapability(anyInt());
-        doReturn(DataNetwork.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR)
-                .when(mDataConfigManager).getBandwidthEstimateSource();
-        doReturn(true).when(mDataConfigManager).isTempNotMeteredSupportedByCarrier();
-        doReturn(true).when(mDataConfigManager).isImsDelayTearDownEnabled();
-        doReturn(DEFAULT_MTU).when(mDataConfigManager).getDefaultMtu();
-        doReturn(FAKE_IMSI).when(mPhone).getSubscriberId();
-        doReturn(true).when(mDataNetworkController)
-                .isNetworkRequestExisting(any(TelephonyNetworkRequest.class));
-
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mDataNetworkUT = null;
-        mDataServiceManagers.clear();
-        super.tearDown();
-    }
-
-    private void sendTearDownEvent(@TransportType int transport, int cid,
-            @DataFailureCause int cause) {
-        DataCallResponse response = new DataCallResponse.Builder()
-                .setCause(cause)
-                .setRetryDurationMillis(DataCallResponse.RETRY_DURATION_UNDEFINED)
-                .setId(cid)
-                .setLinkStatus(DataCallResponse.LINK_STATUS_INACTIVE)
-                .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
-                .setQosBearerSessions(new ArrayList<>())
-                .setTrafficDescriptors(new ArrayList<>())
-                .build();
-        mDataNetworkUT.sendMessage(7/*EVENT_TEAR_DOWN_NETWORK*/,
-                1/*TEAR_DOWN_REASON_CONNECTIVITY_SERVICE_UNWANTED*/);
-        mDataNetworkUT.sendMessage(8/*EVENT_DATA_STATE_CHANGED*/,
-                new AsyncResult(transport, new ArrayList<>(Arrays.asList(response)), null));
-        processAllMessages();
-    }
-
-    // The purpose of this test is to make sure the network request insertion/removal works as
-    // expected, and make sure it is always sorted.
-    @Test
-    public void testCreateDataNetwork() throws Exception {
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), mPhone));
-
-        setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123);
-
-        mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers,
-                mInternetDataProfile, networkRequestList,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                DataAllowedReason.NORMAL, mDataNetworkCallback);
-        replaceInstance(DataNetwork.class, "mDataCallSessionStats",
-                mDataNetworkUT, mDataCallSessionStats);
-        processAllMessages();
-
-        ArgumentCaptor<LinkProperties> linkPropertiesCaptor =
-                ArgumentCaptor.forClass(LinkProperties.class);
-        ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor =
-                ArgumentCaptor.forClass(NetworkCapabilities.class);
-
-        verify(mConnectivityManager).registerNetworkAgent(any(), any(NetworkInfo.class),
-                linkPropertiesCaptor.capture(), networkCapabilitiesCaptor.capture(), any(), any(),
-                anyInt());
-        // The very first link properties from telephony is an empty link properties. It will be
-        // updated later.
-        assertThat(linkPropertiesCaptor.getValue()).isEqualTo(new LinkProperties());
-
-        verify(mSimulatedCommandsVerifier, never()).allocatePduSessionId(any(Message.class));
-        verify(mMockedWwanDataServiceManager).setupDataCall(eq(AccessNetworkType.EUTRAN),
-                eq(mInternetDataProfile), eq(false), eq(false),
-                eq(DataService.REQUEST_REASON_NORMAL), nullable(LinkProperties.class),
-                eq(DataCallResponse.PDU_SESSION_ID_NOT_SET), nullable(NetworkSliceInfo.class),
-                any(TrafficDescriptor.class), eq(true), any(Message.class));
-        assertThat(mDataNetworkUT.getId()).isEqualTo(123);
-        assertThat(networkRequestList.get(0).getState())
-                .isEqualTo(TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
-        LinkProperties lp = mDataNetworkUT.getLinkProperties();
-        assertThat(lp.getAddresses()).containsExactly(
-                InetAddresses.parseNumericAddress(IPV4_ADDRESS),
-                InetAddresses.parseNumericAddress(IPV6_ADDRESS));
-
-        assertThat(lp.getRoutes()).hasSize(2);
-        assertThat(lp.getRoutes().get(0).getGateway()).isEqualTo(
-                InetAddresses.parseNumericAddress("10.0.2.15"));
-        assertThat(lp.getRoutes().get(0).getMtu()).isEqualTo(1234);
-        assertThat(lp.getRoutes().get(1).getGateway()).isEqualTo(
-                InetAddresses.parseNumericAddress("fe80::2"));
-        // The default from carrier configs should be used if MTU is not set.
-        assertThat(lp.getRoutes().get(1).getMtu()).isEqualTo(DEFAULT_MTU);
-        // The higher value of v4 and v6 should be used.
-        assertThat(lp.getMtu()).isEqualTo(DEFAULT_MTU);
-
-        ArgumentCaptor<PreciseDataConnectionState> pdcsCaptor =
-                ArgumentCaptor.forClass(PreciseDataConnectionState.class);
-        verify(mPhone, times(2)).notifyDataConnection(pdcsCaptor.capture());
-        List<PreciseDataConnectionState> pdcsList = pdcsCaptor.getAllValues();
-
-        assertThat(pdcsList.get(0).getApnSetting()).isEqualTo(mInternetApnSetting);
-        assertThat(pdcsList.get(0).getState()).isEqualTo(TelephonyManager.DATA_CONNECTING);
-        assertThat(pdcsList.get(0).getId()).isEqualTo(-1);
-        assertThat(pdcsList.get(0).getNetworkType()).isEqualTo(TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(pdcsList.get(0).getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(pdcsList.get(0).getLinkProperties()).isEqualTo(new LinkProperties());
-
-        assertThat(pdcsList.get(1).getApnSetting()).isEqualTo(mInternetApnSetting);
-        assertThat(pdcsList.get(1).getState()).isEqualTo(TelephonyManager.DATA_CONNECTED);
-        assertThat(pdcsList.get(1).getId()).isEqualTo(123);
-        assertThat(pdcsList.get(1).getNetworkType()).isEqualTo(TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(pdcsList.get(1).getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(pdcsList.get(1).getLinkProperties().getAddresses().get(0))
-                .isEqualTo(InetAddresses.parseNumericAddress(IPV4_ADDRESS));
-        assertThat(pdcsList.get(1).getLinkProperties().getAddresses().get(1))
-                .isEqualTo(InetAddresses.parseNumericAddress(IPV6_ADDRESS));
-        assertThat(mDataNetworkUT.getNetworkCapabilities()).isEqualTo(
-                networkCapabilitiesCaptor.getValue());
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_SUPL)).isTrue();
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)).isTrue();
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)).isTrue();
-        verify(mVcnManager, atLeastOnce()).applyVcnNetworkPolicy(
-                argThat(caps -> caps.hasCapability(
-                        NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)),
-                any());
-
-        verify(mDataNetworkCallback).onConnected(eq(mDataNetworkUT));
-    }
-
-    @Test
-    public void testCreateImsDataNetwork() throws Exception {
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                .build(), mPhone));
-
-        setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123);
-
-        mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers,
-                mImsDataProfile, networkRequestList,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                DataAllowedReason.NORMAL, mDataNetworkCallback);
-        replaceInstance(DataNetwork.class, "mDataCallSessionStats",
-                mDataNetworkUT, mDataCallSessionStats);
-        processAllMessages();
-
-        ArgumentCaptor<LinkProperties> linkPropertiesCaptor =
-                ArgumentCaptor.forClass(LinkProperties.class);
-        ArgumentCaptor<NetworkCapabilities> networkCapabilitiesCaptor =
-                ArgumentCaptor.forClass(NetworkCapabilities.class);
-
-        verify(mConnectivityManager).registerNetworkAgent(any(), any(NetworkInfo.class),
-                linkPropertiesCaptor.capture(), networkCapabilitiesCaptor.capture(), any(), any(),
-                anyInt());
-        // The very first link properties from telephony is an empty link properties. It will be
-        // updated later.
-        assertThat(linkPropertiesCaptor.getValue()).isEqualTo(new LinkProperties());
-
-        verify(mSimulatedCommandsVerifier, never()).allocatePduSessionId(any(Message.class));
-        verify(mMockedWwanDataServiceManager).setupDataCall(eq(AccessNetworkType.EUTRAN),
-                eq(mImsDataProfile), eq(false), eq(false),
-                eq(DataService.REQUEST_REASON_NORMAL), nullable(LinkProperties.class),
-                eq(DataCallResponse.PDU_SESSION_ID_NOT_SET), nullable(NetworkSliceInfo.class),
-                any(TrafficDescriptor.class), eq(true), any(Message.class));
-        assertThat(mDataNetworkUT.getId()).isEqualTo(123);
-        assertThat(networkRequestList.get(0).getState())
-                .isEqualTo(TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
-        LinkProperties lp = mDataNetworkUT.getLinkProperties();
-        assertThat(lp.getAddresses()).containsExactly(
-                InetAddresses.parseNumericAddress(IPV4_ADDRESS),
-                InetAddresses.parseNumericAddress(IPV6_ADDRESS));
-
-        ArgumentCaptor<PreciseDataConnectionState> pdcsCaptor =
-                ArgumentCaptor.forClass(PreciseDataConnectionState.class);
-        verify(mPhone, times(2)).notifyDataConnection(pdcsCaptor.capture());
-        List<PreciseDataConnectionState> pdcsList = pdcsCaptor.getAllValues();
-
-        assertThat(pdcsList.get(0).getApnSetting()).isEqualTo(mImsApnSetting);
-        assertThat(pdcsList.get(0).getState()).isEqualTo(TelephonyManager.DATA_CONNECTING);
-        assertThat(pdcsList.get(0).getId()).isEqualTo(-1);
-        assertThat(pdcsList.get(0).getNetworkType()).isEqualTo(TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(pdcsList.get(0).getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(pdcsList.get(0).getLinkProperties()).isEqualTo(new LinkProperties());
-
-        assertThat(pdcsList.get(1).getApnSetting()).isEqualTo(mImsApnSetting);
-        assertThat(pdcsList.get(1).getState()).isEqualTo(TelephonyManager.DATA_CONNECTED);
-        assertThat(pdcsList.get(1).getId()).isEqualTo(123);
-        assertThat(pdcsList.get(1).getNetworkType()).isEqualTo(TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(pdcsList.get(1).getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(pdcsList.get(1).getLinkProperties().getAddresses().get(0))
-                .isEqualTo(InetAddresses.parseNumericAddress(IPV4_ADDRESS));
-        assertThat(pdcsList.get(1).getLinkProperties().getAddresses().get(1))
-                .isEqualTo(InetAddresses.parseNumericAddress(IPV6_ADDRESS));
-
-        assertThat(mDataNetworkUT.getNetworkCapabilities()).isEqualTo(
-                networkCapabilitiesCaptor.getValue());
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_IMS)).isTrue();
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)).isFalse();
-
-        verify(mDataNetworkCallback).onConnected(eq(mDataNetworkUT));
-    }
-
-    @Test
-    public void testCreateDataNetworkOnEnterpriseSlice() throws Exception {
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
-                .build(), mPhone));
-
-        List<TrafficDescriptor> tds = List.of(
-                new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
-                        TrafficDescriptor.OsAppId.ANDROID_OS_ID, "ENTERPRISE", 1).getBytes()),
-                new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
-                        TrafficDescriptor.OsAppId.ANDROID_OS_ID, "ENTERPRISE", 5).getBytes())
-        );
-        setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123, tds);
-
-        mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers,
-                mEnterpriseDataProfile, networkRequestList,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, DataAllowedReason.NORMAL,
-                mDataNetworkCallback);
-        replaceInstance(DataNetwork.class, "mDataCallSessionStats",
-                mDataNetworkUT, mDataCallSessionStats);
-        processAllMessages();
-
-        verify(mMockedWwanDataServiceManager).setupDataCall(eq(AccessNetworkType.EUTRAN),
-                eq(mEnterpriseDataProfile), eq(false), eq(false),
-                eq(DataService.REQUEST_REASON_NORMAL), nullable(LinkProperties.class),
-                eq(DataCallResponse.PDU_SESSION_ID_NOT_SET), nullable(NetworkSliceInfo.class),
-                any(TrafficDescriptor.class), eq(false), any(Message.class));
-
-        NetworkCapabilities nc = mDataNetworkUT.getNetworkCapabilities();
-        assertThat(nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)).isTrue();
-        assertThat(nc.getEnterpriseIds()).asList().containsExactly(1, 5);
-        assertThat(nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
-    }
-
-    @Test
-    public void testCreateDataNetworkOnUrllcSlice() throws Exception {
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
-                .build(), mPhone));
-
-        List<TrafficDescriptor> tds = List.of(
-                new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
-                        TrafficDescriptor.OsAppId.ANDROID_OS_ID, "PRIORITIZE_LATENCY", 1)
-                        .getBytes())
-        );
-        setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123, tds);
-
-        mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers,
-                mUrlccDataProfile, networkRequestList,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, DataAllowedReason.NORMAL,
-                mDataNetworkCallback);
-        replaceInstance(DataNetwork.class, "mDataCallSessionStats",
-                mDataNetworkUT, mDataCallSessionStats);
-        processAllMessages();
-
-        verify(mMockedWwanDataServiceManager).setupDataCall(eq(AccessNetworkType.EUTRAN),
-                eq(mUrlccDataProfile), eq(false), eq(false),
-                eq(DataService.REQUEST_REASON_NORMAL), nullable(LinkProperties.class),
-                eq(DataCallResponse.PDU_SESSION_ID_NOT_SET), nullable(NetworkSliceInfo.class),
-                any(TrafficDescriptor.class), eq(false), any(Message.class));
-
-        NetworkCapabilities nc = mDataNetworkUT.getNetworkCapabilities();
-        assertThat(nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY))
-                .isTrue();
-    }
-
-    @Test
-    public void testCreateDataNetworkOnEmbbSlice() throws Exception {
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
-                .build(), mPhone));
-
-        List<TrafficDescriptor> tds = List.of(
-                new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
-                        TrafficDescriptor.OsAppId.ANDROID_OS_ID, "PRIORITIZE_BANDWIDTH", 1)
-                        .getBytes())
-        );
-        setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123, tds);
-
-        mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers,
-                mEmbbDataProfile, networkRequestList,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, DataAllowedReason.NORMAL,
-                mDataNetworkCallback);
-        replaceInstance(DataNetwork.class, "mDataCallSessionStats",
-                mDataNetworkUT, mDataCallSessionStats);
-        processAllMessages();
-
-        verify(mMockedWwanDataServiceManager).setupDataCall(eq(AccessNetworkType.EUTRAN),
-                eq(mEmbbDataProfile), eq(false), eq(false),
-                eq(DataService.REQUEST_REASON_NORMAL), nullable(LinkProperties.class),
-                eq(DataCallResponse.PDU_SESSION_ID_NOT_SET), nullable(NetworkSliceInfo.class),
-                any(TrafficDescriptor.class), eq(false), any(Message.class));
-
-        NetworkCapabilities nc = mDataNetworkUT.getNetworkCapabilities();
-        assertThat(nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH))
-                .isTrue();
-    }
-
-    @Test
-    public void testCreateDataNetworkOnCbsSlice() throws Exception {
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
-                .build(), mPhone));
-
-        List<TrafficDescriptor> tds = List.of(
-                new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
-                        TrafficDescriptor.OsAppId.ANDROID_OS_ID, "CBS", 1)
-                        .getBytes())
-        );
-
-        setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123, tds);
-
-        mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers,
-                mCbsDataProfile, networkRequestList,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, DataAllowedReason.NORMAL,
-                mDataNetworkCallback);
-        replaceInstance(DataNetwork.class, "mDataCallSessionStats",
-                mDataNetworkUT, mDataCallSessionStats);
-        processAllMessages();
-
-        verify(mMockedWwanDataServiceManager).setupDataCall(eq(AccessNetworkType.EUTRAN),
-                eq(mCbsDataProfile), eq(false), eq(false),
-                eq(DataService.REQUEST_REASON_NORMAL), nullable(LinkProperties.class),
-                eq(DataCallResponse.PDU_SESSION_ID_NOT_SET), nullable(NetworkSliceInfo.class),
-                any(TrafficDescriptor.class), eq(false), any(Message.class));
-
-        NetworkCapabilities nc = mDataNetworkUT.getNetworkCapabilities();
-        assertThat(nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS))
-                .isTrue();
-    }
-
-    @Test
-    public void testSlicingDataNetworkHasSlicingCapabilitiesBeforeConnected() throws Exception {
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
-                .build(), mPhone));
-
-        List<TrafficDescriptor> tds = List.of(
-                new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
-                        TrafficDescriptor.OsAppId.ANDROID_OS_ID, "CBS", 1)
-                        .getBytes())
-        );
-
-        mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers,
-                mCbsDataProfile, networkRequestList,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, DataAllowedReason.NORMAL,
-                mDataNetworkCallback);
-        replaceInstance(DataNetwork.class, "mDataCallSessionStats",
-                mDataNetworkUT, mDataCallSessionStats);
-        processAllMessages();
-
-        // Didn't call setSuccessfulSetupDataResponse, so data network should stuck in connecting.
-
-        // Verify the network has the right capability at beginning.
-        NetworkCapabilities nc = mDataNetworkUT.getNetworkCapabilities();
-        assertThat(nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS))
-                .isTrue();
-
-        // Verify the network was not detached due to not satisfied.
-        assertThat(networkRequestList).isEqualTo(mDataNetworkUT.getAttachedNetworkRequestList());
-    }
-
-    // The purpose of this test is to make sure data could be torn down properly.
-    @Test
-    public void testTearDown() throws Exception {
-        setupDataNetwork();
-        sendTearDownEvent(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, 123,
-                DataFailCause.EMM_DETACHED);
-
-        verify(mSimulatedCommandsVerifier, never()).releasePduSessionId(nullable(Message.class),
-                anyInt());
-        verify(mMockedWwanDataServiceManager).deactivateDataCall(eq(123),
-                eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
-        verify(mDataNetworkCallback).onDisconnected(eq(mDataNetworkUT), eq(
-                DataFailCause.EMM_DETACHED));
-
-        ArgumentCaptor<PreciseDataConnectionState> pdcsCaptor =
-                ArgumentCaptor.forClass(PreciseDataConnectionState.class);
-        verify(mPhone, times(4)).notifyDataConnection(pdcsCaptor.capture());
-        List<PreciseDataConnectionState> pdcsList = pdcsCaptor.getAllValues();
-
-        assertThat(pdcsList.get(2).getApnSetting()).isEqualTo(mInternetApnSetting);
-        assertThat(pdcsList.get(2).getState()).isEqualTo(TelephonyManager.DATA_DISCONNECTING);
-        assertThat(pdcsList.get(2).getId()).isEqualTo(123);
-        assertThat(pdcsList.get(2).getNetworkType()).isEqualTo(TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(pdcsList.get(2).getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-
-        assertThat(pdcsList.get(3).getApnSetting()).isEqualTo(mInternetApnSetting);
-        assertThat(pdcsList.get(3).getState()).isEqualTo(TelephonyManager.DATA_DISCONNECTED);
-        assertThat(pdcsList.get(3).getId()).isEqualTo(123);
-        assertThat(pdcsList.get(3).getNetworkType()).isEqualTo(TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(pdcsList.get(3).getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-    }
-
-    @Test
-    public void testAirplaneModeShutdownDeactivateData() throws Exception {
-        setupDataNetwork();
-
-        mDataNetworkUT.tearDown(DataNetwork.TEAR_DOWN_REASON_AIRPLANE_MODE_ON);
-        processAllMessages();
-
-        // Make sure REQUEST_REASON_SHUTDOWN is sent when tear down reason is APM.
-        verify(mMockedWwanDataServiceManager).deactivateDataCall(eq(123),
-                eq(DataService.REQUEST_REASON_SHUTDOWN), any(Message.class));
-    }
-
-
-    @Test
-    public void testCreateDataNetworkOnIwlan() throws Exception {
-        doReturn(mIwlanNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
-                eq(NetworkRegistrationInfo.DOMAIN_PS),
-                eq(AccessNetworkConstants.TRANSPORT_TYPE_WLAN));
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
-                .getPreferredTransportByNetworkCapability(NetworkCapabilities.NET_CAPABILITY_IMS);
-
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                .build(), mPhone));
-
-        setSuccessfulSetupDataResponse(mMockedWlanDataServiceManager, 123);
-
-        mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers,
-                mImsDataProfile, networkRequestList, AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
-                DataAllowedReason.NORMAL, mDataNetworkCallback);
-        replaceInstance(DataNetwork.class, "mDataCallSessionStats",
-                mDataNetworkUT, mDataCallSessionStats);
-        processAllMessages();
-
-        processAllMessages();
-        verify(mSimulatedCommandsVerifier).allocatePduSessionId(any(Message.class));
-        verify(mMockedWlanDataServiceManager).setupDataCall(eq(AccessNetworkType.IWLAN),
-                eq(mImsDataProfile), eq(false), eq(false),
-                eq(DataService.REQUEST_REASON_NORMAL), nullable(LinkProperties.class),
-                eq(1), nullable(NetworkSliceInfo.class),
-                any(TrafficDescriptor.class), eq(true), any(Message.class));
-        assertThat(mDataNetworkUT.getId()).isEqualTo(123);
-        assertThat(networkRequestList.get(0).getState())
-                .isEqualTo(TelephonyNetworkRequest.REQUEST_STATE_SATISFIED);
-        LinkProperties lp = mDataNetworkUT.getLinkProperties();
-        assertThat(lp.getAddresses()).containsExactly(
-                InetAddresses.parseNumericAddress(IPV4_ADDRESS),
-                InetAddresses.parseNumericAddress(IPV6_ADDRESS));
-
-        ArgumentCaptor<PreciseDataConnectionState> pdcsCaptor =
-                ArgumentCaptor.forClass(PreciseDataConnectionState.class);
-        verify(mPhone, times(2)).notifyDataConnection(pdcsCaptor.capture());
-        List<PreciseDataConnectionState> pdcsList = pdcsCaptor.getAllValues();
-
-        assertThat(pdcsList.get(0).getApnSetting()).isEqualTo(mImsApnSetting);
-        assertThat(pdcsList.get(0).getState()).isEqualTo(TelephonyManager.DATA_CONNECTING);
-        assertThat(pdcsList.get(0).getId()).isEqualTo(-1);
-        assertThat(pdcsList.get(0).getNetworkType()).isEqualTo(TelephonyManager.NETWORK_TYPE_IWLAN);
-        assertThat(pdcsList.get(0).getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        assertThat(pdcsList.get(0).getLinkProperties()).isEqualTo(new LinkProperties());
-
-        assertThat(pdcsList.get(1).getApnSetting()).isEqualTo(mImsApnSetting);
-        assertThat(pdcsList.get(1).getState()).isEqualTo(TelephonyManager.DATA_CONNECTED);
-        assertThat(pdcsList.get(1).getId()).isEqualTo(123);
-        assertThat(pdcsList.get(1).getNetworkType()).isEqualTo(TelephonyManager.NETWORK_TYPE_IWLAN);
-        assertThat(pdcsList.get(1).getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        assertThat(pdcsList.get(1).getLinkProperties().getAddresses()).containsExactly(
-                InetAddresses.parseNumericAddress(IPV4_ADDRESS),
-                InetAddresses.parseNumericAddress(IPV6_ADDRESS));
-
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_IMS)).isTrue();
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)).isFalse();
-
-        verify(mDataNetworkCallback).onConnected(eq(mDataNetworkUT));
-    }
-
-    @Test
-    public void testTearDownIwlan() throws Exception {
-        testCreateDataNetworkOnIwlan();
-        sendTearDownEvent(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, 123,
-                DataFailCause.EMM_DETACHED);
-
-        verify(mSimulatedCommandsVerifier).releasePduSessionId(nullable(Message.class), eq(1));
-        verify(mMockedWlanDataServiceManager).deactivateDataCall(eq(123),
-                eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
-        verify(mDataNetworkCallback).onDisconnected(eq(mDataNetworkUT), eq(
-                DataFailCause.EMM_DETACHED));
-
-        ArgumentCaptor<PreciseDataConnectionState> pdcsCaptor =
-                ArgumentCaptor.forClass(PreciseDataConnectionState.class);
-        verify(mPhone, times(4)).notifyDataConnection(pdcsCaptor.capture());
-        List<PreciseDataConnectionState> pdcsList = pdcsCaptor.getAllValues();
-
-        assertThat(pdcsList.get(2).getApnSetting()).isEqualTo(mImsApnSetting);
-        assertThat(pdcsList.get(2).getState()).isEqualTo(TelephonyManager.DATA_DISCONNECTING);
-        assertThat(pdcsList.get(2).getId()).isEqualTo(123);
-        assertThat(pdcsList.get(2).getNetworkType()).isEqualTo(TelephonyManager.NETWORK_TYPE_IWLAN);
-        assertThat(pdcsList.get(2).getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-
-        assertThat(pdcsList.get(3).getApnSetting()).isEqualTo(mImsApnSetting);
-        assertThat(pdcsList.get(3).getState()).isEqualTo(TelephonyManager.DATA_DISCONNECTED);
-        assertThat(pdcsList.get(3).getId()).isEqualTo(123);
-        assertThat(pdcsList.get(3).getNetworkType()).isEqualTo(TelephonyManager.NETWORK_TYPE_IWLAN);
-        assertThat(pdcsList.get(3).getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-    }
-
-    @Test
-    public void testHandover() throws Exception {
-        setupDataNetwork();
-
-        setSuccessfulSetupDataResponse(mMockedWlanDataServiceManager, 456);
-        // Now handover to IWLAN
-        mDataNetworkUT.startHandover(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, null);
-        processAllMessages();
-
-        verify(mLinkBandwidthEstimator).unregisterCallback(any(
-                LinkBandwidthEstimatorCallback.class));
-        assertThat(mDataNetworkUT.getTransport())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        assertThat(mDataNetworkUT.getId()).isEqualTo(456);
-        verify(mDataNetworkCallback).onHandoverSucceeded(eq(mDataNetworkUT));
-
-        ArgumentCaptor<PreciseDataConnectionState> pdcsCaptor =
-                ArgumentCaptor.forClass(PreciseDataConnectionState.class);
-        verify(mPhone, times(4)).notifyDataConnection(pdcsCaptor.capture());
-        List<PreciseDataConnectionState> pdcsList = pdcsCaptor.getAllValues();
-
-        assertThat(pdcsList).hasSize(4);
-        assertThat(pdcsList.get(0).getState()).isEqualTo(TelephonyManager.DATA_CONNECTING);
-        assertThat(pdcsList.get(1).getState()).isEqualTo(TelephonyManager.DATA_CONNECTED);
-        assertThat(pdcsList.get(2).getState())
-                .isEqualTo(TelephonyManager.DATA_HANDOVER_IN_PROGRESS);
-        assertThat(pdcsList.get(3).getState()).isEqualTo(TelephonyManager.DATA_CONNECTED);
-
-        // Now handover back to cellular
-        Mockito.clearInvocations(mDataNetworkCallback);
-        Mockito.clearInvocations(mLinkBandwidthEstimator);
-        mDataNetworkUT.startHandover(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, null);
-        processAllMessages();
-
-        verify(mLinkBandwidthEstimator).registerCallback(
-                any(LinkBandwidthEstimatorCallback.class));
-        assertThat(mDataNetworkUT.getTransport())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(mDataNetworkUT.getId()).isEqualTo(123);
-        verify(mDataNetworkCallback).onHandoverSucceeded(eq(mDataNetworkUT));
-    }
-
-    @Test
-    public void testHandoverFailed() throws Exception {
-        setupDataNetwork();
-
-        setFailedSetupDataResponse(mMockedWlanDataServiceManager,
-                DataServiceCallback.RESULT_ERROR_TEMPORARILY_UNAVAILABLE);
-        // Now attempt to handover to IWLAN but fail it.
-        mDataNetworkUT.startHandover(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, null);
-        processAllMessages();
-
-        verify(mDataNetworkCallback).onHandoverFailed(eq(mDataNetworkUT),
-                eq(DataFailCause.SERVICE_TEMPORARILY_UNAVAILABLE), eq(-1L),
-                eq(DataCallResponse.HANDOVER_FAILURE_MODE_LEGACY));
-        verify(mLinkBandwidthEstimator, never()).unregisterForBandwidthChanged(
-                eq(mDataNetworkUT.getHandler()));
-        assertThat(mDataNetworkUT.getTransport())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        assertThat(mDataNetworkUT.getId()).isEqualTo(123);
-
-        ArgumentCaptor<PreciseDataConnectionState> pdcsCaptor =
-                ArgumentCaptor.forClass(PreciseDataConnectionState.class);
-        verify(mPhone, times(4)).notifyDataConnection(pdcsCaptor.capture());
-        List<PreciseDataConnectionState> pdcsList = pdcsCaptor.getAllValues();
-
-        assertThat(pdcsList).hasSize(4);
-        assertThat(pdcsList.get(0).getState()).isEqualTo(TelephonyManager.DATA_CONNECTING);
-        assertThat(pdcsList.get(1).getState()).isEqualTo(TelephonyManager.DATA_CONNECTED);
-        assertThat(pdcsList.get(2).getState())
-                .isEqualTo(TelephonyManager.DATA_HANDOVER_IN_PROGRESS);
-        assertThat(pdcsList.get(3).getState()).isEqualTo(TelephonyManager.DATA_CONNECTED);
-        assertThat(pdcsList.get(3).getLastCauseCode())
-                .isEqualTo(DataFailCause.SERVICE_TEMPORARILY_UNAVAILABLE);
-    }
-
-    @Test
-    public void testAdminAndOwnerUids() throws Exception {
-        doReturn(ADMIN_UID2).when(mCarrierPrivilegesTracker).getCarrierServicePackageUid();
-        setupDataNetwork();
-
-        assertThat(mDataNetworkUT.getNetworkCapabilities().getAdministratorUids()).asList()
-                .containsExactly(ADMIN_UID1, ADMIN_UID2);
-        assertThat(mDataNetworkUT.getNetworkCapabilities().getOwnerUid()).isEqualTo(ADMIN_UID2);
-    }
-
-    private void setupDataNetwork() throws Exception {
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), mPhone));
-
-        setSuccessfulSetupDataResponse(mMockedWwanDataServiceManager, 123);
-
-        mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers,
-                mInternetDataProfile, networkRequestList,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                DataAllowedReason.NORMAL, mDataNetworkCallback);
-        replaceInstance(DataNetwork.class, "mDataCallSessionStats",
-                mDataNetworkUT, mDataCallSessionStats);
-        mDataNetworkUT.sendMessage(18/*EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED*/,
-                new AsyncResult(null, new int[]{ADMIN_UID1, ADMIN_UID2}, null));
-        processAllMessages();
-    }
-
-    // Make sure data network register all the required events and unregister all of them at the
-    // end.
-    @Test
-    public void testRegisterUnregisterEvents() throws Exception {
-        // Setup a new data network and tear down.
-        testTearDown();
-
-        // Verify register all events.
-        verify(mDataConfigManager).registerForConfigUpdate(any(Handler.class), anyInt());
-        verify(mDisplayInfoController).registerForTelephonyDisplayInfoChanged(
-                any(Handler.class), anyInt(), eq(null));
-        verify(mMockedWwanDataServiceManager).registerForDataCallListChanged(
-                any(Handler.class), anyInt());
-        verify(mMockedWlanDataServiceManager).registerForDataCallListChanged(
-                any(Handler.class), anyInt());
-        verify(mCarrierPrivilegesTracker).registerCarrierPrivilegesListener(any(Handler.class),
-                anyInt(), eq(null));
-        verify(mLinkBandwidthEstimator).registerCallback(
-                any(LinkBandwidthEstimatorCallback.class));
-        verify(mSimulatedCommandsVerifier).registerForNattKeepaliveStatus(any(Handler.class),
-                anyInt(), eq(null));
-        verify(mSimulatedCommandsVerifier).registerForPcoData(any(Handler.class), anyInt(),
-                eq(null));
-        verify(mVcnManager).addVcnNetworkPolicyChangeListener(any(Executor.class),
-                any(VcnNetworkPolicyChangeListener.class));
-        verify(mSST).registerForCssIndicatorChanged(any(Handler.class), anyInt(), eq(null));
-        verify(mSST).registerForServiceStateChanged(any(Handler.class), anyInt());
-        verify(mCT).registerForVoiceCallStarted(any(Handler.class), anyInt(), eq(null));
-        verify(mCT).registerForVoiceCallEnded(any(Handler.class), anyInt(), eq(null));
-        verify(mImsCT).registerForVoiceCallStarted(any(Handler.class), anyInt(), eq(null));
-        verify(mImsCT).registerForVoiceCallEnded(any(Handler.class), anyInt(), eq(null));
-
-        // Verify unregister all events.
-        verify(mDataConfigManager).unregisterForConfigUpdate(any(Handler.class));
-        verify(mDisplayInfoController).unregisterForTelephonyDisplayInfoChanged(any(Handler.class));
-        verify(mMockedWwanDataServiceManager).unregisterForDataCallListChanged(any(Handler.class));
-        verify(mMockedWlanDataServiceManager).unregisterForDataCallListChanged(any(Handler.class));
-        verify(mCarrierPrivilegesTracker).unregisterCarrierPrivilegesListener(any(Handler.class));
-        verify(mLinkBandwidthEstimator).unregisterCallback(
-                any(LinkBandwidthEstimatorCallback.class));
-        verify(mSimulatedCommandsVerifier).unregisterForNattKeepaliveStatus(any(Handler.class));
-        verify(mSimulatedCommandsVerifier).unregisterForPcoData(any(Handler.class));
-        verify(mVcnManager).removeVcnNetworkPolicyChangeListener(
-                any(VcnNetworkPolicyChangeListener.class));
-        verify(mSST).unregisterForCssIndicatorChanged(any(Handler.class));
-        verify(mSST).unregisterForServiceStateChanged(any(Handler.class));
-        verify(mImsCT).unregisterForVoiceCallStarted(any(Handler.class));
-        verify(mImsCT).unregisterForVoiceCallEnded(any(Handler.class));
-        verify(mCT).unregisterForVoiceCallStarted(any(Handler.class));
-        verify(mCT).unregisterForVoiceCallEnded(any(Handler.class));
-    }
-
-    @Test
-    public void testVcnPolicy() throws Exception {
-        doAnswer(invocation -> {
-            NetworkCapabilities nc = invocation.getArgument(0);
-            NetworkCapabilities policyNc = new NetworkCapabilities.Builder(nc)
-                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                    .build();
-
-            return new VcnNetworkPolicyResult(
-                    false /* isTearDownRequested */, policyNc);
-        }).when(mVcnManager).applyVcnNetworkPolicy(any(), any());
-
-        setupDataNetwork();
-
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)).isFalse();
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)).isFalse();
-    }
-
-    @Test
-    public void testVcnPolicyUpdated() throws Exception {
-        setupDataNetwork();
-
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)).isTrue();
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)).isTrue();
-
-        doAnswer(invocation -> {
-            NetworkCapabilities nc = invocation.getArgument(0);
-            NetworkCapabilities policyNc = new NetworkCapabilities.Builder(nc)
-                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                    .build();
-
-            return new VcnNetworkPolicyResult(
-                    false /* isTearDownRequested */, policyNc);
-        }).when(mVcnManager).applyVcnNetworkPolicy(any(), any());
-        triggerVcnNetworkPolicyChanged();
-
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)).isFalse();
-    }
-
-    @Test
-    public void testVcnPolicyTeardownRequested() throws Exception {
-        setupDataNetwork();
-
-        doAnswer(invocation -> {
-            NetworkCapabilities nc = invocation.getArgument(0);
-
-            return new VcnNetworkPolicyResult(
-                    true /* isTearDownRequested */, nc);
-        }).when(mVcnManager).applyVcnNetworkPolicy(any(), any());
-        triggerVcnNetworkPolicyChanged();
-
-        assertThat(mDataNetworkUT.isConnected()).isFalse();
-    }
-
-    private void triggerVcnNetworkPolicyChanged() {
-        ArgumentCaptor<VcnNetworkPolicyChangeListener> captor =
-                ArgumentCaptor.forClass(VcnNetworkPolicyChangeListener.class);
-
-        verify(mVcnManager).addVcnNetworkPolicyChangeListener(any(), captor.capture());
-        captor.getValue().onPolicyChanged();
-        processAllMessages();
-    }
-
-    @Test
-    public void testDeactivateDataCallRadioNotAvailable() throws Exception {
-        setupDataNetwork();
-
-        assertThat(mDataNetworkUT.isConnected()).isTrue();
-        mDataNetworkUT.sendMessage(19/*EVENT_DEACTIVATE_DATA_NETWORK_RESPONSE*/,
-                4/*RESULT_ERROR_ILLEGAL_STATE*/);
-        processAllMessages();
-
-        verify(mDataNetworkCallback).onDisconnected(eq(mDataNetworkUT), eq(
-                DataFailCause.RADIO_NOT_AVAILABLE));
-        assertThat(mDataNetworkUT.isConnected()).isFalse();
-    }
-
-    @Test
-    public void testNetworkAgentConfig() throws Exception {
-        testCreateImsDataNetwork();
-
-        ArgumentCaptor<NetworkAgentConfig> captor = ArgumentCaptor
-                .forClass(NetworkAgentConfig.class);
-
-        verify(mConnectivityManager).registerNetworkAgent(any(), any(NetworkInfo.class),
-                any(LinkProperties.class), any(NetworkCapabilities.class), any(), captor.capture(),
-                anyInt());
-
-        NetworkAgentConfig networkAgentConfig = captor.getValue();
-
-        assertThat(networkAgentConfig.getSubscriberId()).isEqualTo(FAKE_IMSI);
-        assertThat(networkAgentConfig.getLegacyExtraInfo()).isEqualTo(
-                mImsApnSetting.getApnName());
-        assertThat(networkAgentConfig.getLegacyType()).isEqualTo(ConnectivityManager.TYPE_MOBILE);
-        assertThat(networkAgentConfig.getLegacyTypeName()).isEqualTo("MOBILE");
-        assertThat(networkAgentConfig.legacySubType).isEqualTo(TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(networkAgentConfig.skip464xlat).isTrue();
-    }
-
-    @Test
-    public void testDataNetworkHasCapabilitiesAtBeginning() {
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), mPhone));
-        mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers,
-                mInternetDataProfile, networkRequestList,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                DataAllowedReason.NORMAL, mDataNetworkCallback);
-        NetworkCapabilities caps = mDataNetworkUT.getNetworkCapabilities();
-        assertThat(caps).isNotNull();
-        assertThat(caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
-        assertThat(caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)).isTrue();
-    }
-
-    @Test
-    public void testBandwidthUpdate() throws Exception {
-        setupDataNetwork();
-
-        ArgumentCaptor<LinkBandwidthEstimatorCallback> linkBandwidthCallbackCaptor =
-                ArgumentCaptor.forClass(LinkBandwidthEstimatorCallback.class);
-        verify(mLinkBandwidthEstimator).registerCallback(linkBandwidthCallbackCaptor.capture());
-        LinkBandwidthEstimatorCallback linkBandwidthEstimatorCallback =
-                linkBandwidthCallbackCaptor.getValue();
-
-        linkBandwidthEstimatorCallback.onBandwidthChanged(12345, 67890);
-        processAllMessages();
-
-        assertThat(mDataNetworkUT.getNetworkCapabilities().getLinkUpstreamBandwidthKbps())
-                .isEqualTo(12345);
-        assertThat(mDataNetworkUT.getNetworkCapabilities().getLinkDownstreamBandwidthKbps())
-                .isEqualTo(67890);
-
-        linkBandwidthEstimatorCallback.onBandwidthChanged(123, 456);
-        processAllMessages();
-
-        assertThat(mDataNetworkUT.getNetworkCapabilities().getLinkUpstreamBandwidthKbps())
-                .isEqualTo(123);
-        assertThat(mDataNetworkUT.getNetworkCapabilities().getLinkDownstreamBandwidthKbps())
-                .isEqualTo(456);
-    }
-
-    @Test
-    public void testChangingImmutableCapabilities() throws Exception {
-        setupDataNetwork();
-
-        List<TrafficDescriptor> tds = List.of(
-                new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
-                        TrafficDescriptor.OsAppId.ANDROID_OS_ID, "ENTERPRISE", 1).getBytes())
-                );
-
-        DataCallResponse response = new DataCallResponse.Builder()
-                .setCause(DataFailCause.NONE)
-                .setRetryDurationMillis(DataCallResponse.RETRY_DURATION_UNDEFINED)
-                .setId(123)
-                .setLinkStatus(DataCallResponse.LINK_STATUS_ACTIVE)
-                .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
-                .setQosBearerSessions(new ArrayList<>())
-                .setTrafficDescriptors(tds)
-                .build();
-        // Sending the data call list changed event which has enterprise traffic descriptor added.
-        mDataNetworkUT.sendMessage(8/*EVENT_DATA_STATE_CHANGED*/,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                        new ArrayList<>(Arrays.asList(response)), null));
-        processAllMessages();
-
-        // Agent re-created, so register should be called twice.
-        verify(mConnectivityManager, times(2)).registerNetworkAgent(any(), any(NetworkInfo.class),
-                any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
-                anyInt());
-
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)).isTrue();
-    }
-
-    @Test
-    public void testChangingMutableCapabilities() throws Exception {
-        setupDataNetwork();
-
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)).isFalse();
-
-        doReturn(Set.of(TelephonyManager.NETWORK_TYPE_LTE)).when(mDataNetworkController)
-                .getUnmeteredOverrideNetworkTypes();
-        mDataNetworkUT.sendMessage(1/*EVENT_DATA_CONFIG_UPDATED*/);
-
-        processAllMessages();
-
-        // Agent not re-created, so register should be called once.
-        verify(mConnectivityManager, times(1)).registerNetworkAgent(any(), any(NetworkInfo.class),
-                any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
-                anyInt());
-
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED)).isTrue();
-    }
-
-    @Test
-    public void testMovingToNonVops() throws Exception {
-        DataSpecificRegistrationInfo dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_SUPPORTED));
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
-        testCreateImsDataNetwork();
-
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_MMTEL)).isTrue();
-
-        dsri = new DataSpecificRegistrationInfo(8, false, true, true,
-                new LteVopsSupportInfo(LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED,
-                        LteVopsSupportInfo.LTE_STATUS_NOT_SUPPORTED));
-        logd("Trigger non VoPS");
-        serviceStateChanged(TelephonyManager.NETWORK_TYPE_LTE,
-                NetworkRegistrationInfo.REGISTRATION_STATE_HOME, dsri);
-        // MMTEL should not be removed.
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_MMTEL)).isTrue();
-    }
-
-    @Test
-    public void testCssIndicatorChanged() throws Exception {
-        setupDataNetwork();
-
-        mDataNetworkUT.sendMessage(24/*EVENT_CSS_INDICATOR_CHANGED*/);
-        doReturn(false).when(mSST).isConcurrentVoiceAndDataAllowed();
-        processAllMessages();
-
-        // Suspended
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)).isFalse();
-
-        mDataNetworkUT.sendMessage(24/*EVENT_CSS_INDICATOR_CHANGED*/);
-        doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed();
-        processAllMessages();
-
-        // Not suspended
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)).isTrue();
-    }
-
-    @Test
-    public void testNonConcurrentDataSuspended() throws Exception {
-        doReturn(false).when(mSST).isConcurrentVoiceAndDataAllowed();
-        setupDataNetwork();
-
-        // Voice call start.
-        doReturn(PhoneConstants.State.OFFHOOK).when(mCT).getState();
-        mDataNetworkUT.sendMessage(22/*EVENT_VOICE_CALL_STARTED*/);
-        processAllMessages();
-
-        // Suspended
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)).isFalse();
-
-        // Voice call ended.
-        doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
-        mDataNetworkUT.sendMessage(23/*EVENT_VOICE_CALL_ENDED*/);
-        processAllMessages();
-
-        // Not suspended
-        assertThat(mDataNetworkUT.getNetworkCapabilities().hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED)).isTrue();
-    }
-
-    @Test
-    public void testGetApnTypeCapability() throws Exception {
-        testCreateDataNetwork();
-        assertThat(mDataNetworkUT.getApnTypeNetworkCapability())
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-
-        TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder().addCapability(
-                        NetworkCapabilities.NET_CAPABILITY_SUPL).build(), mPhone);
-        mDataNetworkUT.attachNetworkRequests(new NetworkRequestList(networkRequest));
-        processAllMessages();
-
-        assertThat(mDataNetworkUT.getApnTypeNetworkCapability())
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_SUPL);
-
-        mDataNetworkUT.detachNetworkRequest(networkRequest);
-        processAllMessages();
-
-        assertThat(mDataNetworkUT.getApnTypeNetworkCapability())
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_INTERNET);
-    }
-
-    @Test
-    public void testGetPriority() throws Exception {
-        testCreateDataNetwork();
-
-        // Internet priority is 20
-        assertThat(mDataNetworkUT.getPriority()).isEqualTo(20);
-
-        TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder().addCapability(
-                        NetworkCapabilities.NET_CAPABILITY_SUPL).build(), mPhone);
-        mDataNetworkUT.attachNetworkRequests(new NetworkRequestList(networkRequest));
-        processAllMessages();
-
-        // SUPL priority is 80
-        assertThat(mDataNetworkUT.getPriority()).isEqualTo(80);
-
-        mDataNetworkUT.detachNetworkRequest(networkRequest);
-        processAllMessages();
-
-        // Internet priority is 20
-        assertThat(mDataNetworkUT.getPriority()).isEqualTo(20);
-    }
-
-    @Test
-    public void testIpChangedV4() throws Exception {
-        testCreateDataNetwork();
-
-        DataCallResponse response = new DataCallResponse.Builder()
-                .setCause(0)
-                .setRetryDurationMillis(-1L)
-                .setId(123)
-                .setLinkStatus(2)
-                .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
-                .setInterfaceName("ifname")
-                .setAddresses(Arrays.asList(
-                        new LinkAddress(InetAddresses.parseNumericAddress(IPV4_ADDRESS1), 32),
-                        new LinkAddress(IPV6_ADDRESS + "/64")))
-                .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress("10.0.2.3"),
-                        InetAddresses.parseNumericAddress("fd00:976a::9")))
-                .setGatewayAddresses(Arrays.asList(
-                        InetAddresses.parseNumericAddress("10.0.2.15"),
-                        InetAddresses.parseNumericAddress("fe80::2")))
-                .setPcscfAddresses(Arrays.asList(
-                        InetAddresses.parseNumericAddress("fd00:976a:c305:1d::8"),
-                        InetAddresses.parseNumericAddress("fd00:976a:c202:1d::7"),
-                        InetAddresses.parseNumericAddress("fd00:976a:c305:1d::5")))
-                .setMtuV4(1234)
-                .setMtuV6(5678)
-                .setPduSessionId(1)
-                .setQosBearerSessions(new ArrayList<>())
-                .setTrafficDescriptors(Collections.emptyList())
-                .build();
-
-        // IP changes
-        mDataNetworkUT.obtainMessage(8/*EVENT_DATA_STATE_CHANGED*/,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                        List.of(response), null)).sendToTarget();
-        processAllMessages();
-
-        ArgumentCaptor<LinkProperties> linkPropertiesCaptor =
-                ArgumentCaptor.forClass(LinkProperties.class);
-
-        // Agent re-created, so register should be called twice.
-        verify(mConnectivityManager, times(2)).registerNetworkAgent(any(), any(NetworkInfo.class),
-                linkPropertiesCaptor.capture(), any(NetworkCapabilities.class), any(), any(),
-                anyInt());
-        // The new agent should have the new IP address.
-        assertThat(linkPropertiesCaptor.getValue().getAllAddresses()).containsExactly(
-                InetAddresses.parseNumericAddress(IPV4_ADDRESS1),
-                InetAddresses.parseNumericAddress(IPV6_ADDRESS));
-
-        assertThat(linkPropertiesCaptor.getValue()).isEqualTo(mDataNetworkUT.getLinkProperties());
-    }
-
-    @Test
-    public void testIpChangedV6() throws Exception {
-        testCreateDataNetwork();
-
-        DataCallResponse response = new DataCallResponse.Builder()
-                .setCause(0)
-                .setRetryDurationMillis(-1L)
-                .setId(123)
-                .setLinkStatus(2)
-                .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
-                .setInterfaceName("ifname")
-                .setAddresses(Arrays.asList(new LinkAddress(IPV6_ADDRESS1 + "/64")))
-                .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress("10.0.2.3"),
-                        InetAddresses.parseNumericAddress("fd00:976a::9")))
-                .setGatewayAddresses(Arrays.asList(
-                        InetAddresses.parseNumericAddress("10.0.2.15"),
-                        InetAddresses.parseNumericAddress("fe80::2")))
-                .setPcscfAddresses(Arrays.asList(
-                        InetAddresses.parseNumericAddress("fd00:976a:c305:1d::8"),
-                        InetAddresses.parseNumericAddress("fd00:976a:c202:1d::7"),
-                        InetAddresses.parseNumericAddress("fd00:976a:c305:1d::5")))
-                .setMtuV4(1234)
-                .setMtuV6(5678)
-                .setPduSessionId(1)
-                .setQosBearerSessions(new ArrayList<>())
-                .setTrafficDescriptors(Collections.emptyList())
-                .build();
-
-        // IP changes
-        mDataNetworkUT.obtainMessage(8/*EVENT_DATA_STATE_CHANGED*/,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                        List.of(response), null)).sendToTarget();
-        processAllMessages();
-
-        ArgumentCaptor<LinkProperties> linkPropertiesCaptor =
-                ArgumentCaptor.forClass(LinkProperties.class);
-
-        // Agent re-created, so register should be called twice.
-        verify(mConnectivityManager, times(2)).registerNetworkAgent(any(), any(NetworkInfo.class),
-                linkPropertiesCaptor.capture(), any(NetworkCapabilities.class), any(), any(),
-                anyInt());
-        // The new agent should have the new IP address.
-        assertThat(linkPropertiesCaptor.getValue().getAllAddresses()).containsExactly(
-                InetAddresses.parseNumericAddress(IPV6_ADDRESS1));
-
-        assertThat(linkPropertiesCaptor.getValue()).isEqualTo(mDataNetworkUT.getLinkProperties());
-    }
-
-    @Test
-    public void testIpChangedFromV4ToV6() throws Exception {
-        doAnswer(invocation -> {
-            final Message msg = (Message) invocation.getArguments()[10];
-
-            DataCallResponse response = new DataCallResponse.Builder()
-                    .setCause(0)
-                    .setRetryDurationMillis(-1L)
-                    .setId(123)
-                    .setLinkStatus(2)
-                    .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
-                    .setInterfaceName("ifname")
-                    .setAddresses(Arrays.asList(
-                            new LinkAddress(InetAddresses.parseNumericAddress(IPV4_ADDRESS), 32)))
-                    .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress("10.0.2.3"),
-                            InetAddresses.parseNumericAddress("fd00:976a::9")))
-                    .setGatewayAddresses(Arrays.asList(
-                            InetAddresses.parseNumericAddress("10.0.2.15"),
-                            InetAddresses.parseNumericAddress("fe80::2")))
-                    .setPcscfAddresses(Arrays.asList(
-                            InetAddresses.parseNumericAddress("fd00:976a:c305:1d::8"),
-                            InetAddresses.parseNumericAddress("fd00:976a:c202:1d::7"),
-                            InetAddresses.parseNumericAddress("fd00:976a:c305:1d::5")))
-                    .setMtuV4(1234)
-                    .setMtuV6(5678)
-                    .setPduSessionId(1)
-                    .setQosBearerSessions(new ArrayList<>())
-                    .setTrafficDescriptors(Collections.emptyList())
-                    .build();
-            msg.getData().putParcelable("data_call_response", response);
-            msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
-            msg.sendToTarget();
-            return null;
-        }).when(mMockedWwanDataServiceManager).setupDataCall(anyInt(), any(DataProfile.class),
-                anyBoolean(), anyBoolean(), anyInt(), any(), anyInt(), any(), any(), anyBoolean(),
-                any(Message.class));
-
-        NetworkRequestList networkRequestList = new NetworkRequestList();
-        networkRequestList.add(new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build(), mPhone));
-
-        mDataNetworkUT = new DataNetwork(mPhone, Looper.myLooper(), mDataServiceManagers,
-                mInternetDataProfile, networkRequestList,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                DataAllowedReason.NORMAL, mDataNetworkCallback);
-        replaceInstance(DataNetwork.class, "mDataCallSessionStats",
-                mDataNetworkUT, mDataCallSessionStats);
-        processAllMessages();
-
-        DataCallResponse response = new DataCallResponse.Builder()
-                .setCause(0)
-                .setRetryDurationMillis(-1L)
-                .setId(123)
-                .setLinkStatus(2)
-                .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
-                .setInterfaceName("ifname")
-                .setAddresses(Arrays.asList(new LinkAddress(IPV6_ADDRESS + "/64")))
-                .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress("10.0.2.3"),
-                        InetAddresses.parseNumericAddress("fd00:976a::9")))
-                .setGatewayAddresses(Arrays.asList(
-                        InetAddresses.parseNumericAddress("10.0.2.15"),
-                        InetAddresses.parseNumericAddress("fe80::2")))
-                .setPcscfAddresses(Arrays.asList(
-                        InetAddresses.parseNumericAddress("fd00:976a:c305:1d::8"),
-                        InetAddresses.parseNumericAddress("fd00:976a:c202:1d::7"),
-                        InetAddresses.parseNumericAddress("fd00:976a:c305:1d::5")))
-                .setMtuV4(1234)
-                .setMtuV6(5678)
-                .setPduSessionId(1)
-                .setQosBearerSessions(new ArrayList<>())
-                .setTrafficDescriptors(Collections.emptyList())
-                .build();
-
-        // IP changes
-        mDataNetworkUT.obtainMessage(8/*EVENT_DATA_STATE_CHANGED*/,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                        List.of(response), null)).sendToTarget();
-        processAllMessages();
-
-        // Agent should not be re-created, so register should be called ony once.
-        verify(mConnectivityManager, times(1)).registerNetworkAgent(any(), any(NetworkInfo.class),
-                any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
-                anyInt());
-
-        // The network should have IPv6 address now
-        assertThat(mDataNetworkUT.getLinkProperties().getAllAddresses()).containsExactly(
-                InetAddresses.parseNumericAddress(IPV6_ADDRESS));
-    }
-
-    @Test
-    public void testIpChangedV4Removed() throws Exception {
-        testCreateDataNetwork();
-
-        DataCallResponse response = new DataCallResponse.Builder()
-                .setCause(0)
-                .setRetryDurationMillis(-1L)
-                .setId(123)
-                .setLinkStatus(2)
-                .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
-                .setInterfaceName("ifname")
-                .setAddresses(Arrays.asList(new LinkAddress(IPV6_ADDRESS + "/64")))
-                .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress("10.0.2.3"),
-                        InetAddresses.parseNumericAddress("fd00:976a::9")))
-                .setGatewayAddresses(Arrays.asList(
-                        InetAddresses.parseNumericAddress("10.0.2.15"),
-                        InetAddresses.parseNumericAddress("fe80::2")))
-                .setPcscfAddresses(Arrays.asList(
-                        InetAddresses.parseNumericAddress("fd00:976a:c305:1d::8"),
-                        InetAddresses.parseNumericAddress("fd00:976a:c202:1d::7"),
-                        InetAddresses.parseNumericAddress("fd00:976a:c305:1d::5")))
-                .setMtuV4(1234)
-                .setMtuV6(5678)
-                .setPduSessionId(1)
-                .setQosBearerSessions(new ArrayList<>())
-                .setTrafficDescriptors(Collections.emptyList())
-                .build();
-
-        // IP changes
-        mDataNetworkUT.obtainMessage(8/*EVENT_DATA_STATE_CHANGED*/,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                        List.of(response), null)).sendToTarget();
-        processAllMessages();
-
-        // Agent should not be re-created, so register should be called ony once.
-        verify(mConnectivityManager, times(1)).registerNetworkAgent(any(), any(NetworkInfo.class),
-                any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
-                anyInt());
-
-        // The network should have IPv6 address now
-        assertThat(mDataNetworkUT.getLinkProperties().getAllAddresses()).containsExactly(
-                InetAddresses.parseNumericAddress(IPV6_ADDRESS));
-    }
-
-    @Test
-    public void testIpChangedV6Removed() throws Exception {
-        testCreateDataNetwork();
-
-        DataCallResponse response = new DataCallResponse.Builder()
-                .setCause(0)
-                .setRetryDurationMillis(-1L)
-                .setId(123)
-                .setLinkStatus(2)
-                .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
-                .setInterfaceName("ifname")
-                .setAddresses(Arrays.asList(new LinkAddress(
-                        InetAddresses.parseNumericAddress(IPV4_ADDRESS), 32)))
-                .setDnsAddresses(Arrays.asList(InetAddresses.parseNumericAddress("10.0.2.3"),
-                        InetAddresses.parseNumericAddress("fd00:976a::9")))
-                .setGatewayAddresses(Arrays.asList(
-                        InetAddresses.parseNumericAddress("10.0.2.15"),
-                        InetAddresses.parseNumericAddress("fe80::2")))
-                .setPcscfAddresses(Arrays.asList(
-                        InetAddresses.parseNumericAddress("fd00:976a:c305:1d::8"),
-                        InetAddresses.parseNumericAddress("fd00:976a:c202:1d::7"),
-                        InetAddresses.parseNumericAddress("fd00:976a:c305:1d::5")))
-                .setMtuV4(1234)
-                .setMtuV6(5678)
-                .setPduSessionId(1)
-                .setQosBearerSessions(new ArrayList<>())
-                .setTrafficDescriptors(Collections.emptyList())
-                .build();
-
-        // IP changes
-        mDataNetworkUT.obtainMessage(8/*EVENT_DATA_STATE_CHANGED*/,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                        List.of(response), null)).sendToTarget();
-        processAllMessages();
-
-        // Agent should not be re-created, so register should be called ony once.
-        verify(mConnectivityManager, times(1)).registerNetworkAgent(any(), any(NetworkInfo.class),
-                any(LinkProperties.class), any(NetworkCapabilities.class), any(), any(),
-                anyInt());
-
-        // The network should have IPv6 address now
-        assertThat(mDataNetworkUT.getLinkProperties().getAllAddresses()).containsExactly(
-                InetAddresses.parseNumericAddress(IPV4_ADDRESS));
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
deleted file mode 100644
index 783df82..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileManagerTest.java
+++ /dev/null
@@ -1,950 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-
-import android.annotation.NonNull;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.MatrixCursor;
-import android.net.ConnectivityManager;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.Uri;
-import android.os.Looper;
-import android.os.SystemClock;
-import android.provider.Telephony;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.NetworkRegistrationInfo;
-import android.telephony.ServiceState;
-import android.telephony.TelephonyManager;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataProfile;
-import android.telephony.data.TrafficDescriptor.OsAppId;
-import android.test.mock.MockContentProvider;
-import android.test.mock.MockContentResolver;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
-import com.android.internal.telephony.data.DataProfileManager.DataProfileManagerCallback;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.stream.Collectors;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class DataProfileManagerTest extends TelephonyTest {
-    private static final String GENERAL_PURPOSE_APN = "GP_APN";
-    private static final String GENERAL_PURPOSE_APN1 = "GP_APN1";
-    private static final String IMS_APN = "IMS_APN";
-    private static final String TETHERING_APN = "DUN_APN";
-    private static final String PLMN = "330123";
-
-    // Mocked classes
-    private DataProfileManagerCallback mDataProfileManagerCallback;
-
-    private DataProfileManager mDataProfileManagerUT;
-
-    private final ApnSettingContentProvider mApnSettingContentProvider =
-            new ApnSettingContentProvider();
-
-    private int mPreferredApnId = 0;
-
-    private DataNetworkControllerCallback mDataNetworkControllerCallback;
-
-    private boolean mSimInserted = true;
-
-    private class ApnSettingContentProvider extends MockContentProvider {
-        public final String[] APN_COLUMNS = new String[]{
-                Telephony.Carriers._ID, Telephony.Carriers.NUMERIC,
-                Telephony.Carriers.NAME, Telephony.Carriers.APN,
-                Telephony.Carriers.PROXY, Telephony.Carriers.PORT,
-                Telephony.Carriers.MMSC, Telephony.Carriers.MMSPROXY,
-                Telephony.Carriers.MMSPORT, Telephony.Carriers.USER,
-                Telephony.Carriers.PASSWORD, Telephony.Carriers.AUTH_TYPE,
-                Telephony.Carriers.TYPE,
-                Telephony.Carriers.PROTOCOL,
-                Telephony.Carriers.ROAMING_PROTOCOL,
-                Telephony.Carriers.CARRIER_ENABLED,
-                Telephony.Carriers.PROFILE_ID,
-                Telephony.Carriers.MODEM_PERSIST,
-                Telephony.Carriers.MAX_CONNECTIONS,
-                Telephony.Carriers.WAIT_TIME_RETRY,
-                Telephony.Carriers.TIME_LIMIT_FOR_MAX_CONNECTIONS,
-                Telephony.Carriers.MTU,
-                Telephony.Carriers.MTU_V4,
-                Telephony.Carriers.MTU_V6,
-                Telephony.Carriers.MVNO_TYPE,
-                Telephony.Carriers.MVNO_MATCH_DATA,
-                Telephony.Carriers.NETWORK_TYPE_BITMASK,
-                Telephony.Carriers.LINGERING_NETWORK_TYPE_BITMASK,
-                Telephony.Carriers.APN_SET_ID,
-                Telephony.Carriers.CARRIER_ID,
-                Telephony.Carriers.SKIP_464XLAT,
-                Telephony.Carriers.ALWAYS_ON,
-        };
-
-        private int mPreferredApnSet = 0;
-
-        public List<Object> mAllApnSettings = List.of(
-                new Object[]{
-                        1,                      // id
-                        PLMN,                   // numeric
-                        GENERAL_PURPOSE_APN,    // name
-                        GENERAL_PURPOSE_APN,    // apn
-                        "",                     // proxy
-                        "",                     // port
-                        "",                     // mmsc
-                        "",                     // mmsproxy
-                        "",                     // mmsport
-                        "",                     // user
-                        "",                     // password
-                        -1,                     // authtype
-                        "default,supl,mms,ia",  // types
-                        "IPV4V6",               // protocol
-                        "IPV4V6",               // roaming_protocol
-                        1,                      // carrier_enabled
-                        0,                      // profile_id
-                        1,                      // modem_cognitive
-                        0,                      // max_conns
-                        0,                      // wait_time
-                        0,                      // max_conns_time
-                        0,                      // mtu
-                        1280,                   // mtu_v4
-                        1280,                   // mtu_v6
-                        "",                     // mvno_type
-                        "",                     // mnvo_match_data
-                        TelephonyManager.NETWORK_TYPE_BITMASK_LTE
-                                | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
-                        0,                      // lingering_network_type_bitmask
-                        0,                      // apn_set_id
-                        -1,                     // carrier_id
-                        -1,                     // skip_464xlat
-                        0                       // always_on
-                },
-                new Object[]{
-                        2,                      // id
-                        PLMN,                   // numeric
-                        IMS_APN,                // name
-                        IMS_APN,                // apn
-                        "",                     // proxy
-                        "",                     // port
-                        "",                     // mmsc
-                        "",                     // mmsproxy
-                        "",                     // mmsport
-                        "",                     // user
-                        "",                     // password
-                        -1,                     // authtype
-                        "ims",                  // types
-                        "IPV4V6",               // protocol
-                        "IPV4V6",               // roaming_protocol
-                        1,                      // carrier_enabled
-                        0,                      // profile_id
-                        1,                      // modem_cognitive
-                        0,                      // max_conns
-                        0,                      // wait_time
-                        0,                      // max_conns_time
-                        0,                      // mtu
-                        0,                      // mtu_v4
-                        0,                      // mtu_v6
-                        "",                     // mvno_type
-                        "",                     // mnvo_match_data
-                        TelephonyManager.NETWORK_TYPE_BITMASK_LTE, // network_type_bitmask
-                        0,                      // lingering_network_type_bitmask
-                        0,                      // apn_set_id
-                        -1,                     // carrier_id
-                        -1,                     // skip_464xlat
-                        0                       // always_on
-                },
-                new Object[]{
-                        3,                      // id
-                        PLMN,                   // numeric
-                        TETHERING_APN,          // name
-                        TETHERING_APN,          // apn
-                        "",                     // proxy
-                        "",                     // port
-                        "",                     // mmsc
-                        "",                     // mmsproxy
-                        "",                     // mmsport
-                        "",                     // user
-                        "",                     // password
-                        -1,                     // authtype
-                        "dun",                  // types
-                        "IPV4V6",               // protocol
-                        "IPV4V6",               // roaming_protocol
-                        1,                      // carrier_enabled
-                        2,                      // profile_id
-                        1,                      // modem_cognitive
-                        0,                      // max_conns
-                        0,                      // wait_time
-                        0,                      // max_conns_time
-                        0,                      // mtu
-                        0,                      // mtu_v4
-                        0,                      // mtu_v6
-                        "",                     // mvno_type
-                        "",                     // mnvo_match_data
-                        TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
-                        0,                      // lingering_network_type_bitmask
-                        0,                      // apn_set_id
-                        -1,                     // carrier_id
-                        -1,                     // skip_464xlat
-                        0                       // alwys_on
-                },
-                new Object[]{
-                        4,                      // id
-                        PLMN,                   // numeric
-                        GENERAL_PURPOSE_APN1,   // name
-                        GENERAL_PURPOSE_APN1,   // apn
-                        "",                     // proxy
-                        "",                     // port
-                        "",                     // mmsc
-                        "",                     // mmsproxy
-                        "",                     // mmsport
-                        "",                     // user
-                        "",                     // password
-                        -1,                     // authtype
-                        "default,supl",         // types
-                        "IPV4V6",               // protocol
-                        "IPV4V6",               // roaming_protocol
-                        1,                      // carrier_enabled
-                        0,                      // profile_id
-                        1,                      // modem_cognitive
-                        0,                      // max_conns
-                        0,                      // wait_time
-                        0,                      // max_conns_time
-                        0,                      // mtu
-                        0,                      // mtu_v4
-                        0,                      // mtu_v6
-                        "",                     // mvno_type
-                        "",                     // mnvo_match_data
-                        TelephonyManager.NETWORK_TYPE_BITMASK_LTE
-                                | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
-                        0,                      // lingering_network_type_bitmask
-                        0,                      // apn_set_id
-                        -1,                     // carrier_id
-                        -1,                     // skip_464xlat
-                        0                       // always_on
-                },
-                // This APN entry is created to test de-duping.
-                new Object[]{
-                        5,                      // id
-                        PLMN,                   // numeric
-                        GENERAL_PURPOSE_APN,    // name
-                        GENERAL_PURPOSE_APN,    // apn
-                        "",                     // proxy
-                        "",                     // port
-                        "",                     // mmsc
-                        "",                     // mmsproxy
-                        "",                     // mmsport
-                        "",                     // user
-                        "",                     // password
-                        -1,                     // authtype
-                        "fota",                 // types
-                        "IPV4V6",               // protocol
-                        "IPV4V6",               // roaming_protocol
-                        1,                      // carrier_enabled
-                        0,                      // profile_id
-                        1,                      // modem_cognitive
-                        0,                      // max_conns
-                        0,                      // wait_time
-                        0,                      // max_conns_time
-                        0,                      // mtu
-                        0,                      // mtu_v4
-                        0,                      // mtu_v6
-                        "",                     // mvno_type
-                        "",                     // mnvo_match_data
-                        TelephonyManager.NETWORK_TYPE_BITMASK_LTE
-                                | TelephonyManager.NETWORK_TYPE_BITMASK_NR, // network_type_bitmask
-                        0,                      // lingering_network_type_bitmask
-                        0,                      // apn_set_id
-                        -1,                     // carrier_id
-                        -1,                     // skip_464xlat
-                        0                       // always_on
-                }
-        );
-
-        @Override
-        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-                String sortOrder) {
-            logd("ApnSettingContentProvider: query");
-            logd("   uri = " + uri);
-            logd("   projection = " + Arrays.toString(projection));
-            logd("   selection = " + selection);
-            logd("   selectionArgs = " + Arrays.toString(selectionArgs));
-            logd("   sortOrder = " + sortOrder);
-
-            if (uri.compareTo(Telephony.Carriers.CONTENT_URI) == 0
-                    || uri.toString().startsWith(Uri.withAppendedPath(
-                    Telephony.Carriers.CONTENT_URI, "filtered").toString())
-                    || uri.toString().startsWith(Uri.withAppendedPath(
-                    Telephony.Carriers.SIM_APN_URI, "filtered").toString())) {
-                if (projection == null) {
-
-                    logd("Query '" + PLMN + "' APN settings");
-                    MatrixCursor mc = new MatrixCursor(APN_COLUMNS);
-                    if (mSimInserted) {
-                        for (Object apnSetting : mAllApnSettings) {
-                            mc.addRow((Object[]) apnSetting);
-                        }
-                    }
-                    return mc;
-                }
-            } else if (isPathPrefixMatch(uri,
-                    Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "preferapnset"))) {
-                MatrixCursor mc = new MatrixCursor(
-                        new String[]{Telephony.Carriers.APN_SET_ID});
-                // apn_set_id is the only field used with this URL
-                mc.addRow(new Object[]{ mPreferredApnSet });
-                mc.addRow(new Object[]{ 0 });
-                return mc;
-            } else if (uri.isPathPrefixMatch(Telephony.Carriers.PREFERRED_APN_URI)) {
-                for (Object apnSetting : mAllApnSettings) {
-                    int id = (int) ((Object[]) apnSetting)[0];
-                    if (id == mPreferredApnId) {
-                        MatrixCursor mc = new MatrixCursor(APN_COLUMNS);
-                        mc.addRow((Object[]) apnSetting);
-                        return mc;
-                    }
-                }
-            }
-
-            return null;
-        }
-
-        @Override
-        public int update(Uri url, ContentValues values, String where, String[] whereArgs) {
-            mPreferredApnSet = values.getAsInteger(Telephony.Carriers.APN_SET_ID);
-            return 1;
-        }
-
-        @Override
-        public int delete(Uri uri, String selection, String[] selectionArgs) {
-            return 0;
-        }
-
-        @Override
-        public Uri insert(Uri uri, ContentValues values) {
-            logd("ApnSettingContentProvider: uri=" + uri + ", values=" + values);
-            if (uri.isPathPrefixMatch(Telephony.Carriers.PREFERRED_APN_URI)) {
-                mPreferredApnId = values.getAsInteger(Telephony.Carriers.APN_ID);
-                if (mPreferredApnId != -1) {
-                    for (Object apnSetting : mAllApnSettings) {
-                        int id = (int) ((Object[]) apnSetting)[0];
-                        if (id == mPreferredApnId) {
-                            mPreferredApnSet = (int) ((Object[]) apnSetting)[28]; //update setId too
-                        }
-                    }
-                } else {
-                    mPreferredApnSet = 0; // db is emptied
-                }
-                logd("mPreferredApnId=" + mPreferredApnId);
-            }
-            return null;
-        }
-    }
-
-    /**
-     * Test if this is a path prefix match against the given Uri. Verifies that
-     * scheme, authority, and atomic path segments match.
-     *
-     * Copied from frameworks/base/core/java/android/net/Uri.java
-     */
-    private boolean isPathPrefixMatch(Uri uriA, Uri uriB) {
-        if (!Objects.equals(uriA.getScheme(), uriB.getScheme())) return false;
-        if (!Objects.equals(uriA.getAuthority(), uriB.getAuthority())) return false;
-
-        List<String> segA = uriA.getPathSegments();
-        List<String> segB = uriB.getPathSegments();
-
-        final int size = segB.size();
-        if (segA.size() < size) return false;
-
-        for (int i = 0; i < size; i++) {
-            if (!Objects.equals(segA.get(i), segB.get(i))) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    private void dedupeDataProfiles(@NonNull List<DataProfile> dataProfiles) throws Exception {
-        Class[] cArgs = new Class[1];
-        cArgs[0] = List.class;
-        Method method = DataProfileManager.class.getDeclaredMethod("dedupeDataProfiles", cArgs);
-        method.setAccessible(true);
-        method.invoke(mDataProfileManagerUT, dataProfiles);
-    }
-
-    private @NonNull List<DataProfile> getAllDataProfiles() throws Exception {
-        Field field = DataProfileManager.class.getDeclaredField("mAllDataProfiles");
-        field.setAccessible(true);
-        return (List<DataProfile>) field.get(mDataProfileManagerUT);
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        logd("DataProfileManagerTest +Setup!");
-        super.setUp(getClass().getSimpleName());
-        mDataProfileManagerCallback = Mockito.mock(DataProfileManagerCallback.class);
-        ((MockContentResolver) mContext.getContentResolver()).addProvider(
-                Telephony.Carriers.CONTENT_URI.getAuthority(), mApnSettingContentProvider);
-
-        doReturn(true).when(mDataConfigManager).isConfigCarrierSpecific();
-        doReturn(List.of(ApnSetting.TYPE_IA, ApnSetting.TYPE_DEFAULT))
-                .when(mDataConfigManager).getAllowedInitialAttachApnTypes();
-        doAnswer(invocation -> {
-            ((Runnable) invocation.getArguments()[0]).run();
-            return null;
-        }).when(mDataProfileManagerCallback).invokeFromExecutor(any(Runnable.class));
-        mDataProfileManagerUT = new DataProfileManager(mPhone, mDataNetworkController,
-                mMockedWwanDataServiceManager, Looper.myLooper(), mDataProfileManagerCallback);
-        ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor =
-                ArgumentCaptor.forClass(DataNetworkControllerCallback.class);
-        verify(mDataNetworkController).registerDataNetworkControllerCallback(
-                        dataNetworkControllerCallbackCaptor.capture());
-        mDataNetworkControllerCallback = dataNetworkControllerCallbackCaptor.getValue();
-        mDataProfileManagerUT.obtainMessage(1 /*EVENT_DATA_CONFIG_UPDATED*/).sendToTarget();
-        processAllMessages();
-
-        logd("DataProfileManagerTest -Setup!");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mDataProfileManagerUT = null;
-        mDataNetworkControllerCallback = null;
-        super.tearDown();
-    }
-
-    @Test
-    public void testGetDataProfileForNetworkRequest() {
-        NetworkRequest request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
-        DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
-                TelephonyManager.NETWORK_TYPE_LTE);
-
-        assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
-        assertThat(dp.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
-
-        request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)
-                .build();
-        tnr = new TelephonyNetworkRequest(request, mPhone);
-        dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
-                TelephonyManager.NETWORK_TYPE_LTE);
-
-        assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
-        assertThat(dp.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
-
-        request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                .build();
-        tnr = new TelephonyNetworkRequest(request, mPhone);
-        dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
-                TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
-        assertThat(dp.getApnSetting().getApnName()).isEqualTo(IMS_APN);
-
-        request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
-                .build();
-        tnr = new TelephonyNetworkRequest(request, mPhone);
-        dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
-                TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dp).isNull();
-
-        doReturn(new NetworkRegistrationInfo.Builder()
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .build()).when(mServiceState).getNetworkRegistrationInfo(anyInt(), anyInt());
-
-        request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
-                .build();
-        tnr = new TelephonyNetworkRequest(request, mPhone);
-        dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
-                TelephonyManager.NETWORK_TYPE_NR);
-        assertThat(dp.canSatisfy(tnr.getCapabilities())).isTrue();
-        assertThat(dp.getApnSetting().getApnName()).isEqualTo(TETHERING_APN);
-    }
-
-    @Test
-    public void testGetDataProfileForNetworkRequestNoCompatibleRat() {
-        NetworkRequest request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
-        DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
-                TelephonyManager.NETWORK_TYPE_GSM);
-        // Should not find data profile due to RAT incompatible.
-        assertThat(dp).isNull();
-    }
-
-    @Test
-    public void testGetDataProfileForNetworkRequestRotation() {
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
-        DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
-        logd("Set setLastSetupTimestamp on " + dataProfile);
-        dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
-
-        // See if another one can be returned.
-        dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN1);
-    }
-
-    @Test
-    public void testGetDataProfileForEnterpriseNetworkRequest() {
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
-                        .build(), mPhone);
-        DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile.getApnSetting()).isNull();
-        OsAppId osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId());
-
-        assertThat(osAppId.getOsId()).isEqualTo(OsAppId.ANDROID_OS_ID);
-        assertThat(osAppId.getAppId()).isEqualTo("ENTERPRISE");
-        assertThat(osAppId.getDifferentiator()).isEqualTo(1);
-
-        tnr = new TelephonyNetworkRequest(new NetworkRequest(new NetworkCapabilities()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
-                .addEnterpriseId(2), ConnectivityManager.TYPE_NONE,
-                0, NetworkRequest.Type.REQUEST), mPhone);
-        dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile.getApnSetting()).isNull();
-        osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId());
-
-        assertThat(osAppId.getOsId()).isEqualTo(OsAppId.ANDROID_OS_ID);
-        assertThat(osAppId.getAppId()).isEqualTo("ENTERPRISE");
-        assertThat(osAppId.getDifferentiator()).isEqualTo(2);
-    }
-
-    @Test
-    public void testGetDataProfileForUrllcNetworkRequest() {
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
-                        .build(), mPhone);
-        DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile.getApnSetting()).isNull();
-        OsAppId osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId());
-
-        assertThat(osAppId.getOsId()).isEqualTo(OsAppId.ANDROID_OS_ID);
-        assertThat(osAppId.getAppId()).isEqualTo("PRIORITIZE_LATENCY");
-        assertThat(osAppId.getDifferentiator()).isEqualTo(1);
-    }
-
-    @Test
-    public void testGetDataProfileForEmbbNetworkRequest() {
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
-                        .build(), mPhone);
-        DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile.getApnSetting()).isNull();
-        OsAppId osAppId = new OsAppId(dataProfile.getTrafficDescriptor().getOsAppId());
-
-        assertThat(osAppId.getOsId()).isEqualTo(OsAppId.ANDROID_OS_ID);
-        assertThat(osAppId.getAppId()).isEqualTo("PRIORITIZE_BANDWIDTH");
-        assertThat(osAppId.getDifferentiator()).isEqualTo(1);
-    }
-
-
-    @Test
-    public void testSetPreferredDataProfile() {
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
-        DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
-        dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
-        dataProfile.setPreferred(true);
-        mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(dataProfile));
-        processAllMessages();
-
-        // See if the same one can be returned.
-        dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
-    }
-
-    @Test
-    public void testSetInitialAttachDataProfile() {
-        ArgumentCaptor<DataProfile> dataProfileCaptor =
-                ArgumentCaptor.forClass(DataProfile.class);
-
-        verify(mMockedWwanDataServiceManager).setInitialAttachApn(dataProfileCaptor.capture(),
-                eq(false), eq(null));
-        assertThat(dataProfileCaptor.getValue().getApnSetting().getApnName())
-                .isEqualTo(GENERAL_PURPOSE_APN);
-    }
-
-    @Test
-    public void testSimRemoval() {
-        Mockito.clearInvocations(mDataProfileManagerCallback);
-        mSimInserted = false;
-        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
-        processAllMessages();
-
-        verify(mDataProfileManagerCallback).onDataProfilesChanged();
-
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
-        DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile).isNull();
-
-        tnr = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
-                        .build(), mPhone);
-        dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("sos");
-
-        tnr = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                        .build(), mPhone);
-        dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("ims");
-    }
-
-    @Test
-    public void testSimInsertedAgain() throws Exception {
-        testSimRemoval();
-        Mockito.clearInvocations(mDataProfileManagerCallback);
-        Mockito.clearInvocations(mMockedWwanDataServiceManager);
-
-        doReturn(List.of(ApnSetting.TYPE_IMS))
-                .when(mDataConfigManager).getAllowedInitialAttachApnTypes();
-
-        mSimInserted = true;
-        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
-        processAllMessages();
-
-        ArgumentCaptor<DataProfile> dataProfileCaptor =
-                ArgumentCaptor.forClass(DataProfile.class);
-
-        verify(mDataProfileManagerCallback).onDataProfilesChanged();
-        verify(mMockedWwanDataServiceManager).setInitialAttachApn(dataProfileCaptor.capture(),
-                eq(false), eq(null));
-
-        // Should only use IMS APN for initial attach
-        assertThat(dataProfileCaptor.getValue().getApnSetting().getApnName()).isEqualTo(IMS_APN);
-
-        DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                        .build(), mPhone),
-                TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(IMS_APN);
-    }
-
-    @Test
-    public void testDedupeDataProfiles() {
-        NetworkRequest request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)
-                .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
-        // This should get the merged data profile after deduping.
-        DataProfile dp = mDataProfileManagerUT.getDataProfileForNetworkRequest(tnr,
-                TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
-    }
-
-    @Test
-    public void testDedupeDataProfiles2() throws Exception {
-        DataProfile dataProfile1 = new DataProfile.Builder()
-                .setApnSetting(new ApnSetting.Builder()
-                        .setEntryName("general")
-                        .setApnName("apn")
-                        .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS
-                                | ApnSetting.TYPE_SUPL | ApnSetting.TYPE_HIPRI)
-                        .setUser("user")
-                        .setPassword("password")
-                        .setAuthType(ApnSetting.AUTH_TYPE_CHAP)
-                        .setMmsc(Uri.parse("http://mms-s"))
-                        .setMmsProxyAddress("mmsc.proxy")
-                        .setMmsProxyPort(8080)
-                        .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
-                        .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
-                        .setCarrierEnabled(true)
-                        .build())
-                .build();
-
-        DataProfile dataProfile2 = new DataProfile.Builder()
-                .setApnSetting(new ApnSetting.Builder()
-                        .setEntryName("XCAP")
-                        .setApnName("apn")
-                        .setApnTypeBitmask(ApnSetting.TYPE_XCAP)
-                        .setUser("user")
-                        .setPassword("password")
-                        .setAuthType(ApnSetting.AUTH_TYPE_CHAP)
-                        .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
-                        .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
-                        .setCarrierEnabled(true)
-                        .build())
-                .build();
-
-        logd("apn1=" + dataProfile1.getApnSetting());
-        logd("apn2=" + dataProfile2.getApnSetting());
-        logd("apn1 can handle default=" + dataProfile1.getApnSetting()
-                .canHandleType(ApnSetting.TYPE_DEFAULT));
-        logd("apn2 can handle default=" + dataProfile2.getApnSetting()
-                .canHandleType(ApnSetting.TYPE_DEFAULT));
-        assertThat(dataProfile1.getApnSetting().similar(dataProfile2.getApnSetting())).isTrue();
-
-        List<DataProfile> dataProfiles = new ArrayList<>(Arrays.asList(dataProfile2, dataProfile1));
-
-        dedupeDataProfiles(dataProfiles);
-        // After deduping, there should be only one.
-        assertThat(dataProfiles).hasSize(1);
-
-        DataProfile dataProfile = dataProfiles.get(0);
-        assertThat(dataProfile.getApnSetting()).isNotNull();
-
-        logd("Merged profile=" + dataProfile);
-        assertThat(dataProfile.getApnSetting().getEntryName()).isEqualTo("general");
-        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo("apn");
-        assertThat(dataProfile.getApnSetting().getApnTypeBitmask()).isEqualTo(
-                ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS | ApnSetting.TYPE_SUPL
-                        | ApnSetting.TYPE_HIPRI | ApnSetting.TYPE_XCAP);
-        assertThat(dataProfile.getApnSetting().getUser()).isEqualTo("user");
-        assertThat(dataProfile.getApnSetting().getPassword()).isEqualTo("password");
-        assertThat(dataProfile.getApnSetting().getAuthType()).isEqualTo(ApnSetting.AUTH_TYPE_CHAP);
-        assertThat(dataProfile.getApnSetting().getMmsc()).isEqualTo(Uri.parse("http://mms-s"));
-        assertThat(dataProfile.getApnSetting().getMmsProxyAddressAsString())
-                .isEqualTo("mmsc.proxy");
-        assertThat(dataProfile.getApnSetting().getMmsProxyPort()).isEqualTo(8080);
-        assertThat(dataProfile.getApnSetting().getProtocol()).isEqualTo(ApnSetting.PROTOCOL_IPV4V6);
-        assertThat(dataProfile.getApnSetting().getRoamingProtocol())
-                .isEqualTo(ApnSetting.PROTOCOL_IPV4V6);
-    }
-
-    @Test
-    public void testDedupeDataProfiles3() throws Exception {
-        DataProfile dataProfile1 = new DataProfile.Builder()
-                .setApnSetting(new ApnSetting.Builder()
-                        .setEntryName("BTT Lastgenphone")
-                        .setId(1)
-                        .setOperatorNumeric("123456")
-                        .setApnName("lastgenphone")
-                        .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS
-                                | ApnSetting.TYPE_SUPL | ApnSetting.TYPE_FOTA)
-                        .setMmsc(Uri.parse("http://mmsc.mobile.btt.net"))
-                        .setMmsProxyAddress("proxy.mobile.btt.net")
-                        .setMmsProxyPort(80)
-                        .setMtuV4(1410)
-                        .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
-                        .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
-                        .setCarrierEnabled(true)
-                        .build())
-                .build();
-
-        DataProfile dataProfile2 = new DataProfile.Builder()
-                .setApnSetting(new ApnSetting.Builder()
-                        .setEntryName("BTT XCAP")
-                        .setId(5)
-                        .setOperatorNumeric("123456")
-                        .setApnName("lastgenphone")
-                        .setApnTypeBitmask(ApnSetting.TYPE_XCAP)
-                        .setProtocol(ApnSetting.PROTOCOL_IPV4V6)
-                        .setRoamingProtocol(ApnSetting.PROTOCOL_IPV4V6)
-                        .setCarrierEnabled(true)
-                        .build())
-                .build();
-
-        List<DataProfile> dataProfiles = new ArrayList<>(Arrays.asList(dataProfile2, dataProfile1));
-
-        logd("dp1.apnSetting, dp2.apnSetting similar="
-                + dataProfile1.getApnSetting().similar(dataProfile2.getApnSetting()));
-
-        dedupeDataProfiles(dataProfiles);
-        // After deduping, there should be only one.
-        assertThat(dataProfiles).hasSize(1);
-
-        DataProfile dataProfile = dataProfiles.get(0);
-        assertThat(dataProfile.getApnSetting()).isNotNull();
-
-
-        logd("After merged: " + dataProfile);
-        assertThat(dataProfile.getApnSetting().getApnTypeBitmask()).isEqualTo(
-                ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS | ApnSetting.TYPE_SUPL
-                        | ApnSetting.TYPE_FOTA | ApnSetting.TYPE_XCAP);
-    }
-
-    @Test
-    public void testDefaultEmergencyDataProfileValid() {
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
-                .build(), mPhone);
-        DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-
-        assertThat(dataProfile.getApn()).isEqualTo("sos");
-        assertThat(dataProfile.getTrafficDescriptor().getDataNetworkName()).isEqualTo("sos");
-    }
-
-    @Test
-    public void testResetApn() {
-        mSimInserted = true;
-        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
-        processAllMessages();
-
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
-        DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN);
-        dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
-        dataProfile.setPreferred(true);
-        mDataNetworkControllerCallback.onInternetDataNetworkConnected(List.of(dataProfile));
-        processAllMessages();
-
-        // After internet connected, preferred APN should be set
-        assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isTrue();
-        assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
-
-        // APN reset
-        mPreferredApnId = -1;
-        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
-        processAllMessages();
-
-        // There should be no preferred APN after APN reset
-        assertThat(mDataProfileManagerUT.isAnyPreferredDataProfileExisting()).isFalse();
-        assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isFalse();
-    }
-
-    @Test
-    public void testResetApnWithPreferredConfig() {
-        // carrier configured preferred data profile should be picked
-        doReturn(GENERAL_PURPOSE_APN1).when(mDataConfigManager).getDefaultPreferredApn();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
-        mSimInserted = true;
-        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
-        processAllMessages();
-
-        // The carrier configured data profile should be the preferred APN after APN reset
-        DataProfile dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-
-        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN1);
-        assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
-
-        // APN reset
-        mPreferredApnId = -1;
-        mDataProfileManagerUT.obtainMessage(2 /*EVENT_APN_DATABASE_CHANGED*/).sendToTarget();
-        Mockito.clearInvocations(mDataConfigManager);
-        processAllMessages();
-
-        // The carrier configured data profile should be the preferred APN after APN reset
-        dataProfile = mDataProfileManagerUT.getDataProfileForNetworkRequest(
-                tnr, TelephonyManager.NETWORK_TYPE_LTE);
-        assertThat(dataProfile.getApnSetting().getApnName()).isEqualTo(GENERAL_PURPOSE_APN1);
-        assertThat(mDataProfileManagerUT.isDataProfilePreferred(dataProfile)).isTrue();
-    }
-
-    @Test
-    public void testTetheringApnExisting() {
-        assertThat(mDataProfileManagerUT.isTetheringDataProfileExisting(
-                TelephonyManager.NETWORK_TYPE_NR)).isTrue();
-        assertThat(mDataProfileManagerUT.isTetheringDataProfileExisting(
-                TelephonyManager.NETWORK_TYPE_LTE)).isFalse();
-    }
-
-    @Test
-    public void testTetheringApnDisabledForRoaming() {
-        doReturn(true).when(mDataConfigManager).isTetheringProfileDisabledForRoaming();
-
-        assertThat(mDataProfileManagerUT.isTetheringDataProfileExisting(
-                TelephonyManager.NETWORK_TYPE_NR)).isTrue();
-
-        ServiceState ss = new ServiceState();
-
-        ss.addNetworkRegistrationInfo(new NetworkRegistrationInfo.Builder()
-                .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_NR)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_ROAMING)
-                .setDomain(NetworkRegistrationInfo.DOMAIN_PS)
-                .build());
-
-        ss.setDataRoamingFromRegistration(true);
-        doReturn(ss).when(mSST).getServiceState();
-        doReturn(ss).when(mPhone).getServiceState();
-
-        assertThat(mDataProfileManagerUT.isTetheringDataProfileExisting(
-                TelephonyManager.NETWORK_TYPE_NR)).isFalse();
-    }
-
-    @Test
-    public void testNoDefaultIms() throws Exception {
-        List<DataProfile> dataProfiles = getAllDataProfiles();
-
-        // Since the database already had IMS, there should not be default IMS created in the
-        // database.
-        assertThat(dataProfiles.stream()
-                .filter(dp -> dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_IMS))
-                .collect(Collectors.toList())).hasSize(1);
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileTest.java
deleted file mode 100644
index 4a2eb38..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataProfileTest.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * Copyright (C) 2010 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.data;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.net.NetworkCapabilities;
-import android.os.Parcel;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataProfile;
-import android.telephony.data.TrafficDescriptor;
-
-import org.junit.Test;
-
-public class DataProfileTest {
-
-    private ApnSetting mApn1 = new ApnSetting.Builder()
-            .setId(2163)
-            .setOperatorNumeric("12345")
-            .setEntryName("fake_apn")
-            .setApnName("fake_apn")
-            .setUser("user")
-            .setPassword("passwd")
-            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
-            .setProtocol(ApnSetting.PROTOCOL_IPV6)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .setNetworkTypeBitmask(0)
-            .setProfileId(1234)
-            .setMaxConns(321)
-            .setWaitTime(456)
-            .setMaxConnsTime(789)
-            .build();
-
-    private ApnSetting mApn2 = new ApnSetting.Builder()
-            .setId(2163)
-            .setOperatorNumeric("12345")
-            .setEntryName("fake_apn")
-            .setApnName("fake_apn")
-            .setUser("user")
-            .setPassword("passwd")
-            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
-            .setProtocol(ApnSetting.PROTOCOL_IP)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .setNetworkTypeBitmask(0)
-            .setProfileId(1234)
-            .setMaxConns(111)
-            .setWaitTime(456)
-            .setMaxConnsTime(789)
-            .build();
-
-    private ApnSetting mApn3 = new ApnSetting.Builder()
-            .setId(2163)
-            .setOperatorNumeric("12345")
-            .setEntryName("fake_apn")
-            .setApnName("fake_apn")
-            .setUser("user")
-            .setPassword("passwd")
-            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
-            .setProtocol(ApnSetting.PROTOCOL_IP)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .setNetworkTypeBitmask(276600)
-            .setProfileId(1234)
-            .setMaxConns(111)
-            .setWaitTime(456)
-            .setMaxConnsTime(789)
-            .build();
-
-    private ApnSetting mApn4 = new ApnSetting.Builder()
-            .setId(2163)
-            .setOperatorNumeric("12345")
-            .setEntryName("fake_apn")
-            .setApnName("fake_apn")
-            .setUser("user")
-            .setPassword("passwd")
-            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
-            .setProtocol(ApnSetting.PROTOCOL_IP)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .setNetworkTypeBitmask(10360)
-            .setProfileId(1234)
-            .setMaxConns(111)
-            .setWaitTime(456)
-            .setMaxConnsTime(789)
-            .build();
-
-    // Disabled APN
-    private ApnSetting mApn5 = new ApnSetting.Builder()
-            .setId(2163)
-            .setOperatorNumeric("12345")
-            .setEntryName("fake_apn")
-            .setApnName("fake_apn")
-            .setUser("user")
-            .setPassword("passwd")
-            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
-            .setProtocol(ApnSetting.PROTOCOL_IPV6)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(false)
-            .setNetworkTypeBitmask(0)
-            .setProfileId(1234)
-            .setMaxConns(321)
-            .setWaitTime(456)
-            .setMaxConnsTime(789)
-            .build();
-
-
-    @Test
-    public void testCreateFromApnSetting() throws Exception {
-        DataProfile dp = new DataProfile.Builder()
-                .setApnSetting(mApn1)
-                .setPreferred(false)
-                .build();
-        assertThat(dp.getProfileId()).isEqualTo(mApn1.getProfileId());
-        assertThat(dp.getApn()).isEqualTo(mApn1.getApnName());
-        assertThat(dp.getProtocolType()).isEqualTo(mApn1.getProtocol());
-        assertThat(dp.getAuthType()).isEqualTo(ApnSetting.AUTH_TYPE_PAP_OR_CHAP);
-        assertThat(dp.getUserName()).isEqualTo(mApn1.getUser());
-        assertThat(dp.getPassword()).isEqualTo(mApn1.getPassword());
-        assertThat(dp.getType()).isEqualTo(DataProfile.TYPE_COMMON);
-        assertThat(dp.getWaitTime()).isEqualTo(mApn1.getWaitTime());
-        assertThat(dp.isEnabled()).isEqualTo(mApn1.isEnabled());
-        assertThat(dp.isPersistent()).isFalse();
-        assertThat(dp.isPreferred()).isFalse();
-    }
-
-    @Test
-    public void testCreateFromApnSettingWithNetworkTypeBitmask() throws Exception {
-        DataProfile dp = new DataProfile.Builder()
-                .setApnSetting(mApn3)
-                .setPreferred(false)
-                .build();
-        assertThat(dp.getProfileId()).isEqualTo(mApn3.getProfileId());
-        assertThat(dp.getApn()).isEqualTo(mApn3.getApnName());
-        assertThat(dp.getProtocolType()).isEqualTo(mApn3.getProtocol());
-        assertThat(dp.getAuthType()).isEqualTo(ApnSetting.AUTH_TYPE_PAP_OR_CHAP);
-        assertThat(dp.getUserName()).isEqualTo(mApn3.getUser());
-        assertThat(dp.getPassword()).isEqualTo(mApn3.getPassword());
-        assertThat(dp.getType()).isEqualTo(DataProfile.TYPE_COMMON);
-        assertThat(dp.getWaitTime()).isEqualTo(mApn3.getWaitTime());
-        assertThat(dp.isEnabled()).isEqualTo(mApn3.isEnabled());
-        int expectedBearerBitmap = mApn3.getNetworkTypeBitmask();
-        assertThat(dp.getBearerBitmask()).isEqualTo(expectedBearerBitmap);
-        dp = new DataProfile.Builder()
-                .setApnSetting(mApn4)
-                .setPreferred(false)
-                .build();
-        assertThat(dp.getType()).isEqualTo(2);  // TYPE_3GPP2
-    }
-
-    @Test
-    public void testCanSatisfy() {
-        DataProfile dp = new DataProfile.Builder()
-                .setApnSetting(mApn1)
-                .setPreferred(false)
-                .build();
-
-        assertThat(dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
-        assertThat(dp.canSatisfy(new int[]{NetworkCapabilities.NET_CAPABILITY_INTERNET,
-                NetworkCapabilities.NET_CAPABILITY_SUPL})).isTrue();
-        assertThat(dp.canSatisfy(new int[]{NetworkCapabilities.NET_CAPABILITY_INTERNET,
-                NetworkCapabilities.NET_CAPABILITY_SUPL,
-                NetworkCapabilities.NET_CAPABILITY_NOT_SUSPENDED})).isTrue();
-        assertThat(dp.canSatisfy(NetworkCapabilities.NET_CAPABILITY_MMS)).isFalse();
-        assertThat(dp.canSatisfy(new int[]{NetworkCapabilities.NET_CAPABILITY_INTERNET,
-                NetworkCapabilities.NET_CAPABILITY_MMS})).isFalse();
-    }
-
-    @Test
-    public void testEquals() throws Exception {
-        DataProfile dp1 = new DataProfile.Builder()
-                .setApnSetting(mApn1)
-                .setPreferred(false)
-                .build();
-        DataProfile dp2 = new DataProfile.Builder()
-                .setApnSetting(mApn1)
-                .setPreferred(false)
-                .build();
-        assertThat(dp1).isEqualTo(dp2);
-
-        dp2 = new DataProfile.Builder()
-                .setApnSetting(mApn2)
-                .setPreferred(false)
-                .build();
-        assertThat(dp1).isNotEqualTo(dp2);
-    }
-
-    @Test
-    public void testParcel() {
-        DataProfile dp = new DataProfile.Builder()
-                .setApnSetting(mApn1)
-                .setPreferred(false)
-                .build();
-
-        Parcel parcel = Parcel.obtain();
-        dp.writeToParcel(parcel, 0 /* flags */);
-        parcel.setDataPosition(0);
-
-        DataProfile fromParcel = DataProfile.CREATOR.createFromParcel(parcel);
-
-        assertThat(fromParcel).isEqualTo(dp);
-
-        parcel.recycle();
-    }
-
-    @Test
-    public void testIsEnabled() {
-        TrafficDescriptor td = new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
-                TrafficDescriptor.OsAppId.ANDROID_OS_ID, "ENTERPRISE", 1).getBytes());
-
-        DataProfile dp = new DataProfile.Builder()
-                .setApnSetting(mApn5)
-                .setPreferred(false)
-                .build();
-        assertThat(dp.isEnabled()).isFalse();
-
-        dp = new DataProfile.Builder()
-                .setApnSetting(mApn1)
-                .build();
-        assertThat(dp.isEnabled()).isTrue();
-
-        dp = new DataProfile.Builder()
-                .setTrafficDescriptor(td)
-                .build();
-        assertThat(dp.isEnabled()).isTrue();
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
deleted file mode 100644
index bdb1929..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataRetryManagerTest.java
+++ /dev/null
@@ -1,734 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import static com.android.internal.telephony.data.DataRetryManager.DataSetupRetryEntry;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertThrows;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.os.AsyncResult;
-import android.os.Looper;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataCallResponse;
-import android.telephony.data.DataProfile;
-import android.telephony.data.ThrottleStatus;
-import android.telephony.data.TrafficDescriptor;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.util.SparseArray;
-
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.data.DataRetryManager.DataHandoverRetryRule;
-import com.android.internal.telephony.data.DataRetryManager.DataRetryManagerCallback;
-import com.android.internal.telephony.data.DataRetryManager.DataSetupRetryRule;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.stream.Collectors;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class DataRetryManagerTest extends TelephonyTest {
-    private final DataProfile mDataProfile1 = new DataProfile.Builder()
-            .setApnSetting(new ApnSetting.Builder()
-                    .setId(2163)
-                    .setOperatorNumeric("12345")
-                    .setEntryName("fake_apn1")
-                    .setApnName("fake_apn1")
-                    .setUser("user")
-                    .setPassword("passwd")
-                    .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
-                    .setProtocol(ApnSetting.PROTOCOL_IPV6)
-                    .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-                    .setCarrierEnabled(true)
-                    .setNetworkTypeBitmask(0)
-                    .setProfileId(1234)
-                    .setMaxConns(321)
-                    .setWaitTime(456)
-                    .setMaxConnsTime(789)
-                    .build())
-                .setPreferred(false)
-                .build();
-
-    private final DataProfile mDataProfile2 = new DataProfile.Builder()
-            .setApnSetting(new ApnSetting.Builder()
-                    .setId(2163)
-                    .setOperatorNumeric("12345")
-                    .setEntryName("fake_apn2")
-                    .setApnName("fake_apn2")
-                    .setUser("user")
-                    .setPassword("passwd")
-                    .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL
-                            | ApnSetting.TYPE_FOTA)
-                    .setProtocol(ApnSetting.PROTOCOL_IPV6)
-                    .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-                    .setCarrierEnabled(true)
-                    .setNetworkTypeBitmask(0)
-                    .setProfileId(1234)
-                    .setMaxConns(321)
-                    .setWaitTime(456)
-                    .setMaxConnsTime(789)
-                    .build())
-            .setPreferred(false)
-            .build();
-
-    private final DataProfile mDataProfile3 = new DataProfile.Builder()
-            .setApnSetting(new ApnSetting.Builder()
-                    .setId(2163)
-                    .setOperatorNumeric("12345")
-                    .setEntryName("fake_ims")
-                    .setApnName("fake_ims")
-                    .setUser("user")
-                    .setPassword("passwd")
-                    .setApnTypeBitmask(ApnSetting.TYPE_IMS)
-                    .setProtocol(ApnSetting.PROTOCOL_IPV6)
-                    .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-                    .setCarrierEnabled(true)
-                    .setNetworkTypeBitmask(0)
-                    .setProfileId(1234)
-                    .setMaxConns(321)
-                    .setWaitTime(456)
-                    .setMaxConnsTime(789)
-                    .build())
-            .setPreferred(false)
-            .build();
-
-    private final List<DataProfile> mAllDataProfileList = List.of(mDataProfile1, mDataProfile2,
-            mDataProfile3);
-
-    // Mocked classes
-    private DataRetryManagerCallback mDataRetryManagerCallbackMock;
-
-    private DataRetryManager mDataRetryManagerUT;
-
-    @Before
-    public void setUp() throws Exception {
-        logd("DataRetryManagerTest +Setup!");
-        super.setUp(getClass().getSimpleName());
-        mDataRetryManagerCallbackMock = Mockito.mock(DataRetryManagerCallback.class);
-        doAnswer(invocation -> {
-            ((Runnable) invocation.getArguments()[0]).run();
-            return null;
-        }).when(mDataRetryManagerCallbackMock).invokeFromExecutor(any(Runnable.class));
-        SparseArray<DataServiceManager> mockedDataServiceManagers = new SparseArray<>();
-        mockedDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
-                mMockedWwanDataServiceManager);
-        mockedDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
-                mMockedWlanDataServiceManager);
-        mDataRetryManagerUT = new DataRetryManager(mPhone, mDataNetworkController,
-                mockedDataServiceManagers, Looper.myLooper(), mDataRetryManagerCallbackMock);
-
-        doAnswer(invocation -> {
-            String apnName = (String) invocation.getArguments()[0];
-            TrafficDescriptor td = (TrafficDescriptor) invocation.getArguments()[1];
-
-            if (apnName == null && td == null) return null;
-
-            List<DataProfile> dataProfiles = mAllDataProfileList;
-            if (apnName != null) {
-                dataProfiles = dataProfiles.stream()
-                        .filter(dp -> dp.getApnSetting() != null
-                                && apnName.equals(dp.getApnSetting().getApnName()))
-                        .collect(Collectors.toList());
-            }
-            if (td != null) {
-                dataProfiles = dataProfiles.stream()
-                        .filter(dp -> dp.getTrafficDescriptor() != null
-                                && td.equals(dp.getTrafficDescriptor()))
-                        .collect(Collectors.toList());
-            }
-            return dataProfiles.isEmpty() ? null : dataProfiles.get(0);
-        }).when(mDataProfileManager).getDataProfile(anyString(), any());
-
-        logd("DataRetryManagerTest -Setup!");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mDataRetryManagerUT = null;
-        super.tearDown();
-    }
-
-    // The purpose of this test is to ensure retry rule in string format can be correctly parsed.
-    @Test
-    public void testDataSetupRetryRulesParsingFromString() {
-        String ruleString = "  capabilities   =    eims,     retry_interval = 1000   ";
-        DataSetupRetryRule rule = new DataSetupRetryRule(ruleString);
-        assertThat(rule.getNetworkCapabilities()).containsExactly(
-                NetworkCapabilities.NET_CAPABILITY_EIMS);
-        assertThat(rule.getMaxRetries()).isEqualTo(10);
-        assertThat(rule.getFailCauses()).isEmpty();
-        assertThat(rule.getRetryIntervalsMillis()).containsExactly(1000L);
-
-        ruleString = "fail_causes=8|27|28|29|30| 32| 33|35 |50|51|111|-5 |-6|65537|65538|-3|2253|"
-                + "2254, maximum_retries=0  ";
-        rule = new DataSetupRetryRule(ruleString);
-        assertThat(rule.getNetworkCapabilities()).isEmpty();
-        assertThat(rule.getMaxRetries()).isEqualTo(0);
-        assertThat(rule.getFailCauses()).containsExactly(8, 27, 28, 29, 30, 32, 33, 35, 50,
-                51, 111, -5, -6, 65537, 65538, -3, 2253, 2254);
-        assertThat(rule.getRetryIntervalsMillis()).isEmpty();
-
-        ruleString = "capabilities=internet|enterprise|dun|ims|fota, retry_interval=2500|  3000|"
-                + "    5000|  10000 | 15000|        20000|40000|60000|  120000|240000  |"
-                + "600000| 1200000|        1800000, maximum_retries=20";
-        rule = new DataSetupRetryRule(ruleString);
-        assertThat(rule.getNetworkCapabilities()).containsExactly(
-                NetworkCapabilities.NET_CAPABILITY_INTERNET,
-                NetworkCapabilities.NET_CAPABILITY_ENTERPRISE,
-                NetworkCapabilities.NET_CAPABILITY_DUN,
-                NetworkCapabilities.NET_CAPABILITY_IMS,
-                NetworkCapabilities.NET_CAPABILITY_FOTA
-        );
-        assertThat(rule.getMaxRetries()).isEqualTo(20);
-        assertThat(rule.getFailCauses()).isEmpty();
-        assertThat(rule.getRetryIntervalsMillis()).containsExactly(2500L, 3000L, 5000L,
-                10000L, 15000L, 20000L, 40000L, 60000L, 120000L, 240000L, 600000L, 1200000L,
-                1800000L).inOrder();
-
-        ruleString = " capabilities = mms   |supl |  cbs, retry_interval =  2000  ";
-        rule = new DataSetupRetryRule(ruleString);
-        assertThat(rule.getNetworkCapabilities()).containsExactly(
-                NetworkCapabilities.NET_CAPABILITY_MMS,
-                NetworkCapabilities.NET_CAPABILITY_SUPL,
-                NetworkCapabilities.NET_CAPABILITY_CBS
-        );
-        assertThat(rule.getMaxRetries()).isEqualTo(10);
-        assertThat(rule.getFailCauses()).isEmpty();
-        assertThat(rule.getRetryIntervalsMillis()).containsExactly(2000L);
-    }
-
-    @Test
-    public void testDataSetupRetryInvalidRulesFromString() {
-        assertThrows(IllegalArgumentException.class,
-                () -> new DataSetupRetryRule("V2hhdCBUaGUgRnVjayBpcyB0aGlzIQ=="));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new DataSetupRetryRule(
-                        " capabilities = mms   |supl |  cbs, retry_interval =  20kkj00  "));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new DataSetupRetryRule(
-                        " capabilities = mms   |supl |  cbs, retry_interval =  -100  "));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new DataSetupRetryRule(
-                        " capabilities = mms   |supl |  cbs, maximum_retries =  -100  "));
-
-        assertThrows(IllegalArgumentException.class,
-                () -> new DataSetupRetryRule(
-                        " retry_interval=100, maximum_retries =  100  "));
-    }
-
-    @Test
-    public void testDataSetupRetryRuleMatchingByFailCause() {
-        String ruleString = "fail_causes=8|27|28|29|30| 32| 33|35 |50|51|111|-5 |-6|65537|65538|-3"
-                + "|2253|2254, maximum_retries=0  ";
-        DataSetupRetryRule rule = new DataSetupRetryRule(ruleString);
-        assertThat(rule.canBeMatched(NetworkCapabilities.NET_CAPABILITY_IMS, 111)).isTrue();
-        assertThat(rule.canBeMatched(NetworkCapabilities.NET_CAPABILITY_MMS, 65537)).isTrue();
-        assertThat(rule.canBeMatched(NetworkCapabilities.NET_CAPABILITY_MMS, 12345))
-                .isFalse();
-    }
-
-    @Test
-    public void testDataSetupRetryRuleMatchingByNetworkCapabilities() {
-        String ruleString = " capabilities = mms   |supl |  cbs, retry_interval =  2000  ";
-        DataSetupRetryRule rule = new DataSetupRetryRule(ruleString);
-
-        assertThat(rule.canBeMatched(NetworkCapabilities.NET_CAPABILITY_MMS, 123456))
-                .isTrue();
-        assertThat(rule.canBeMatched(NetworkCapabilities.NET_CAPABILITY_SUPL, 1345)).isTrue();
-        assertThat(rule.canBeMatched(NetworkCapabilities.NET_CAPABILITY_FOTA, 12345))
-                .isFalse();
-    }
-
-    @Test
-    public void testDataSetupRetryRuleMatchingByBothFailCauseAndNetworkCapabilities() {
-        String ruleString = " capabilities = mms   |supl |  cbs, retry_interval =  2000  ,  "
-                + "fail_causes=8|27|28|29|30| 32| 3";
-        DataSetupRetryRule rule = new DataSetupRetryRule(ruleString);
-        assertThat(rule.canBeMatched(NetworkCapabilities.NET_CAPABILITY_MMS, 3)).isTrue();
-        assertThat(rule.canBeMatched(NetworkCapabilities.NET_CAPABILITY_CBS, 28)).isTrue();
-        assertThat(rule.canBeMatched(NetworkCapabilities.NET_CAPABILITY_SUPL, 4)).isFalse();
-        assertThat(rule.canBeMatched(NetworkCapabilities.NET_CAPABILITY_IMS, 3)).isFalse();
-    }
-
-    @Test
-    public void testDataSetupRetryNetworkSuggestedRetry() {
-        NetworkRequest request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
-        DataNetworkController.NetworkRequestList
-                networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
-        mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile1,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, networkRequestList, 123, 1000);
-        processAllFutureMessages();
-
-        ArgumentCaptor<DataSetupRetryEntry> retryEntryCaptor =
-                ArgumentCaptor.forClass(DataSetupRetryEntry.class);
-        verify(mDataRetryManagerCallbackMock).onDataNetworkSetupRetry(retryEntryCaptor.capture());
-        DataSetupRetryEntry entry = retryEntryCaptor.getValue();
-
-        assertThat(entry.setupRetryType).isEqualTo(DataSetupRetryEntry.RETRY_TYPE_DATA_PROFILE);
-        assertThat(entry.dataProfile).isEqualTo(mDataProfile1);
-        assertThat(entry.retryDelayMillis).isEqualTo(1000);
-        assertThat(entry.networkRequestList).isEqualTo(networkRequestList);
-        assertThat(entry.appliedDataRetryRule).isNull();
-    }
-
-    @Test
-    public void testDataSetupRetryNetworkSuggestedNeverRetry() {
-        NetworkRequest request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
-        DataNetworkController.NetworkRequestList
-                networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
-        mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile3,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, networkRequestList, 123,
-                Long.MAX_VALUE);
-        processAllFutureMessages();
-
-        ArgumentCaptor<List<ThrottleStatus>> throttleStatusCaptor =
-                ArgumentCaptor.forClass(List.class);
-        verify(mDataRetryManagerCallbackMock).onThrottleStatusChanged(
-                throttleStatusCaptor.capture());
-        assertThat(throttleStatusCaptor.getValue()).hasSize(1);
-        ThrottleStatus throttleStatus = throttleStatusCaptor.getValue().get(0);
-        assertThat(throttleStatus.getApnType()).isEqualTo(ApnSetting.TYPE_IMS);
-        assertThat(throttleStatus.getRetryType()).isEqualTo(ThrottleStatus.RETRY_TYPE_NONE);
-        assertThat(throttleStatus.getThrottleExpiryTimeMillis()).isEqualTo(Long.MAX_VALUE);
-        assertThat(throttleStatus.getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        verify(mDataRetryManagerCallbackMock, never())
-                .onDataNetworkSetupRetry(any(DataSetupRetryEntry.class));
-    }
-
-    @Test
-    public void testDataSetupUnthrottling() {
-        testDataSetupRetryNetworkSuggestedNeverRetry();
-        Mockito.clearInvocations(mDataRetryManagerCallbackMock);
-
-        mDataRetryManagerUT.obtainMessage(6/*EVENT_DATA_PROFILE_UNTHROTTLED*/,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, mDataProfile3, null))
-                .sendToTarget();
-        processAllMessages();
-
-        ArgumentCaptor<List<ThrottleStatus>> throttleStatusCaptor =
-                ArgumentCaptor.forClass(List.class);
-        verify(mDataRetryManagerCallbackMock).onThrottleStatusChanged(
-                throttleStatusCaptor.capture());
-        assertThat(throttleStatusCaptor.getValue()).hasSize(1);
-        ThrottleStatus throttleStatus = throttleStatusCaptor.getValue().get(0);
-        assertThat(throttleStatus.getApnType()).isEqualTo(ApnSetting.TYPE_IMS);
-        assertThat(throttleStatus.getRetryType())
-                .isEqualTo(ThrottleStatus.RETRY_TYPE_NEW_CONNECTION);
-        assertThat(throttleStatus.getThrottleExpiryTimeMillis()).isEqualTo(-1);
-        assertThat(throttleStatus.getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-
-        ArgumentCaptor<DataSetupRetryEntry> dataSetupRetryEntryCaptor =
-                ArgumentCaptor.forClass(DataSetupRetryEntry.class);
-        verify(mDataRetryManagerCallbackMock)
-                .onDataNetworkSetupRetry(dataSetupRetryEntryCaptor.capture());
-        DataSetupRetryEntry entry = dataSetupRetryEntryCaptor.getValue();
-        assertThat(entry.dataProfile).isEqualTo(mDataProfile3);
-        assertThat(entry.retryDelayMillis).isEqualTo(0);
-        assertThat(entry.transport).isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-    }
-
-    @Test
-    public void testDataSetupRetryPermanentFailure() {
-        DataSetupRetryRule retryRule = new DataSetupRetryRule(
-                "fail_causes=8|27|28|29|30|32|33|35|50|51|111|-5|-6|65537|65538|-3|2253|"
-                        + "2254, maximum_retries=0");
-        doReturn(Collections.singletonList(retryRule)).when(mDataConfigManager)
-                .getDataSetupRetryRules();
-        mDataRetryManagerUT.obtainMessage(1/*EVENT_DATA_CONFIG_UPDATED*/).sendToTarget();
-        processAllMessages();
-
-
-        NetworkRequest request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
-        DataNetworkController.NetworkRequestList
-                networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
-        mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile1,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, networkRequestList, 2253,
-                DataCallResponse.RETRY_DURATION_UNDEFINED);
-        processAllFutureMessages();
-
-        verify(mDataRetryManagerCallbackMock, never())
-                .onDataNetworkSetupRetry(any(DataSetupRetryEntry.class));
-    }
-
-    @Test
-    public void testDataSetupRetryMaximumRetries() {
-        DataSetupRetryRule retryRule = new DataSetupRetryRule(
-                "capabilities=internet, retry_interval=2000, maximum_retries=2");
-        doReturn(Collections.singletonList(retryRule)).when(mDataConfigManager)
-                .getDataSetupRetryRules();
-        mDataRetryManagerUT.obtainMessage(1/*EVENT_DATA_CONFIG_UPDATED*/).sendToTarget();
-        processAllMessages();
-
-        NetworkRequest request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
-        DataNetworkController.NetworkRequestList
-                networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
-
-        // 1st failed and retry.
-        mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile1,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, networkRequestList, 123,
-                DataCallResponse.RETRY_DURATION_UNDEFINED);
-        processAllFutureMessages();
-
-        ArgumentCaptor<DataSetupRetryEntry> retryEntryCaptor =
-                ArgumentCaptor.forClass(DataSetupRetryEntry.class);
-        verify(mDataRetryManagerCallbackMock).onDataNetworkSetupRetry(retryEntryCaptor.capture());
-        DataSetupRetryEntry entry = retryEntryCaptor.getValue();
-
-        assertThat(entry.setupRetryType)
-                .isEqualTo(DataSetupRetryEntry.RETRY_TYPE_NETWORK_REQUESTS);
-        assertThat(entry.dataProfile).isNull();
-        assertThat(entry.retryDelayMillis).isEqualTo(2000);
-        assertThat(entry.networkRequestList).isEqualTo(networkRequestList);
-        assertThat(entry.appliedDataRetryRule).isEqualTo(retryRule);
-        entry.setState(DataSetupRetryEntry.RETRY_STATE_FAILED);
-        logd("retry entry: (" + entry.hashCode() + ")=" + entry);
-
-        // 2nd failed and retry.
-        Mockito.clearInvocations(mDataRetryManagerCallbackMock);
-        mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile2,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, networkRequestList, 123,
-                DataCallResponse.RETRY_DURATION_UNDEFINED);
-        processAllFutureMessages();
-
-        retryEntryCaptor = ArgumentCaptor.forClass(DataSetupRetryEntry.class);
-        verify(mDataRetryManagerCallbackMock).onDataNetworkSetupRetry(retryEntryCaptor.capture());
-        entry = retryEntryCaptor.getValue();
-
-        assertThat(entry.setupRetryType)
-                .isEqualTo(DataSetupRetryEntry.RETRY_TYPE_NETWORK_REQUESTS);
-        assertThat(entry.dataProfile).isNull();
-        assertThat(entry.retryDelayMillis).isEqualTo(2000);
-        assertThat(entry.networkRequestList).isEqualTo(networkRequestList);
-        assertThat(entry.appliedDataRetryRule).isEqualTo(retryRule);
-        entry.setState(DataSetupRetryEntry.RETRY_STATE_FAILED);
-        logd("retry entry: (" + entry.hashCode() + ")=" + entry);
-
-        // 3rd failed and never retry.
-        Mockito.clearInvocations(mDataRetryManagerCallbackMock);
-        mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile1,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, networkRequestList, 123,
-                DataCallResponse.RETRY_DURATION_UNDEFINED);
-        processAllFutureMessages();
-
-        // Verify there is no retry.
-        verify(mDataRetryManagerCallbackMock, never())
-                .onDataNetworkSetupRetry(any(DataSetupRetryEntry.class));
-    }
-
-    @Test
-    public void testDataSetupRetryMaximumRetriesReset() {
-        DataSetupRetryRule retryRule1 = new DataSetupRetryRule(
-                "capabilities=eims, retry_interval=1000, maximum_retries=20");
-        DataSetupRetryRule retryRule2 = new DataSetupRetryRule(
-                "capabilities=ims|mms|fota, retry_interval=3000, maximum_retries=1");
-        doReturn(List.of(retryRule1, retryRule2)).when(mDataConfigManager).getDataSetupRetryRules();
-        mDataRetryManagerUT.obtainMessage(1/*EVENT_DATA_CONFIG_UPDATED*/).sendToTarget();
-        processAllMessages();
-
-        NetworkRequest request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
-        DataNetworkController.NetworkRequestList
-                networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
-
-        // 1st failed and retry.
-        mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile3,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, networkRequestList, 123,
-                DataCallResponse.RETRY_DURATION_UNDEFINED);
-        processAllFutureMessages();
-
-        ArgumentCaptor<DataSetupRetryEntry> retryEntryCaptor =
-                ArgumentCaptor.forClass(DataSetupRetryEntry.class);
-        verify(mDataRetryManagerCallbackMock).onDataNetworkSetupRetry(retryEntryCaptor.capture());
-        DataSetupRetryEntry entry = retryEntryCaptor.getValue();
-
-        assertThat(entry.setupRetryType)
-                .isEqualTo(DataSetupRetryEntry.RETRY_TYPE_NETWORK_REQUESTS);
-        assertThat(entry.dataProfile).isNull();
-        assertThat(entry.retryDelayMillis).isEqualTo(3000L);
-        assertThat(entry.networkRequestList).isEqualTo(networkRequestList);
-        assertThat(entry.appliedDataRetryRule).isEqualTo(retryRule2);
-
-        // Succeeded. This should clear the retry count.
-        entry.setState(DataSetupRetryEntry.RETRY_STATE_SUCCEEDED);
-
-        // Failed again. Retry should happen.
-        Mockito.clearInvocations(mDataRetryManagerCallbackMock);
-        mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile3,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, networkRequestList, 123,
-                DataCallResponse.RETRY_DURATION_UNDEFINED);
-        processAllFutureMessages();
-
-        retryEntryCaptor = ArgumentCaptor.forClass(DataSetupRetryEntry.class);
-        verify(mDataRetryManagerCallbackMock).onDataNetworkSetupRetry(retryEntryCaptor.capture());
-        entry = retryEntryCaptor.getValue();
-
-        assertThat(entry.setupRetryType)
-                .isEqualTo(DataSetupRetryEntry.RETRY_TYPE_NETWORK_REQUESTS);
-        assertThat(entry.dataProfile).isNull();
-        assertThat(entry.retryDelayMillis).isEqualTo(3000L);
-        assertThat(entry.networkRequestList).isEqualTo(networkRequestList);
-        assertThat(entry.appliedDataRetryRule).isEqualTo(retryRule2);
-    }
-
-    @Test
-    public void testDataSetupRetryBackOffTimer() {
-        DataSetupRetryRule retryRule1 = new DataSetupRetryRule(
-                "capabilities=eims, retry_interval=1000, maximum_retries=20");
-        DataSetupRetryRule retryRule2 = new DataSetupRetryRule(
-                "capabilities=internet|mms|fota, retry_interval=3000, maximum_retries=1");
-        DataSetupRetryRule retryRule3 = new DataSetupRetryRule(
-                "capabilities=ims, retry_interval=2000|4000|8000, "
-                        + "maximum_retries=4");
-        doReturn(List.of(retryRule1, retryRule2, retryRule3)).when(mDataConfigManager)
-                .getDataSetupRetryRules();
-
-        mDataRetryManagerUT.obtainMessage(1/*EVET_DATA_CONFIG_UPDATED*/).sendToTarget();
-        processAllMessages();
-
-        NetworkRequest request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
-        DataNetworkController.NetworkRequestList
-                networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
-
-        // 1st/2nd/3rd/4th failed and retry.
-        for (long delay : List.of(2000, 4000, 8000, 8000)) {
-            Mockito.clearInvocations(mDataRetryManagerCallbackMock);
-            mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile3,
-                    AccessNetworkConstants.TRANSPORT_TYPE_WWAN, networkRequestList, 123,
-                    DataCallResponse.RETRY_DURATION_UNDEFINED);
-            processAllFutureMessages();
-
-            ArgumentCaptor<DataSetupRetryEntry> retryEntryCaptor =
-                    ArgumentCaptor.forClass(DataSetupRetryEntry.class);
-            verify(mDataRetryManagerCallbackMock)
-                    .onDataNetworkSetupRetry(retryEntryCaptor.capture());
-            DataSetupRetryEntry entry = retryEntryCaptor.getValue();
-
-            assertThat(entry.setupRetryType)
-                    .isEqualTo(DataSetupRetryEntry.RETRY_TYPE_NETWORK_REQUESTS);
-            assertThat(entry.dataProfile).isNull();
-            assertThat(entry.retryDelayMillis).isEqualTo(delay);
-            assertThat(entry.networkRequestList).isEqualTo(networkRequestList);
-            assertThat(entry.appliedDataRetryRule).isEqualTo(retryRule3);
-
-            entry.setState(DataRetryManager.DataRetryEntry.RETRY_STATE_FAILED);
-        }
-
-        // The last fail should not trigger any retry.
-        Mockito.clearInvocations(mDataRetryManagerCallbackMock);
-        mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile3,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, networkRequestList, 123,
-                DataCallResponse.RETRY_DURATION_UNDEFINED);
-        processAllFutureMessages();
-
-        // Verify there is no retry.
-        verify(mDataRetryManagerCallbackMock, never())
-                .onDataNetworkSetupRetry(any(DataSetupRetryEntry.class));
-    }
-
-    @Test
-    public void testDataHandoverRetryRulesParsingFromString() {
-        String ruleString = "fail_causes=8|27|28|29|30| 32| 33|35 |50|51|111|-5 |-6|65537|65538|-3"
-                + "|2253|2254, maximum_retries=0  ";
-        DataHandoverRetryRule rule = new DataHandoverRetryRule(ruleString);
-        assertThat(rule.getMaxRetries()).isEqualTo(0);
-        assertThat(rule.getFailCauses()).containsExactly(8, 27, 28, 29, 30, 32, 33, 35, 50,
-                51, 111, -5, -6, 65537, 65538, -3, 2253, 2254);
-        assertThat(rule.getRetryIntervalsMillis()).isEmpty();
-
-        ruleString = "retry_interval=1000|2000|4000|8000|16000, maximum_retries=5";
-        rule = new DataHandoverRetryRule(ruleString);
-        assertThat(rule.getMaxRetries()).isEqualTo(5);
-        assertThat(rule.getFailCauses()).isEmpty();
-        assertThat(rule.getRetryIntervalsMillis()).containsExactly(1000L, 2000L, 4000L, 8000L,
-                16000L).inOrder();
-
-        ruleString = "retry_interval=1000|2000, maximum_retries=10";
-        rule = new DataHandoverRetryRule(ruleString);
-        assertThat(rule.getMaxRetries()).isEqualTo(10);
-        assertThat(rule.getFailCauses()).isEmpty();
-        assertThat(rule.getRetryIntervalsMillis()).containsExactly(1000L, 2000L).inOrder();
-
-        ruleString = "retry_interval=1000";
-        rule = new DataHandoverRetryRule(ruleString);
-        assertThat(rule.getMaxRetries()).isEqualTo(10);
-        assertThat(rule.getFailCauses()).isEmpty();
-        assertThat(rule.getRetryIntervalsMillis()).containsExactly(1000L);
-
-        ruleString = "maximum_retries=5";
-        rule = new DataHandoverRetryRule(ruleString);
-        assertThat(rule.getMaxRetries()).isEqualTo(5);
-        assertThat(rule.getFailCauses()).isEmpty();
-        assertThat(rule.getRetryIntervalsMillis()).containsExactly(5000L);
-    }
-
-    @Test
-    public void testDataHandoverRetryInvalidRulesFromString() {
-        assertThrows(IllegalArgumentException.class,
-                () -> new DataHandoverRetryRule("V2hhdCBUaGUgRnVjayBpcyB0aGlzIQ=="));
-    }
-
-    @Test
-    public void testIsSimilarNetworkRequestRetryScheduled() {
-        DataSetupRetryRule retryRule = new DataSetupRetryRule(
-                "capabilities=internet, retry_interval=2000, maximum_retries=2");
-        doReturn(Collections.singletonList(retryRule)).when(mDataConfigManager)
-                .getDataSetupRetryRules();
-        mDataRetryManagerUT.obtainMessage(1/*EVENT_DATA_CONFIG_UPDATED*/).sendToTarget();
-        processAllMessages();
-
-        NetworkRequest request = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build();
-        TelephonyNetworkRequest tnr = new TelephonyNetworkRequest(request, mPhone);
-        DataNetworkController.NetworkRequestList
-                networkRequestList = new DataNetworkController.NetworkRequestList(tnr);
-
-        // failed and retry.
-        mDataRetryManagerUT.evaluateDataSetupRetry(mDataProfile1,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN, networkRequestList, 123,
-                DataCallResponse.RETRY_DURATION_UNDEFINED);
-        processAllFutureMessages();
-
-        tnr = new TelephonyNetworkRequest(new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
-                .build(), mPhone);
-        assertThat(mDataRetryManagerUT.isSimilarNetworkRequestRetryScheduled(tnr,
-                AccessNetworkConstants.TRANSPORT_TYPE_WWAN)).isTrue();
-        assertThat(mDataRetryManagerUT.isSimilarNetworkRequestRetryScheduled(tnr,
-                AccessNetworkConstants.TRANSPORT_TYPE_WLAN)).isFalse();
-    }
-
-    @Test
-    public void testRilCrashedReset() {
-        testDataSetupRetryNetworkSuggestedNeverRetry();
-        Mockito.clearInvocations(mDataRetryManagerCallbackMock);
-
-        // RIL crashed and came back online.
-        mDataRetryManagerUT.obtainMessage(8/*EVENT_RADIO_ON*/,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, mDataProfile3, null))
-                .sendToTarget();
-        processAllMessages();
-
-        ArgumentCaptor<List<ThrottleStatus>> throttleStatusCaptor =
-                ArgumentCaptor.forClass(List.class);
-        verify(mDataRetryManagerCallbackMock).onThrottleStatusChanged(
-                throttleStatusCaptor.capture());
-        assertThat(throttleStatusCaptor.getValue()).hasSize(1);
-        ThrottleStatus throttleStatus = throttleStatusCaptor.getValue().get(0);
-        assertThat(throttleStatus.getApnType()).isEqualTo(ApnSetting.TYPE_IMS);
-        assertThat(throttleStatus.getRetryType())
-                .isEqualTo(ThrottleStatus.RETRY_TYPE_NEW_CONNECTION);
-        assertThat(throttleStatus.getThrottleExpiryTimeMillis()).isEqualTo(-1);
-        assertThat(throttleStatus.getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-    }
-
-    @Test
-    public void testModemCrashedReset() {
-        testDataSetupRetryNetworkSuggestedNeverRetry();
-        Mockito.clearInvocations(mDataRetryManagerCallbackMock);
-
-        // RIL crashed and came back online.
-        mDataRetryManagerUT.obtainMessage(10 /*EVENT_TAC_CHANGED*/,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, mDataProfile3, null))
-                .sendToTarget();
-        processAllMessages();
-
-        ArgumentCaptor<List<ThrottleStatus>> throttleStatusCaptor =
-                ArgumentCaptor.forClass(List.class);
-        verify(mDataRetryManagerCallbackMock).onThrottleStatusChanged(
-                throttleStatusCaptor.capture());
-        assertThat(throttleStatusCaptor.getValue()).hasSize(1);
-        ThrottleStatus throttleStatus = throttleStatusCaptor.getValue().get(0);
-        assertThat(throttleStatus.getApnType()).isEqualTo(ApnSetting.TYPE_IMS);
-        assertThat(throttleStatus.getRetryType())
-                .isEqualTo(ThrottleStatus.RETRY_TYPE_NEW_CONNECTION);
-        assertThat(throttleStatus.getThrottleExpiryTimeMillis()).isEqualTo(-1);
-        assertThat(throttleStatus.getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-    }
-
-    @Test
-    public void testTacChangedReset() {
-        doReturn(true).when(mDataConfigManager).shouldResetDataThrottlingWhenTacChanges();
-
-        testDataSetupRetryNetworkSuggestedNeverRetry();
-        Mockito.clearInvocations(mDataRetryManagerCallbackMock);
-
-        // RIL crashed and came back online.
-        mDataRetryManagerUT.obtainMessage(9/*EVENT_MODEM_RESET*/,
-                new AsyncResult(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, mDataProfile3, null))
-                .sendToTarget();
-        processAllMessages();
-
-        ArgumentCaptor<List<ThrottleStatus>> throttleStatusCaptor =
-                ArgumentCaptor.forClass(List.class);
-        verify(mDataRetryManagerCallbackMock).onThrottleStatusChanged(
-                throttleStatusCaptor.capture());
-        assertThat(throttleStatusCaptor.getValue()).hasSize(1);
-        ThrottleStatus throttleStatus = throttleStatusCaptor.getValue().get(0);
-        assertThat(throttleStatus.getApnType()).isEqualTo(ApnSetting.TYPE_IMS);
-        assertThat(throttleStatus.getRetryType())
-                .isEqualTo(ThrottleStatus.RETRY_TYPE_NEW_CONNECTION);
-        assertThat(throttleStatus.getThrottleExpiryTimeMillis()).isEqualTo(-1);
-        assertThat(throttleStatus.getTransportType())
-                .isEqualTo(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java
deleted file mode 100644
index de0998d..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.net.NetworkAgent;
-import android.telephony.Annotation.ValidationStatus;
-import android.telephony.CarrierConfigManager;
-import android.telephony.data.DataProfile;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback;
-import com.android.internal.telephony.data.DataStallRecoveryManager.DataStallRecoveryManagerCallback;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-
-import java.util.ArrayList;
-import java.util.List;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class DataStallRecoveryManagerTest extends TelephonyTest {
-    // Mocked classes
-    private DataStallRecoveryManagerCallback mDataStallRecoveryManagerCallback;
-
-    private DataStallRecoveryManager mDataStallRecoveryManager;
-
-    @Before
-    public void setUp() throws Exception {
-        logd("DataStallRecoveryManagerTest +Setup!");
-        super.setUp(getClass().getSimpleName());
-        mDataStallRecoveryManagerCallback = mock(DataStallRecoveryManagerCallback.class);
-        mCarrierConfigManager = mPhone.getContext().getSystemService(CarrierConfigManager.class);
-        long[] dataStallRecoveryTimersArray = new long[] {100, 100, 100, 100};
-        boolean[] dataStallRecoveryStepsArray = new boolean[] {false, false, true, false, false};
-        doReturn(dataStallRecoveryTimersArray)
-                .when(mDataConfigManager)
-                .getDataStallRecoveryDelayMillis();
-        doReturn(dataStallRecoveryStepsArray)
-                .when(mDataConfigManager)
-                .getDataStallRecoveryShouldSkipArray();
-        doReturn(true).when(mDataNetworkController).isInternetDataAllowed();
-
-        doAnswer(
-                invocation -> {
-                    ((Runnable) invocation.getArguments()[0]).run();
-                    return null;
-                })
-                .when(mDataStallRecoveryManagerCallback)
-                .invokeFromExecutor(any(Runnable.class));
-        doReturn("").when(mSubscriptionController).getDataEnabledOverrideRules(anyInt());
-
-        mDataStallRecoveryManager =
-                new DataStallRecoveryManager(
-                        mPhone,
-                        mDataNetworkController,
-                        mMockedWwanDataServiceManager,
-                        mTestableLooper.getLooper(),
-                        mDataStallRecoveryManagerCallback);
-        logd("DataStallRecoveryManagerTest -Setup!");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mDataStallRecoveryManager = null;
-        super.tearDown();
-    }
-
-    private void sendValidationStatusCallback(@ValidationStatus int status) {
-        ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor =
-                ArgumentCaptor.forClass(DataNetworkControllerCallback.class);
-        verify(mDataNetworkController)
-                .registerDataNetworkControllerCallback(
-                        dataNetworkControllerCallbackCaptor.capture());
-        DataNetworkControllerCallback dataNetworkControllerCallback =
-                dataNetworkControllerCallbackCaptor.getValue();
-        dataNetworkControllerCallback.onInternetDataNetworkValidationStatusChanged(status);
-    }
-
-    private void sendOnInternetDataNetworkCallback(boolean isConnected) {
-        ArgumentCaptor<DataNetworkControllerCallback> dataNetworkControllerCallbackCaptor =
-                ArgumentCaptor.forClass(DataNetworkControllerCallback.class);
-        verify(mDataNetworkController)
-                .registerDataNetworkControllerCallback(
-                        dataNetworkControllerCallbackCaptor.capture());
-        DataNetworkControllerCallback dataNetworkControllerCallback =
-                dataNetworkControllerCallbackCaptor.getValue();
-
-        if (isConnected) {
-            List<DataProfile> dataprofile = new ArrayList<DataProfile>();
-            dataNetworkControllerCallback.onInternetDataNetworkConnected(dataprofile);
-        } else {
-            dataNetworkControllerCallback.onInternetDataNetworkDisconnected();
-        }
-        processAllMessages();
-    }
-
-    @Test
-    public void testRecoveryStepPDPReset() throws Exception {
-        sendOnInternetDataNetworkCallback(true);
-        mDataStallRecoveryManager.setRecoveryAction(1);
-        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
-        doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
-
-        logd("Sending validation failed callback");
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllFutureMessages();
-
-        verify(mDataStallRecoveryManagerCallback).onDataStallReestablishInternet();
-    }
-
-    @Test
-    public void testRecoveryStepRestartRadio() throws Exception {
-        sendOnInternetDataNetworkCallback(true);
-        mDataStallRecoveryManager.setRecoveryAction(3);
-        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
-        doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
-
-        logd("Sending validation failed callback");
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllFutureMessages();
-
-        verify(mSST, times(1)).powerOffRadioSafely();
-    }
-
-    @Test
-    public void testRecoveryStepModemReset() throws Exception {
-        sendOnInternetDataNetworkCallback(true);
-        mDataStallRecoveryManager.setRecoveryAction(4);
-        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
-        doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
-
-        logd("Sending validation failed callback");
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-
-        processAllFutureMessages();
-
-        verify(mPhone, times(1)).rebootModem(any());
-    }
-
-    @Test
-    public void testDoNotDoRecoveryActionWhenPoorSignal() throws Exception {
-        sendOnInternetDataNetworkCallback(true);
-        mDataStallRecoveryManager.setRecoveryAction(3);
-        doReturn(1).when(mSignalStrength).getLevel();
-        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
-        doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
-
-        logd("Sending validation failed callback");
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-
-        processAllFutureMessages();
-
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3);
-    }
-
-    @Test
-    public void testDoNotDoRecoveryActionWhenDialCall() throws Exception {
-        sendOnInternetDataNetworkCallback(true);
-        mDataStallRecoveryManager.setRecoveryAction(3);
-        doReturn(3).when(mSignalStrength).getLevel();
-        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
-        doReturn(PhoneConstants.State.OFFHOOK).when(mPhone).getState();
-
-        logd("Sending validation failed callback");
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-
-        processAllFutureMessages();
-
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3);
-    }
-
-    @Test
-    public void testDoNotDoRecoveryBySendMessageDelayedWhenDialCall() throws Exception {
-        sendOnInternetDataNetworkCallback(true);
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
-        mDataStallRecoveryManager.setRecoveryAction(0);
-        doReturn(PhoneConstants.State.OFFHOOK).when(mPhone).getState();
-        doReturn(3).when(mSignalStrength).getLevel();
-        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
-        logd("Sending validation failed callback");
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllMessages();
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1);
-        mDataStallRecoveryManager.sendMessageDelayed(
-                mDataStallRecoveryManager.obtainMessage(3), 1000);
-        moveTimeForward(15000);
-        processAllMessages();
-
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3);
-    }
-
-    @Test
-    public void testDoNotContinueRecoveryActionAfterModemReset() throws Exception {
-        sendOnInternetDataNetworkCallback(true);
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
-        mDataStallRecoveryManager.setRecoveryAction(0);
-        doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
-        doReturn(3).when(mSignalStrength).getLevel();
-        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
-        logd("Sending validation failed callback");
-
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllMessages();
-        moveTimeForward(101);
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1);
-
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllMessages();
-        moveTimeForward(101);
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3);
-
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllMessages();
-        moveTimeForward(101);
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(4);
-
-        // Handle multiple VALIDATION_STATUS_NOT_VALID and make sure we don't attempt recovery
-        for (int i = 0; i < 4; i++) {
-            sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-            logd("Sending validation failed callback");
-            processAllMessages();
-            moveTimeForward(101);
-            assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
-        }
-    }
-
-    @Test
-    public void testDoRecoveryWhenMeetDataStallAgain() throws Exception {
-        sendOnInternetDataNetworkCallback(true);
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_VALID);
-        mDataStallRecoveryManager.setRecoveryAction(0);
-        doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
-        doReturn(3).when(mSignalStrength).getLevel();
-        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
-        logd("Sending validation failed callback");
-
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllMessages();
-        moveTimeForward(101);
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1);
-
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllMessages();
-        moveTimeForward(101);
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(3);
-
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllMessages();
-        moveTimeForward(101);
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(4);
-
-        // Handle multiple VALIDATION_STATUS_NOT_VALID and make sure we don't attempt recovery
-        for (int i = 0; i < 4; i++) {
-            sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-            logd("Sending validation failed callback");
-            processAllMessages();
-            moveTimeForward(101);
-            assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
-        }
-
-        moveTimeForward(101);
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
-
-        mDataStallRecoveryManager.sendMessageDelayed(
-                mDataStallRecoveryManager.obtainMessage(0), 1000);
-        processAllMessages();
-        processAllMessages();
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
-    }
-
-    @Test
-    public void testDoNotDoRecoveryWhenDataNoService() throws Exception {
-        sendOnInternetDataNetworkCallback(true);
-        mDataStallRecoveryManager.setRecoveryAction(1);
-        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
-        doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
-        doReturn(false).when(mDataNetworkController).isInternetDataAllowed();
-
-        logd("Sending validation failed callback");
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllFutureMessages();
-
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1);
-    }
-
-    @Test
-    public void testDoNotDoRecoveryWhenDataNetworkNotConnected() throws Exception {
-        sendOnInternetDataNetworkCallback(true);
-        mDataStallRecoveryManager.setRecoveryAction(1);
-        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
-        doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
-        sendOnInternetDataNetworkCallback(false);
-
-        logd("Sending validation failed callback");
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllFutureMessages();
-
-        assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(1);
-    }
-
-    @Test
-    public void testDoNotDoRecoveryIfNoValidationPassedYet() throws Exception {
-        sendOnInternetDataNetworkCallback(false);
-        doReturn(mSignalStrength).when(mPhone).getSignalStrength();
-        doReturn(PhoneConstants.State.IDLE).when(mPhone).getState();
-
-        logd("Sending validation failed callback");
-        sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-        processAllFutureMessages();
-
-        // Handle multiple VALIDATION_STATUS_NOT_VALID and make sure we don't attempt recovery
-        for (int i = 0; i < 4; i++) {
-            sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID);
-            logd("Sending validation failed callback");
-            processAllMessages();
-            moveTimeForward(101);
-            assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0);
-        }
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataUtilsTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/DataUtilsTest.java
deleted file mode 100644
index 0be85c5..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataUtilsTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.data.DataNetworkController.NetworkRequestList;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import java.util.List;
-
-public class DataUtilsTest extends TelephonyTest {
-
-    @Before
-    public void setUp() throws Exception {
-        logd("DataUtilsTest +Setup!");
-        super.setUp(getClass().getSimpleName());
-        logd("DataUtilsTest -Setup!");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    @Test
-    public void testGetGroupedNetworkRequestList() {
-        NetworkRequestList requestList = new NetworkRequestList();
-
-        int[] netCaps = new int[]{
-                NetworkCapabilities.NET_CAPABILITY_INTERNET,
-                NetworkCapabilities.NET_CAPABILITY_INTERNET,
-                NetworkCapabilities.NET_CAPABILITY_MMS,
-                NetworkCapabilities.NET_CAPABILITY_MMS,
-                NetworkCapabilities.NET_CAPABILITY_EIMS
-        };
-
-        int requestId = 0;
-        TelephonyNetworkRequest networkRequest;
-        for (int netCap : netCaps) {
-            networkRequest = new TelephonyNetworkRequest(new NetworkRequest(
-                    new NetworkCapabilities.Builder()
-                            .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-                            .addCapability(netCap).build(), -1, requestId++,
-                    NetworkRequest.Type.REQUEST), mPhone);
-            requestList.add(networkRequest);
-        }
-
-        assertThat(requestList).hasSize(5);
-
-        List<NetworkRequestList> requestListList =
-                DataUtils.getGroupedNetworkRequestList(requestList);
-
-        assertThat(requestListList).hasSize(3);
-        requestList = requestListList.get(0);
-        assertThat(requestList).hasSize(1);
-        assertThat(requestList.get(0).hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_EIMS)).isTrue();
-
-        requestList = requestListList.get(1);
-        assertThat(requestList).hasSize(2);
-        assertThat(requestList.get(0).hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_MMS)).isTrue();
-        assertThat(requestList.get(1).hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_MMS)).isTrue();
-
-        requestList = requestListList.get(2);
-        assertThat(requestList).hasSize(2);
-        assertThat(requestList.get(0).hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
-        assertThat(requestList.get(1).hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_INTERNET)).isTrue();
-    }
-
-    @Test
-    public void testGetNetworkCapabilitiesFromString() {
-        String normal = " MMS  ";
-        assertThat(DataUtils.getNetworkCapabilitiesFromString(normal)).containsExactly(
-                NetworkCapabilities.NET_CAPABILITY_MMS);
-        String normal2 = "MMS|IMS";
-        assertThat(DataUtils.getNetworkCapabilitiesFromString(normal2)).containsExactly(
-                NetworkCapabilities.NET_CAPABILITY_MMS, NetworkCapabilities.NET_CAPABILITY_IMS);
-        String normal3 = " MMS |IMS ";
-        assertThat(DataUtils.getNetworkCapabilitiesFromString(normal3)).containsExactly(
-                NetworkCapabilities.NET_CAPABILITY_MMS, NetworkCapabilities.NET_CAPABILITY_IMS);
-
-        String containsUnknown = "MMS |IMS | what";
-        assertThat(DataUtils.getNetworkCapabilitiesFromString(containsUnknown)
-                .contains(-1)).isTrue();
-
-        String malFormatted = "";
-        assertThat(DataUtils.getNetworkCapabilitiesFromString(malFormatted).contains(-1)).isTrue();
-        String malFormatted2 = " ";
-        assertThat(DataUtils.getNetworkCapabilitiesFromString(malFormatted2).contains(-1)).isTrue();
-        String malFormatted3 = "MMS |IMS |";
-        assertThat(DataUtils.getNetworkCapabilitiesFromString(malFormatted3).contains(-1)).isTrue();
-        String composedDelim = " | ||";
-        assertThat(DataUtils.getNetworkCapabilitiesFromString(composedDelim).contains(-1)).isTrue();
-        String malFormatted4 = "mms||ims";
-        assertThat(DataUtils.getNetworkCapabilitiesFromString(malFormatted4).contains(-1)).isTrue();
-    }
-
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/KeepAliveTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/KeepAliveTrackerTest.java
deleted file mode 100644
index ceb08bf..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/KeepAliveTrackerTest.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.net.InetAddresses;
-import android.net.KeepalivePacketData;
-import android.net.NattKeepalivePacketData;
-import android.net.NetworkAgent;
-import android.os.AsyncResult;
-import android.os.Looper;
-import android.os.Message;
-import android.telephony.AccessNetworkConstants;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.data.TelephonyNetworkAgent.TelephonyNetworkAgentCallback;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-
-import java.time.Duration;
-import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class KeepAliveTrackerTest extends TelephonyTest {
-
-    private KeepaliveTracker mKeepaliveTrackerUT;
-
-    // Mocked classes
-    private DataNetwork mMockedDataNetwork;
-    private TelephonyNetworkAgent mMockedTelephonyNetworkAgent;
-
-    private TelephonyNetworkAgentCallback mTelephonyNetworkAgentCallback;
-
-    @Before
-    public void setUp() throws Exception {
-        logd("KeepAliveTrackerTest +Setup!");
-        super.setUp(getClass().getSimpleName());
-        mMockedDataNetwork = mock(DataNetwork.class);
-        mMockedTelephonyNetworkAgent = mock(TelephonyNetworkAgent.class);
-        replaceInstance(NetworkAgent.class, "mPreConnectedQueue",
-                mMockedTelephonyNetworkAgent, new ArrayList<>());
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                .when(mMockedDataNetwork).getTransport();
-        mKeepaliveTrackerUT = new KeepaliveTracker(mPhone, Looper.myLooper(), mMockedDataNetwork,
-                mMockedTelephonyNetworkAgent);
-        ArgumentCaptor<TelephonyNetworkAgentCallback> callbackCaptor =
-                ArgumentCaptor.forClass(TelephonyNetworkAgentCallback.class);
-        verify(mMockedTelephonyNetworkAgent).registerCallback(callbackCaptor.capture());
-        mTelephonyNetworkAgentCallback = callbackCaptor.getValue();
-        logd("KeepAliveTrackerTest -Setup!");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mKeepaliveTrackerUT = null;
-        mTelephonyNetworkAgentCallback = null;
-        super.tearDown();
-    }
-
-    private void checkStartStopNattKeepalive(boolean useCondensedFlow) throws Exception {
-        final int sessionHandle = 0xF00;
-        final int slotId = 3;
-        final int interval = 10; // seconds
-        // Construct a new KeepalivePacketData request as we would receive from a Network Agent,
-        // and check that the packet is sent to the RIL.
-        KeepalivePacketData kd = NattKeepalivePacketData.nattKeepalivePacket(
-                InetAddresses.parseNumericAddress("1.2.3.4"),
-                1234,
-                InetAddresses.parseNumericAddress("8.8.8.8"),
-                4500);
-        mTelephonyNetworkAgentCallback.onStartSocketKeepalive(slotId, Duration.ofSeconds(interval),
-                kd);
-        processAllMessages();
-        verify(mSimulatedCommandsVerifier, times(1))
-                .startNattKeepalive(anyInt(), eq(kd), eq((int) TimeUnit.SECONDS.toMillis(interval)),
-                        any(Message.class));
-
-        Message kaStarted = mKeepaliveTrackerUT.obtainMessage(1 /*EVENT_KEEPALIVE_STARTED*/,
-                slotId, 0);
-        processAllMessages();
-        if (useCondensedFlow) {
-            // Send a singled condensed response that a keepalive have been requested and the
-            // activation is completed. This flow should be used if the keepalive offload request
-            // is handled by a high-priority signalling path.
-            AsyncResult.forMessage(
-                    kaStarted, new KeepaliveStatus(
-                            sessionHandle, KeepaliveStatus.STATUS_ACTIVE), null);
-            kaStarted.sendToTarget();
-        } else {
-            // Send the sequential responses indicating first that the request was received and
-            // then that the keepalive is running. This should create an active record of the
-            // keepalive in keepalive tracker while permitting the status from a low priority or
-            // other high-latency handler to activate the keepalive without blocking a request.
-            AsyncResult.forMessage(
-                    kaStarted, new KeepaliveStatus(
-                            sessionHandle, KeepaliveStatus.STATUS_PENDING), null);
-            kaStarted.sendToTarget();
-            Message kaRunning = mKeepaliveTrackerUT.obtainMessage(3 /*EVENT_KEEPALIVE_STATUS*/);
-            AsyncResult.forMessage(
-                    kaRunning, new KeepaliveStatus(
-                            sessionHandle, KeepaliveStatus.STATUS_ACTIVE), null);
-            kaRunning.sendToTarget();
-        }
-        processAllMessages();
-
-        // Verify that we can stop the connection, which checks that the record in keepalive tracker
-        // has a valid mapping between slotId (from network agent) to sessionHandle (from Radio).
-        mTelephonyNetworkAgentCallback.onStopSocketKeepalive(slotId);
-        processAllMessages();
-        verify(mSimulatedCommandsVerifier, times(1))
-                .stopNattKeepalive(eq(sessionHandle), any(Message.class));
-
-        Message kaStopped = mKeepaliveTrackerUT.obtainMessage(2 /*EVENT_KEEPALIVE_STOPPED*/,
-                sessionHandle, slotId);
-        AsyncResult.forMessage(kaStopped);
-        kaStopped.sendToTarget();
-        processAllMessages();
-        // Verify that after the connection is stopped, the mapping for a Keepalive Session is
-        // removed. Thus, subsequent calls to stop the same keepalive are ignored.
-        mTelephonyNetworkAgentCallback.onStopSocketKeepalive(slotId);
-        processAllMessages();
-        // Check that the mock has not been called subsequent to the previous invocation
-        // while avoiding the use of reset()
-        verify(mSimulatedCommandsVerifier, times(1))
-                .stopNattKeepalive(anyInt(), any(Message.class));
-    }
-
-    @Test
-    public void testStartStopNattKeepalive() throws Exception {
-        checkStartStopNattKeepalive(false);
-    }
-
-    @Test
-    public void testStartStopNattKeepaliveCondensed() throws Exception {
-        checkStartStopNattKeepalive(true);
-    }
-
-    private void checkStartNattKeepaliveFail(boolean useCondensedFlow) throws Exception {
-        final int sessionHandle = 0xF00;
-        final int slotId = 3;
-        final int interval = 10; // seconds
-        // Construct a new KeepalivePacketData request as we would receive from a Network Agent,
-        // and check that the packet is sent to the RIL.
-        KeepalivePacketData kd = NattKeepalivePacketData.nattKeepalivePacket(
-                InetAddresses.parseNumericAddress("1.2.3.4"),
-                1234,
-                InetAddresses.parseNumericAddress("8.8.8.8"),
-                4500);
-        mTelephonyNetworkAgentCallback.onStartSocketKeepalive(slotId, Duration.ofSeconds(interval),
-                kd);
-        processAllMessages();
-        verify(mSimulatedCommandsVerifier, times(1))
-                .startNattKeepalive(anyInt(), eq(kd), eq(interval * 1000), any(Message.class));
-
-        Message kaStarted = mKeepaliveTrackerUT.obtainMessage(1 /*EVENT_KEEPALIVE_STARTED*/,
-                slotId, 0);
-        processAllMessages();
-        if (useCondensedFlow) {
-            // Indicate in the response that the keepalive has failed.
-            AsyncResult.forMessage(
-                    kaStarted, new KeepaliveStatus(KeepaliveStatus.ERROR_UNSUPPORTED),
-                    null);
-            kaStarted.sendToTarget();
-        } else {
-            // Indicate that the keepalive is queued, and then signal a failure from the modem
-            // such that a pending keepalive fails to activate.
-            AsyncResult.forMessage(
-                    kaStarted, new KeepaliveStatus(
-                            sessionHandle, KeepaliveStatus.STATUS_PENDING), null);
-            kaStarted.sendToTarget();
-            Message kaRunning = mKeepaliveTrackerUT.obtainMessage(3 /*EVENT_KEEPALIVE_STATUS*/);
-            AsyncResult.forMessage(
-                    kaRunning, new KeepaliveStatus(
-                            sessionHandle, KeepaliveStatus.STATUS_INACTIVE), null);
-            kaRunning.sendToTarget();
-        }
-        processAllMessages();
-        // Verify that a failed connection request cannot be stopped due to no record in
-        // the keepalive tracker.
-        mTelephonyNetworkAgentCallback.onStopSocketKeepalive(slotId);
-        processAllMessages();
-        verify(mSimulatedCommandsVerifier, never()).stopNattKeepalive(anyInt(), any(Message.class));
-    }
-
-    @Test
-    public void testStartNattKeepaliveFail() throws Exception {
-        checkStartNattKeepaliveFail(false);
-    }
-
-    @Test
-    public void testStartNattKeepaliveFailCondensed() throws Exception {
-        checkStartNattKeepaliveFail(true);
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/QosBearerSessionTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/QosBearerSessionTest.java
deleted file mode 100644
index 91affcd..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/QosBearerSessionTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import static com.android.internal.telephony.data.QosCallbackTrackerTest.createEpsQos;
-import static com.android.internal.telephony.data.QosCallbackTrackerTest.createIpv4QosFilter;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Parcel;
-import android.telephony.data.QosBearerFilter;
-import android.telephony.data.QosBearerSession;
-
-import org.junit.Test;
-
-import java.util.ArrayList;
-
-public class QosBearerSessionTest {
-
-    @Test
-    public void testParcel() {
-        ArrayList<QosBearerFilter> qosFilters = new ArrayList<>();
-        qosFilters.add(createIpv4QosFilter("122.22.22.22",
-                new QosBearerFilter.PortRange(2222, 2222), 45));
-        QosBearerSession qosBearerSession = new QosBearerSession(1235,
-                createEpsQos(5, 6, 7, 8), qosFilters);
-
-        Parcel p = Parcel.obtain();
-        qosBearerSession.writeToParcel(p, 0);
-        p.setDataPosition(0);
-
-        QosBearerSession qosBearerSession2 = QosBearerSession.CREATOR.createFromParcel(p);
-        assertThat(qosBearerSession).isEqualTo(qosBearerSession2);
-    }
-
-    @Test
-    public void testEquals() {
-        ArrayList<QosBearerFilter> qosFilters = new ArrayList<>();
-        qosFilters.add(createIpv4QosFilter("122.22.22.22",
-                new QosBearerFilter.PortRange(2222, 2222), 45));
-        QosBearerSession qosBearerSession = new QosBearerSession(1235,
-                createEpsQos(5, 6, 7, 8), qosFilters);
-
-        ArrayList<QosBearerFilter> qosFilters2 = new ArrayList<>();
-        qosFilters2.add(createIpv4QosFilter("122.22.22.22",
-                new QosBearerFilter.PortRange(2222, 2222), 45));
-        QosBearerSession qosBearerSession2 = new QosBearerSession(1235,
-                createEpsQos(5, 6, 7, 8), qosFilters2);
-
-        assertThat(qosBearerSession).isEqualTo(qosBearerSession2);
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java
deleted file mode 100644
index 9752885..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkRequestTest.java
+++ /dev/null
@@ -1,365 +0,0 @@
-/*
- * Copyright 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.net.ConnectivityManager;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
-import android.net.TelephonyNetworkSpecifier;
-import android.telephony.data.ApnSetting;
-import android.telephony.data.DataProfile;
-import android.telephony.data.TrafficDescriptor;
-
-import com.android.internal.telephony.TelephonyTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class TelephonyNetworkRequestTest extends TelephonyTest {
-
-    private static final ApnSetting INTERNET_APN_SETTING = new ApnSetting.Builder()
-            .setId(2163)
-            .setOperatorNumeric("12345")
-            .setEntryName("internet")
-            .setApnName("internet")
-            .setUser("user")
-            .setPassword("passwd")
-            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
-            .setProtocol(ApnSetting.PROTOCOL_IPV6)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .setNetworkTypeBitmask(0)
-            .setProfileId(1234)
-            .setMaxConns(321)
-            .setWaitTime(456)
-            .setMaxConnsTime(789)
-            .build();
-
-    private static final ApnSetting MMS_APN_SETTING = new ApnSetting.Builder()
-            .setId(2163)
-            .setOperatorNumeric("12345")
-            .setEntryName("mms")
-            .setApnName("mms")
-            .setUser("user")
-            .setPassword("passwd")
-            .setApnTypeBitmask(ApnSetting.TYPE_MMS)
-            .setProtocol(ApnSetting.PROTOCOL_IPV6)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .setNetworkTypeBitmask(0)
-            .setProfileId(1234)
-            .setMaxConns(321)
-            .setWaitTime(456)
-            .setMaxConnsTime(789)
-            .build();
-    private static final ApnSetting ENTERPRISE_APN_SETTING = new ApnSetting.Builder()
-            .setId(2164)
-            .setOperatorNumeric("12345")
-            .setEntryName("enterprise")
-            .setApnName("enterprise")
-            .setUser("user")
-            .setPassword("passwd")
-            .setApnTypeBitmask(ApnSetting.TYPE_ENTERPRISE)
-            .setProtocol(ApnSetting.PROTOCOL_IPV6)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .setNetworkTypeBitmask(0)
-            .setProfileId(1234)
-            .setMaxConns(321)
-            .setWaitTime(456)
-            .setMaxConnsTime(789)
-            .build();
-
-    @Before
-    public void setUp() throws Exception {
-        logd("TelephonyNetworkRequestTest +Setup!");
-        super.setUp(getClass().getSimpleName());
-        logd("TelephonyNetworkRequestTest -Setup!");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    @Test
-    public void testGetNativeRequest() {
-        NetworkRequest nativeRequest = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build();
-        TelephonyNetworkRequest internetRequest =
-                new TelephonyNetworkRequest(nativeRequest, mPhone);
-        assertThat(internetRequest.getNativeNetworkRequest()).isEqualTo(nativeRequest);
-    }
-
-    @Test
-    public void testPriority() {
-        TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
-        TelephonyNetworkRequest imsRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_IMS)
-                        .build(), mPhone);
-
-        assertThat(internetRequest.getPriority()).isEqualTo(20);
-        assertThat(imsRequest.getPriority()).isEqualTo(40);
-    }
-
-    @Test
-    public void testGetNetworkSpecifier() {
-        TelephonyNetworkSpecifier telephonyNetworkSpecifier =
-                new TelephonyNetworkSpecifier.Builder().setSubscriptionId(5).build();
-
-        TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-                        .setNetworkSpecifier(telephonyNetworkSpecifier)
-                        .build(), mPhone);
-        assertThat(internetRequest.getNetworkSpecifier()).isEqualTo(telephonyNetworkSpecifier);
-    }
-
-    @Test
-    public void testGetCapabilities() {
-        TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
-                        .build(), mPhone);
-        assertThat(internetRequest.getCapabilities()).isEqualTo(
-                new int[]{NetworkCapabilities.NET_CAPABILITY_INTERNET,
-                        NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED,
-                        NetworkCapabilities.NET_CAPABILITY_TRUSTED,
-                        NetworkCapabilities.NET_CAPABILITY_NOT_VPN,
-                        NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED});
-        assertThat(internetRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN))
-                .isTrue();
-        assertThat(internetRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET))
-                .isTrue();
-        assertThat(internetRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN))
-                .isTrue();
-        assertThat(internetRequest.hasCapability(
-                NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)).isTrue();
-        assertThat(internetRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS))
-                .isFalse();
-    }
-
-    @Test
-    public void testGetApnTypeNetworkCapability() {
-        TelephonyNetworkRequest request = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)
-                        .build(), mPhone);
-        assertThat(request.getApnTypeNetworkCapability())
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_SUPL);
-
-        request = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                        .build(), mPhone);
-        assertThat(request.getApnTypeNetworkCapability())
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_FOTA);
-
-        request = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                        .build(), mPhone);
-        assertThat(request.getApnTypeNetworkCapability())
-                .isEqualTo(NetworkCapabilities.NET_CAPABILITY_EIMS);
-    }
-
-    @Test
-    public void testCanBeSatisfiedBy() {
-        TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
-        NetworkCapabilities caps = new NetworkCapabilities.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_TRUSTED)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                .build();
-        assertThat(internetRequest.canBeSatisfiedBy(caps)).isTrue();
-    }
-
-    @Test
-    public void testCanBeSatisfiedByApnDataProfile() {
-        TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
-        TelephonyNetworkRequest mmsRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
-                        .build(), mPhone);
-        DataProfile internetDataProfile = new DataProfile.Builder()
-                .setApnSetting(INTERNET_APN_SETTING)
-                .build();
-        DataProfile mmsDataProfile = new DataProfile.Builder()
-                .setApnSetting(MMS_APN_SETTING)
-                .build();
-
-        assertThat(internetRequest.canBeSatisfiedBy(internetDataProfile)).isTrue();
-        assertThat(internetRequest.canBeSatisfiedBy(mmsDataProfile)).isFalse();
-        assertThat(mmsRequest.canBeSatisfiedBy(internetDataProfile)).isFalse();
-        assertThat(mmsRequest.canBeSatisfiedBy(mmsDataProfile)).isTrue();
-    }
-
-    @Test
-    public void testCanBeSatisfiedByEnterpriseDataProfile() {
-        TelephonyNetworkRequest enterpriseRequest1 = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
-                        .build(), mPhone);
-        TelephonyNetworkRequest enterpriseRequest2 = new TelephonyNetworkRequest(
-                new NetworkRequest(new NetworkCapabilities()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
-                        .addEnterpriseId(2), ConnectivityManager.TYPE_NONE,
-                        0, NetworkRequest.Type.REQUEST), mPhone);
-
-        DataProfile enterpriseDataProfile1 = new DataProfile.Builder()
-                .setTrafficDescriptor(new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
-                        TrafficDescriptor.OsAppId.ANDROID_OS_ID, "ENTERPRISE", 1).getBytes()))
-                .build();
-        DataProfile enterpriseDataProfile2 = new DataProfile.Builder()
-                .setTrafficDescriptor(new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
-                        TrafficDescriptor.OsAppId.ANDROID_OS_ID, "ENTERPRISE", 2).getBytes()))
-                .build();
-
-        assertThat(enterpriseRequest1.canBeSatisfiedBy(enterpriseDataProfile1)).isTrue();
-        assertThat(enterpriseRequest1.canBeSatisfiedBy(enterpriseDataProfile2)).isFalse();
-        assertThat(enterpriseRequest2.canBeSatisfiedBy(enterpriseDataProfile1)).isFalse();
-        assertThat(enterpriseRequest2.canBeSatisfiedBy(enterpriseDataProfile2)).isTrue();
-    }
-
-    @Test
-    public void testCanBeSatisfiedByEnterpriseApnDataProfile() {
-        TelephonyNetworkRequest enterpriseRequest1 = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .build(), mPhone);
-        TelephonyNetworkRequest enterpriseRequest2 = new TelephonyNetworkRequest(
-                new NetworkRequest(new NetworkCapabilities()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_ENTERPRISE)
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                        .addEnterpriseId(2), ConnectivityManager.TYPE_NONE,
-                        0, NetworkRequest.Type.REQUEST), mPhone);
-        TelephonyNetworkRequest internetRequest = new TelephonyNetworkRequest(
-                new NetworkRequest(new NetworkCapabilities()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET),
-                        ConnectivityManager.TYPE_NONE,
-                        0, NetworkRequest.Type.REQUEST), mPhone);
-
-        DataProfile enterpriseDataProfile = new DataProfile.Builder()
-                .setApnSetting(ENTERPRISE_APN_SETTING)
-                .build();
-        DataProfile internetDataProfile = new DataProfile.Builder()
-                .setApnSetting(INTERNET_APN_SETTING)
-                .build();
-
-        assertThat(enterpriseRequest1.canBeSatisfiedBy(enterpriseDataProfile)).isTrue();
-        assertThat(enterpriseRequest1.canBeSatisfiedBy(internetDataProfile)).isFalse();
-        assertThat(enterpriseRequest2.canBeSatisfiedBy(enterpriseDataProfile)).isTrue();
-        assertThat(enterpriseRequest2.canBeSatisfiedBy(internetDataProfile)).isFalse();
-        assertThat(internetRequest.canBeSatisfiedBy(enterpriseDataProfile)).isFalse();
-        assertThat(internetRequest.canBeSatisfiedBy(internetDataProfile)).isTrue();
-    }
-
-    @Test
-    public void testCanBeSatisfiedByUrllcDataProfile() {
-        TelephonyNetworkRequest urllcRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
-                        .build(), mPhone);
-
-        TelephonyNetworkRequest embbRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
-                        .build(), mPhone);
-
-        DataProfile urllcDataProfile = new DataProfile.Builder()
-                .setTrafficDescriptor(new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
-                        TrafficDescriptor.OsAppId.ANDROID_OS_ID, "PRIORITIZE_LATENCY", 1)
-                        .getBytes()))
-                .build();
-
-        assertThat(urllcRequest.canBeSatisfiedBy(urllcDataProfile)).isTrue();
-        assertThat(embbRequest.canBeSatisfiedBy(urllcDataProfile)).isFalse();
-    }
-
-    @Test
-    public void testCanBeSatisfiedByEmbbDataProfile() {
-        TelephonyNetworkRequest urllcRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_LATENCY)
-                        .build(), mPhone);
-
-        TelephonyNetworkRequest embbRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
-                        .build(), mPhone);
-
-        DataProfile embbDataProfile = new DataProfile.Builder()
-                .setTrafficDescriptor(new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
-                        TrafficDescriptor.OsAppId.ANDROID_OS_ID, "PRIORITIZE_BANDWIDTH", 1)
-                        .getBytes()))
-                .build();
-
-        assertThat(embbRequest.canBeSatisfiedBy(embbDataProfile)).isTrue();
-        assertThat(urllcRequest.canBeSatisfiedBy(embbDataProfile)).isFalse();
-    }
-
-    @Test
-    public void testCanBeSatisfiedByCbsDataProfile() {
-        TelephonyNetworkRequest cbsRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_CBS)
-                        .build(), mPhone);
-
-        TelephonyNetworkRequest embbRequest = new TelephonyNetworkRequest(
-                new NetworkRequest.Builder()
-                        .addCapability(NetworkCapabilities.NET_CAPABILITY_PRIORITIZE_BANDWIDTH)
-                        .build(), mPhone);
-
-        DataProfile cbsDataProfile = new DataProfile.Builder()
-                .setTrafficDescriptor(new TrafficDescriptor(null, new TrafficDescriptor.OsAppId(
-                        TrafficDescriptor.OsAppId.ANDROID_OS_ID, "CBS")
-                        .getBytes()))
-                .build();
-
-        assertThat(cbsRequest.canBeSatisfiedBy(cbsDataProfile)).isTrue();
-        assertThat(embbRequest.canBeSatisfiedBy(cbsDataProfile)).isFalse();
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/TrafficDescriptorTest.java b/tests/telephonytests/src/com/android/internal/telephony/data/TrafficDescriptorTest.java
deleted file mode 100644
index 7b11e25..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/data/TrafficDescriptorTest.java
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.data;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertThrows;
-
-import android.telephony.Rlog;
-import android.telephony.data.TrafficDescriptor;
-import android.telephony.data.TrafficDescriptor.OsAppId;
-
-import org.junit.Test;
-
-import java.math.BigInteger;
-import java.util.UUID;
-
-public class TrafficDescriptorTest {
-
-    @Test
-    public void testEnterpriseOsAppId() {
-        for (int i = 1; i <= 5; i++) {
-            OsAppId osAppId = new OsAppId(OsAppId.ANDROID_OS_ID, "ENTERPRISE", i);
-            byte[] rawBytes = osAppId.getBytes();
-            Rlog.d("TrafficDescriptorTest", "rawBytes=" + new BigInteger(1, rawBytes).toString(16)
-                    + ", osAppId=" + osAppId);
-            assertThat(new OsAppId(rawBytes)).isEqualTo(osAppId);
-            assertThat(osAppId.getOsId()).isEqualTo(OsAppId.ANDROID_OS_ID);
-            assertThat(osAppId.getAppId()).isEqualTo("ENTERPRISE");
-            assertThat(osAppId.getDifferentiator()).isEqualTo(i);
-        }
-    }
-
-    @Test
-    public void testUrllcOsAppId() {
-        OsAppId osAppId = new OsAppId(OsAppId.ANDROID_OS_ID, "PRIORITIZE_LATENCY", 1);
-        byte[] rawBytes = osAppId.getBytes();
-        Rlog.d("TrafficDescriptorTest", "rawBytes=" + new BigInteger(1, rawBytes).toString(16)
-                + ", osAppId=" + osAppId);
-        assertThat(new OsAppId(rawBytes)).isEqualTo(osAppId);
-        assertThat(osAppId.getOsId()).isEqualTo(OsAppId.ANDROID_OS_ID);
-        assertThat(osAppId.getAppId()).isEqualTo("PRIORITIZE_LATENCY");
-        assertThat(osAppId.getDifferentiator()).isEqualTo(1);
-    }
-
-    @Test
-    public void testEmbbOsAppId() {
-        OsAppId osAppId = new OsAppId(OsAppId.ANDROID_OS_ID, "PRIORITIZE_BANDWIDTH", 1);
-        byte[] rawBytes = osAppId.getBytes();
-        Rlog.d("TrafficDescriptorTest", "rawBytes=" + new BigInteger(1, rawBytes).toString(16)
-                + ", osAppId=" + osAppId);
-        assertThat(new OsAppId(rawBytes)).isEqualTo(osAppId);
-        assertThat(osAppId.getOsId()).isEqualTo(OsAppId.ANDROID_OS_ID);
-        assertThat(osAppId.getAppId()).isEqualTo("PRIORITIZE_BANDWIDTH");
-        assertThat(osAppId.getDifferentiator()).isEqualTo(1);
-    }
-
-    @Test
-    public void testInvalidOsId() {
-        OsAppId osAppId = new OsAppId(UUID.fromString("91b7f6fb-5069-4e29-af83-50e942e9b1c3"),
-                "ENTERPRISE", 1);
-        // IllegalArgumentException is expected when OS id is not Android
-        assertThrows(IllegalArgumentException.class,
-                () -> new TrafficDescriptor.Builder()
-                        .setDataNetworkName("DNN")
-                        .setOsAppId(osAppId.getBytes())
-                        .build());
-    }
-
-    @Test
-    public void testInvalidAppId() {
-        OsAppId osAppId = new OsAppId(OsAppId.ANDROID_OS_ID, "FOO", 1);
-        // IllegalArgumentException is expected when App id is not in the allowed this.
-        assertThrows(IllegalArgumentException.class,
-                () -> new TrafficDescriptor.Builder()
-                        .setDataNetworkName("DNN")
-                        .setOsAppId(osAppId.getBytes())
-                        .build());
-    }
-
-    @Test
-    public void testInvalidDifferentiator() {
-        // IllegalArgumentException is expected when App id is not in the allowed this.
-        assertThrows(IllegalArgumentException.class,
-                () -> new OsAppId(OsAppId.ANDROID_OS_ID, "ENTERPRISE", 0));
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnConfigTypeRepositoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnConfigTypeRepositoryTest.java
index f2d694f..532dbe0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnConfigTypeRepositoryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnConfigTypeRepositoryTest.java
@@ -22,7 +22,6 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.data.ApnSetting;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -38,11 +37,6 @@
         mCarrierConfig = new PersistableBundle();
     }
 
-    @After
-    public void tearDown() {
-        mCarrierConfig = null;
-    }
-
     @Test
     public void testReturnsDefaultsWhenCarrierConfigNull() {
         ApnConfigTypeRepository repository = new ApnConfigTypeRepository(null);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java
index b270548..85d1e5e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnContextTest.java
@@ -21,7 +21,6 @@
 import static junit.framework.Assert.assertTrue;
 
 import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -38,9 +37,10 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 
 public class ApnContextTest extends TelephonyTest {
-    // Mocked classes
+    @Mock
     ApnSetting mApnSetting;
 
     private ApnContext mApnContext;
@@ -48,7 +48,7 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mApnSetting = mock(ApnSetting.class);
+
         mApnContext = new ApnContext(mPhone, ApnSetting.TYPE_DEFAULT, TAG, mDcTracker, 1);
     }
 
@@ -198,16 +198,32 @@
     public void testProvisionApn() throws Exception {
         mContextFixture.putResource(R.string.mobile_provisioning_apn, "fake_apn");
 
-        ApnSetting myApn = new ApnSetting.Builder()
-                .setId(2163)
-                .setOperatorNumeric("44010")
-                .setEntryName("sp-mode")
-                .setApnName("fake_apn")
-                .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
-                .setProtocol(ApnSetting.PROTOCOL_IP)
-                .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-                .setCarrierEnabled(true)
-                .build();
+        ApnSetting myApn = ApnSetting.makeApnSetting(
+                2163,                   // id
+                "44010",                // numeric
+                "sp-mode",              // name
+                "fake_apn",             // apn
+                null,                     // proxy
+                -1,                     // port
+                null,                     // mmsc
+                null,                     // mmsproxy
+                -1,                     // mmsport
+                "",                     // user
+                "",                     // password
+                -1,                     // authtype
+                ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL,     // types
+                ApnSetting.PROTOCOL_IP,                   // protocol
+                ApnSetting.PROTOCOL_IP,                   // roaming_protocol
+                true,                   // carrier_enabled
+                0,                      // networktype_bismask
+                0,                      // profile_id
+                false,                  // modem_cognitive
+                0,                      // max_conns
+                0,                      // wait_time
+                0,                      // max_conns_time
+                0,                      // mtu
+                -1,                     // mvno_type
+                "");                    // mnvo_match_data
 
         mApnContext.setApnSetting(myApn);
         assertTrue(mApnContext.isProvisioningApn());
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
index ddf2fb8..0b19baf 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/ApnSettingTest.java
@@ -24,7 +24,6 @@
 import static org.mockito.Mockito.doReturn;
 
 import android.net.Uri;
-import android.os.Parcel;
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
@@ -41,6 +40,7 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.net.InetAddress;
+import java.util.ArrayList;
 import java.util.List;
 
 public class ApnSettingTest extends TelephonyTest {
@@ -55,7 +55,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mBundle = null;
         super.tearDown();
     }
 
@@ -68,16 +67,32 @@
     }
 
     private static ApnSetting createApnSettingInternal(int apnTypeBitmask, boolean carrierEnabled) {
-        return new ApnSetting.Builder()
-                .setId(2163)
-                .setOperatorNumeric("44010")
-                .setEntryName("sp-mode")
-                .setApnName("fake_apn")
-                .setApnTypeBitmask(apnTypeBitmask)
-                .setProtocol(ApnSetting.PROTOCOL_IP)
-                .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-                .setCarrierEnabled(carrierEnabled)
-                .build();
+        return ApnSetting.makeApnSetting(
+                2163,                   // id
+                "44010",                // numeric
+                "sp-mode",              // name
+                "spmode.ne.jp",         // apn
+                null,                   // proxy
+                -1,                     // port
+                null,                   // mmsc
+                null,                   // mmsproxy
+                -1,                     // mmsport
+                "",                     // user
+                "",                     // password
+                -1,                     // authtype
+                apnTypeBitmask,         // types
+                ApnSetting.PROTOCOL_IP, // protocol
+                ApnSetting.PROTOCOL_IP, // roaming_protocol
+                carrierEnabled,         // carrier_enabled
+                0,                      // networktype_bitmask
+                0,                      // profile_id
+                false,                  // modem_cognitive
+                0,                      // max_conns
+                0,                      // wait_time
+                0,                      // max_conns_time
+                0,                      // mtu
+                -1,                     // mvno_type
+                "");                    // mnvo_match_data
     }
 
     private static void assertApnSettingsEqual(List<ApnSetting> a1, List<ApnSetting> a2) {
@@ -109,7 +124,7 @@
         assertEquals(a1.getMaxConns(), a2.getMaxConns());
         assertEquals(a1.getWaitTime(), a2.getWaitTime());
         assertEquals(a1.getMaxConnsTime(), a2.getMaxConnsTime());
-        assertEquals(a1.getMtuV4(), a2.getMtuV4());
+        assertEquals(a1.getMtu(), a2.getMtu());
         assertEquals(a1.getMvnoType(), a2.getMvnoType());
         assertEquals(a1.getMvnoMatchData(), a2.getMvnoMatchData());
         assertEquals(a1.getNetworkTypeBitmask(), a2.getNetworkTypeBitmask());
@@ -119,6 +134,194 @@
 
     @Test
     @SmallTest
+    public void testFromString() {
+        final int dunTypesBitmask = ApnSetting.TYPE_DUN;
+        final int mmsTypesBitmask = ApnSetting.TYPE_MMS | ApnSetting.TYPE_ALL;
+
+        ApnSetting expectedApn;
+        String testString;
+
+        // A real-world v1 example string.
+        testString = "Vodafone IT,web.omnitel.it,,,,,,,,,222,10,,DUN";
+        expectedApn = ApnSetting.makeApnSetting(
+                -1, "22210", "Vodafone IT", "web.omnitel.it", "", -1, null, "", -1, "", "", 0,
+                dunTypesBitmask, ApnSetting.PROTOCOL_IP, ApnSetting.PROTOCOL_IP, true,
+                0, 0, false, 0, 0, 0, 0, -1, "");
+        assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+        // A v2 string.
+        testString = "[ApnSettingV2] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,14";
+        int networkTypeBitmask = 1 << (13 - 1);
+        expectedApn = ApnSetting.makeApnSetting(
+                -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+                mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                networkTypeBitmask, 0, false, 0, 0, 0, 0, -1, "");
+        assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+        // A v2 string with spaces.
+        testString = "[ApnSettingV2] Name,apn, ,,,,,,,,123,45,,mms|*,IPV6, IP,true,14";
+        expectedApn = ApnSetting.makeApnSetting(
+                -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+                mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                networkTypeBitmask, 0, false, 0, 0, 0, 0, -1, "");
+        assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+        // A v3 string.
+        testString = "[ApnSettingV3] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,14,,,,,,,spn,testspn";
+        expectedApn = ApnSetting.makeApnSetting(
+                -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+                mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn");
+        assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+        // A v4 string with network type bitmask.
+        testString =
+                "[ApnSettingV4] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,0,,,,,,,spn,testspn,6";
+        networkTypeBitmask = 1 << (6 - 1);
+        expectedApn = ApnSetting.makeApnSetting(
+                -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+                mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn");
+        assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+        testString =
+                "[ApnSettingV4] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,0,,,,,,,spn,testspn,"
+                        + "4|5|6|7|8|12|13|14|19";
+        // The value was calculated by adding "4|5|6|7|8|12|13|14|19".
+        networkTypeBitmask = 276728;
+        expectedApn = ApnSetting.makeApnSetting(
+                -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+                mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn");
+        assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+        // A v4 string with network type bitmask and compatible bearer bitmask.
+        testString =
+                "[ApnSettingV4] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,8,,,,,,,spn,testspn, 6";
+        networkTypeBitmask = 1 << (6 - 1);
+        expectedApn = ApnSetting.makeApnSetting(
+                -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+                mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn");
+        assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+        // A v4 string with network type bitmask and incompatible bearer bitmask.
+        testString =
+                "[ApnSettingV4] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,9,,,,,,,spn,testspn, 6";
+        expectedApn = ApnSetting.makeApnSetting(
+                -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+                mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                networkTypeBitmask, 0, false, 0,
+                0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn");
+        assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+        // A v5 string with apnSetId=0
+        testString =
+                "[ApnSettingV5] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,0,,,,,,,spn,testspn,0,0";
+        expectedApn = ApnSetting.makeApnSetting(
+                -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+                mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn");
+        assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+        // A v5 string with apnSetId=3
+        testString =
+                "[ApnSettingV5] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,0,,,,,,,spn,testspn,0,3";
+        expectedApn = ApnSetting.makeApnSetting(
+                -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+                mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3, -1, -1);
+        assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+        // A v6 string with carrierId=100
+        testString =
+            "[ApnSettingV5] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,0,,,,,,,spn,testspn,0,3,"
+                + "100";
+        expectedApn = ApnSetting.makeApnSetting(
+            -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+            mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+            0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3, 100, -1);
+        assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+        // A v7 string with skip_464xlat=1
+        testString =
+            "[ApnSettingV7] Name,apn,,,,,,,,,123,45,,mms|*,IPV6,IP,true,0,,,,,,,spn,testspn,0,3,"
+                + "-1, 1";
+        expectedApn = ApnSetting.makeApnSetting(
+            -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+            mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+            0, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn", 3, -1, 1);
+        assertApnSettingEqual(expectedApn, ApnSetting.fromString(testString));
+
+        // Return no apn if insufficient fields given.
+        testString = "[ApnSettingV3] Name,apn,,,,,,,,,123, 45,,mms|*";
+        assertEquals(null, ApnSetting.fromString(testString));
+
+        testString = "Name,apn,,,,,,,,,123, 45,";
+        assertEquals(null, ApnSetting.fromString(testString));
+    }
+
+    @Test
+    @SmallTest
+    public void testArrayFromString() {
+        final int mmsTypesBitmask = ApnSetting.TYPE_MMS;
+        // Test a multiple v3 string.
+        String testString =
+                "[ApnSettingV3] Name,apn,,,,,,,,,123,45,,mms,IPV6,IP,true,14,,,,,,,spn,testspn";
+        testString +=
+                " ;[ApnSettingV3] Name1,apn1,,,,,,,,,123,46,,mms,IPV6,IP,true,12,,,,,,,gid,testGid";
+        testString +=
+                " ;[ApnSettingV3] Name1,apn2,,,,,,,,,123,46,,mms,IPV6,IP,true,12,,,,,,,,";
+        testString +=
+                " ;[ApnSettingV5] Name1,apn2,,,,,,,,,123,46,,mms,IPV6,IP,true,0,,,,,,,,,,3";
+        List<ApnSetting> expectedApns = new ArrayList<ApnSetting>();
+        expectedApns.add(ApnSetting.makeApnSetting(
+                -1, "12345", "Name", "apn", "", -1, null, "", -1, "", "", 0,
+                mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                1 << (13 - 1), 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "testspn"));
+        expectedApns.add(ApnSetting.makeApnSetting(
+                -1, "12346", "Name1", "apn1", "", -1, null, "", -1, "", "", 0,
+                mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                1 << (12 - 1), 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_GID, "testGid"));
+        expectedApns.add(ApnSetting.makeApnSetting(
+                -1, "12346", "Name1", "apn2", "", -1, null, "", -1, "", "", 0,
+                mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                1 << (12 - 1), 0, false, 0, 0, 0, 0, -1, ""));
+        expectedApns.add(ApnSetting.makeApnSetting(
+                -1, "12346", "Name1", "apn2", "", -1, null, "", -1, "", "", 0,
+                mmsTypesBitmask, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                0, 0, false, 0, 0, 0, 0, -1, "", 3, -1, -1));
+        assertApnSettingsEqual(expectedApns, ApnSetting.arrayFromString(testString));
+    }
+
+    @Test
+    @SmallTest
+    public void testToString() {
+        // Use default apn_set_id constructor.
+        ApnSetting apn = ApnSetting.makeApnSetting(
+                99, "12345", "Name", "apn", null, 10,
+                null, null, -1, "user", "password", 0,
+                ApnSetting.TYPE_DEFAULT, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                4096, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "");
+        String expected = "[ApnSettingV7] Name, 99, 12345, apn, null, "
+                + "null, null, null, 10, 0, hipri | default, "
+                + "IPV6, IP, true, 0, false, 0, 0, 0, 0, spn, , false, 4096, 0, -1, -1";
+        assertEquals(expected, apn.toString());
+
+        final int networkTypeBitmask = 1 << (14 - 1);
+        apn = ApnSetting.makeApnSetting(
+                99, "12345", "Name", "apn", null, 10,
+                null, null, -1, "user", "password", 0,
+                ApnSetting.TYPE_DEFAULT, ApnSetting.PROTOCOL_IPV6, ApnSetting.PROTOCOL_IP, true,
+                networkTypeBitmask, 0, false, 0, 0, 0, 0, ApnSetting.MVNO_TYPE_SPN, "", 3, -1, 1);
+        expected = "[ApnSettingV7] Name, 99, 12345, apn, null, "
+                + "null, null, null, 10, 0, hipri | default, "
+                + "IPV6, IP, true, 0, false, 0, 0, 0, 0, spn, , false, 8192, 3, -1, 1";
+        assertEquals(expected, apn.toString());
+    }
+
+    @Test
+    @SmallTest
     public void testIsMetered() {
         mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
                 new String[]{ApnSetting.TYPE_DEFAULT_STRING, ApnSetting.TYPE_MMS_STRING});
@@ -405,7 +608,6 @@
     @SmallTest
     public void testEquals() throws Exception {
         final int dummyInt = 1;
-        final int dummyLong = 1;
         final String dummyString = "dummy";
         final String[] dummyStringArr = new String[] {"dummy"};
         final InetAddress dummyProxyAddress = InetAddress.getByAddress(new byte[]{0, 0, 0, 0});
@@ -423,9 +625,6 @@
             if (int.class.equals(f.getType())) {
                 testApn = ApnSetting.makeApnSetting(baseApn);
                 f.setInt(testApn, dummyInt + f.getInt(testApn));
-            } else if (long.class.equals(f.getType())) {
-                testApn = ApnSetting.makeApnSetting(baseApn);
-                f.setLong(testApn, dummyLong + f.getLong(testApn));
             } else if (boolean.class.equals(f.getType())) {
                 testApn = ApnSetting.makeApnSetting(baseApn);
                 f.setBoolean(testApn, !f.getBoolean(testApn));
@@ -453,32 +652,59 @@
     @Test
     @SmallTest
     public void testEqualsRoamingProtocol() {
-        ApnSetting apn1 = new ApnSetting.Builder()
-                .setId(1234)
-                .setOperatorNumeric("310260")
-                .setEntryName("ims")
-                .setApnName("ims")
-                .setApnTypeBitmask(ApnSetting.TYPE_IMS)
-                .setProtocol(ApnSetting.PROTOCOL_IPV6)
-                .setNetworkTypeBitmask(
-                        ServiceState.convertBearerBitmaskToNetworkTypeBitmask(131071))
-                .setMtuV4(1440)
-                .setCarrierEnabled(true)
-                .build();
+        ApnSetting apn1 = ApnSetting.makeApnSetting(
+                1234,
+                "310260",
+                "",
+                "ims",
+                null,
+                -1,
+                null,
+                null,
+                -1,
+                "",
+                "",
+                -1,
+                ApnSetting.TYPE_IMS,
+                ApnSetting.PROTOCOL_IPV6,
+                -1,
+                true,
+                ServiceState.convertBearerBitmaskToNetworkTypeBitmask(131071),
+                0,
+                false,
+                0,
+                0,
+                0,
+                1440,
+                -1,
+                "");
 
-        ApnSetting apn2 = new ApnSetting.Builder()
-                .setId(1235)
-                .setOperatorNumeric("310260")
-                .setEntryName("ims")
-                .setApnName("ims")
-                .setApnTypeBitmask(ApnSetting.TYPE_IMS)
-                .setProtocol(ApnSetting.PROTOCOL_IPV6)
-                .setRoamingProtocol(ApnSetting.PROTOCOL_IPV6)
-                .setNetworkTypeBitmask(
-                        ServiceState.convertBearerBitmaskToNetworkTypeBitmask(131072))
-                .setMtuV4(1440)
-                .setCarrierEnabled(true)
-                .build();
+        ApnSetting apn2 = ApnSetting.makeApnSetting(
+                1235,
+                "310260",
+                "",
+                "ims",
+                null,
+                -1,
+                null,
+                null,
+                -1,
+                "",
+                "",
+                -1,
+                ApnSetting.TYPE_IMS,
+                ApnSetting.PROTOCOL_IPV6,
+                ApnSetting.PROTOCOL_IPV6,
+                true,
+                ServiceState.convertBearerBitmaskToNetworkTypeBitmask(131072),
+                0,
+                false,
+                0,
+                0,
+                0,
+                1440,
+                -1,
+                "");
 
         assertTrue(apn1.equals(apn2, false));
         assertFalse(apn1.equals(apn2, true));
@@ -487,32 +713,61 @@
     @Test
     @SmallTest
     public void testCanHandleNetwork() {
-        ApnSetting apn1 = new ApnSetting.Builder()
-                .setId(1234)
-                .setOperatorNumeric("310260")
-                .setEntryName("ims")
-                .setApnName("ims")
-                .setApnTypeBitmask(ApnSetting.TYPE_IMS)
-                .setProtocol(ApnSetting.PROTOCOL_IPV6)
-                .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
-                        | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS))
-                .setMtuV4(1440)
-                .setCarrierEnabled(true)
-                .build();
+        ApnSetting apn1 = ApnSetting.makeApnSetting(
+                1234,
+                "310260",
+                "",
+                "ims",
+                null,
+                -1,
+                null,
+                null,
+                -1,
+                "",
+                "",
+                -1,
+                ApnSetting.TYPE_IMS,
+                ApnSetting.PROTOCOL_IPV6,
+                -1,
+                true,
+                (int) (TelephonyManager.NETWORK_TYPE_BITMASK_LTE
+                        | TelephonyManager.NETWORK_TYPE_BITMASK_UMTS),
+                0,
+                false,
+                0,
+                0,
+                0,
+                1440,
+                -1,
+                "");
 
-        ApnSetting apn2 = new ApnSetting.Builder()
-                .setId(1235)
-                .setOperatorNumeric("310260")
-                .setEntryName("ims")
-                .setApnName("ims")
-                .setApnTypeBitmask(ApnSetting.TYPE_IMS)
-                .setProtocol(ApnSetting.PROTOCOL_IPV6)
-                .setRoamingProtocol(ApnSetting.PROTOCOL_IPV6)
-                .setNetworkTypeBitmask((int) (TelephonyManager.NETWORK_TYPE_BITMASK_EDGE
-                        | TelephonyManager.NETWORK_TYPE_BITMASK_GPRS))
-                .setMtuV4(1440)
-                .setCarrierEnabled(true)
-                .build();
+        ApnSetting apn2 = ApnSetting.makeApnSetting(
+                1235,
+                "310260",
+                "",
+                "ims",
+                null,
+                -1,
+                null,
+                null,
+                -1,
+                "",
+                "",
+                -1,
+                ApnSetting.TYPE_IMS,
+                ApnSetting.PROTOCOL_IPV6,
+                ApnSetting.PROTOCOL_IPV6,
+                true,
+                (int) (TelephonyManager.NETWORK_TYPE_BITMASK_EDGE
+                        | TelephonyManager.NETWORK_TYPE_BITMASK_GPRS),
+                0,
+                false,
+                0,
+                0,
+                0,
+                1440,
+                -1,
+                "");
 
         assertFalse(apn1.canSupportNetworkType(TelephonyManager.NETWORK_TYPE_1xRTT));
         assertTrue(apn1.canSupportNetworkType(TelephonyManager.NETWORK_TYPE_LTE));
@@ -525,19 +780,4 @@
 
         assertTrue(apn2.canSupportNetworkType(TelephonyManager.NETWORK_TYPE_GSM));
     }
-
-    @Test
-    public void testParcel() {
-        ApnSetting apn = createApnSetting(ApnSetting.TYPE_DEFAULT);
-
-        Parcel parcel = Parcel.obtain();
-        apn.writeToParcel(parcel, 0 /* flags */);
-        parcel.setDataPosition(0);
-
-        ApnSetting fromParcel = ApnSetting.CREATOR.createFromParcel(parcel);
-
-        assertEquals(apn, fromParcel);
-
-        parcel.recycle();
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataCallResponseTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataCallResponseTest.java
similarity index 88%
rename from tests/telephonytests/src/com/android/internal/telephony/data/DataCallResponseTest.java
rename to tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataCallResponseTest.java
index 46d1f0a..6f91709 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataCallResponseTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataCallResponseTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony.dataconnection;
 
 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_ADDRESS;
 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_DNS;
@@ -28,7 +28,6 @@
 import android.telephony.data.ApnSetting;
 import android.telephony.data.DataCallResponse;
 import android.telephony.data.EpsQos;
-import android.telephony.data.Qos;
 import android.telephony.data.TrafficDescriptor;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -38,16 +37,8 @@
 
 public class DataCallResponseTest extends AndroidTestCase {
     public static final String FAKE_DNN = "FAKE_DNN";
-    // 97a498e3fc925c9489860333d06e4e470a454e5445525052495345.
-    // [OsAppId.ANDROID_OS_ID, "ENTERPRISE", 1]
-    public static final byte[] FAKE_OS_APP_ID = {-105, -92, -104, -29, -4, -110, 92,
-            -108, -119, -122, 3, 51, -48, 110, 78, 71, 10, 69, 78, 84, 69,
-            82, 80, 82, 73, 83, 69};
-    // 97a498e3fc925c9489860333d06e4e470a454e544552505249534532.
-    // [OsAppId.ANDROID_OS_ID, "ENTERPRISE", 2]
-    public static final byte[] FAKE_OS_APP_ID_2 = {-105, -92, -104, -29, -4, -110, 92,
-            -108, -119, -122, 3, 51, -48, 110, 78, 71, 10, 69, 78, 84, 69,
-            82, 80, 82, 73, 83, 69, 50};
+    public static final byte[] FAKE_OS_APP_ID = {1, 2, 3, 4};
+    public static final byte[] FAKE_OS_APP_ID_2 = {5, 6, 8, 9};
 
     @SmallTest
     public void testParcel() {
@@ -66,8 +57,7 @@
                         Arrays.asList(InetAddresses.parseNumericAddress(FAKE_PCSCF_ADDRESS)))
                 .setMtuV4(1440)
                 .setMtuV6(1440)
-                .setDefaultQos(new EpsQos(
-                        new Qos.QosBandwidth(-1, -1), new Qos.QosBandwidth(-1, -1), -1))
+                .setDefaultQos(new EpsQos())
                 .setQosBearerSessions(new ArrayList<>())
                 .setTrafficDescriptors(
                         Arrays.asList(new TrafficDescriptor(FAKE_DNN, FAKE_OS_APP_ID)))
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
index dcaa2a0..ca8abeb 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataConnectionTest.java
@@ -43,9 +43,6 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
 import android.net.InetAddresses;
 import android.net.KeepalivePacketData;
 import android.net.LinkAddress;
@@ -53,20 +50,16 @@
 import android.net.NattKeepalivePacketData;
 import android.net.Network;
 import android.net.NetworkCapabilities;
-import android.net.vcn.VcnNetworkPolicyResult;
 import android.os.AsyncResult;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Message;
-import android.os.UserManager;
-import android.provider.Telephony;
 import android.telephony.AccessNetworkConstants;
 import android.telephony.AccessNetworkConstants.AccessNetworkType;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
 import android.telephony.ServiceState.RegState;
 import android.telephony.ServiceState.RilRadioTechnology;
-import android.telephony.TelephonyManager;
 import android.telephony.data.ApnSetting;
 import android.telephony.data.DataCallResponse;
 import android.telephony.data.DataProfile;
@@ -81,7 +74,6 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.RetryManager;
 import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.data.KeepaliveStatus;
 import com.android.internal.telephony.dataconnection.DataConnection.ConnectionParams;
 import com.android.internal.telephony.dataconnection.DataConnection.DisconnectParams;
 import com.android.internal.telephony.dataconnection.DataConnection.SetupResult;
@@ -91,6 +83,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -101,92 +94,197 @@
 
 public class DataConnectionTest extends TelephonyTest {
     private static final int DEFAULT_DC_CID = 10;
-    private static final ArrayList<TrafficDescriptor> DEFAULT_TD_LIST = new ArrayList<>();
 
-    // Mocked classes
+    @Mock
     DcTesterFailBringUpAll mDcTesterFailBringUpAll;
+    @Mock
     ConnectionParams mCp;
+    @Mock
     DisconnectParams mDcp;
+    @Mock
     ApnContext mApnContext;
+    @Mock
     ApnContext mEnterpriseApnContext;
+    @Mock
     DcFailBringUp mDcFailBringUp;
+    @Mock
     DataCallSessionStats mDataCallSessionStats;
+    @Mock
     DataConnection mDefaultDc;
+    @Mock
     DataServiceManager mDataServiceManager;
 
     private DataConnection mDc;
     private DataConnectionTestHandler mDataConnectionTestHandler;
     private DcController mDcc;
 
-    private final ApnSetting mApn1 = new ApnSetting.Builder()
-            .setId(2163)
-            .setOperatorNumeric("44010")
-            .setEntryName("sp-mode")
-            .setApnName("spmode.ne.jp")
-            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
-            .setProtocol(ApnSetting.PROTOCOL_IP)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .build();
+    private ApnSetting mApn1 = ApnSetting.makeApnSetting(
+            2163,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "spmode.ne.jp",         // apn
+            null,                   // proxy
+            -1,                     // port
+            null,                   // mmsc
+            null,                   // mmsproxy
+            -1,                     // mmsport
+            "",                     // user
+            "",                     // password
+            -1,                     // authtype
+            ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL, // types
+            ApnSetting.PROTOCOL_IP, // protocol
+            ApnSetting.PROTOCOL_IP, // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            0,                      // profile_id
+            false,                  // modem_cognitive
+            0,                      // max_conns
+            0,                      // wait_time
+            0,                      // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "");                    // mnvo_match_data
 
-    private final ApnSetting mApn2 = new ApnSetting.Builder()
-            .setId(2164)
-            .setOperatorNumeric("44010")
-            .setEntryName("sp-mode")
-            .setApnName("spmode.ne.jp")
-            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_DUN)
-            .setProtocol(ApnSetting.PROTOCOL_IP)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .build();
+    private ApnSetting mApn2 = ApnSetting.makeApnSetting(
+            2164,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "spmode.ne.jp",         // apn
+            null,                   // proxy
+            -1,                     // port
+            null,                   // mmsc
+            null,                   // mmsproxy
+            -1,                     // mmsport
+            "",                     // user
+            "",                     // password
+            -1,                     // authtype
+            ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_DUN, // types
+            ApnSetting.PROTOCOL_IP, // protocol
+            ApnSetting.PROTOCOL_IP, // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            0,                      // profile_id
+            false,                  // modem_cognitive
+            0,                      // max_conns
+            0,                      // wait_time
+            0,                      // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "");                    // mnvo_match_data
 
-    private final ApnSetting mApn3 = new ApnSetting.Builder()
-            .setId(2165)
-            .setOperatorNumeric("44010")
-            .setEntryName("sp-mode")
-            .setApnName("spmode.ne.jp")
-            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT)
-            .setProtocol(ApnSetting.PROTOCOL_IPV6)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setNetworkTypeBitmask(0)
-            .setCarrierEnabled(true)
-            .setCarrierId(1)
-            .setSkip464Xlat(1)
-            .build();
+    private ApnSetting mApn3 = ApnSetting.makeApnSetting(
+            2165,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "spmode.ne.jp",         // apn
+            null,                   // proxy
+            -1,                     // port
+            null,                   // mmsc
+            null,                   // mmsproxy
+            -1,                     // mmsport
+            "",                     // user
+            "",                     // password
+            -1,                     // authtype
+            ApnSetting.TYPE_DEFAULT, // types
+            ApnSetting.PROTOCOL_IPV6, // protocol
+            ApnSetting.PROTOCOL_IP, // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            0,                      // profile_id
+            false,                  // modem_cognitive
+            0,                      // max_conns
+            0,                      // wait_time
+            0,                      // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "",                     // mnvo_match_data
+            0,                      // apn_set_id
+            -1,                     // carrier_id
+            1);                     // skip_464xlat
 
-    private final ApnSetting mApn4 = new ApnSetting.Builder()
-            .setId(2166)
-            .setOperatorNumeric("44010")
-            .setEntryName("sp-mode")
-            .setApnName("spmode.ne.jp")
-            .setApnTypeBitmask(ApnSetting.TYPE_IMS)
-            .setProtocol(ApnSetting.PROTOCOL_IPV6)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .build();
+    private ApnSetting mApn4 = ApnSetting.makeApnSetting(
+            2166,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "spmode.ne.jp",         // apn
+            null,                   // proxy
+            -1,                     // port
+            null,                   // mmsc
+            null,                   // mmsproxy
+            -1,                     // mmsport
+            "",                     // user
+            "",                     // password
+            -1,                     // authtype
+            ApnSetting.TYPE_IMS,    // types
+            ApnSetting.PROTOCOL_IPV6, // protocol
+            ApnSetting.PROTOCOL_IP, // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            0,                      // profile_id
+            false,                  // modem_cognitive
+            0,                      // max_conns
+            0,                      // wait_time
+            0,                      // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "");                    // mnvo_match_data
 
-    private final ApnSetting mApn5 = new ApnSetting.Builder()
-            .setId(2167)
-            .setOperatorNumeric("44010")
-            .setEntryName("sp-mode")
-            .setApnName("spmode.ne.jp")
-            .setApnTypeBitmask(ApnSetting.TYPE_IMS)
-            .setProtocol(ApnSetting.PROTOCOL_IPV6)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .setSkip464Xlat(Telephony.Carriers.SKIP_464XLAT_DISABLE)
-            .build();
+    private ApnSetting mApn5 = ApnSetting.makeApnSetting(
+            2167,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "spmode.ne.jp",         // apn
+            null,                   // proxy
+            -1,                     // port
+            null,                   // mmsc
+            null,                   // mmsproxy
+            -1,                     // mmsport
+            "",                     // user
+            "",                     // password
+            -1,                     // authtype
+            ApnSetting.TYPE_IMS,    // types
+            ApnSetting.PROTOCOL_IPV6, // protocol
+            ApnSetting.PROTOCOL_IP, // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            0,                      // profile_id
+            false,                  // modem_cognitive
+            0,                      // max_conns
+            0,                      // wait_time
+            0,                      // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "",                     // mnvo_match_data
+            0,                      // apn_set_id
+            -1,                     // carrier_id
+            0);                     // skip_464xlat
 
-    private final ApnSetting mApn6 = new ApnSetting.Builder()
-            .setId(2168)
-            .setOperatorNumeric("44010")
-            .setEntryName("sp-mode")
-            .setApnName("spmode.ne.jp")
-            .setApnTypeBitmask(ApnSetting.TYPE_EMERGENCY)
-            .setProtocol(ApnSetting.PROTOCOL_IP)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .build();
+    private ApnSetting mApn6 = ApnSetting.makeApnSetting(
+            2168,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "spmode.ne.jp",         // apn
+            null,                   // proxy
+            -1,                     // port
+            null,                   // mmsc
+            null,                   // mmsproxy
+            -1,                     // mmsport
+            "",                     // user
+            "",                     // password
+            -1,                     // authtype
+            ApnSetting.TYPE_EMERGENCY, // types
+            ApnSetting.PROTOCOL_IP, // protocol
+            ApnSetting.PROTOCOL_IP, // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            0,                      // profile_id
+            false,                  // modem_cognitive
+            0,                      // max_conns
+            0,                      // wait_time
+            0,                      // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "");                    // mnvo_match_data
 
     private class DataConnectionTestHandler extends HandlerThread {
 
@@ -199,11 +297,11 @@
             Handler h = new Handler();
             mDcc = DcController.makeDcc(mPhone, mDcTracker, mDataServiceManager, h.getLooper(), "");
             mDc = DataConnection.makeDataConnection(mPhone, 0, mDcTracker, mDataServiceManager,
-                    mDcTesterFailBringUpAll, mDcc);
+                    mDcTesterFailBringUpAll, mDcc, true);
         }
     }
 
-    private void setSuccessfulSetupDataResponse(int cid, ArrayList<TrafficDescriptor> tds) {
+    private void setSuccessfulSetupDataResponse(int cid) {
         doAnswer(invocation -> {
             final Message msg = (Message) invocation.getArguments()[10];
 
@@ -231,7 +329,7 @@
                     .setMtuV6(1500)
                     .setPduSessionId(1)
                     .setQosBearerSessions(new ArrayList<>())
-                    .setTrafficDescriptors(tds)
+                    .setTrafficDescriptors(new ArrayList<>())
                     .build();
             msg.getData().putParcelable("data_call_response", response);
             msg.arg1 = DataServiceCallback.RESULT_SUCCESS;
@@ -256,18 +354,8 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mDcTesterFailBringUpAll = mock(DcTesterFailBringUpAll.class);
-        mCp = mock(ConnectionParams.class);
-        mDcp = mock(DisconnectParams.class);
-        mApnContext = mock(ApnContext.class);
-        mEnterpriseApnContext = mock(ApnContext.class);
-        mDcFailBringUp = mock(DcFailBringUp.class);
-        mDataCallSessionStats = mock(DataCallSessionStats.class);
-        mDefaultDc = mock(DataConnection.class);
-        mDataServiceManager = mock(DataServiceManager.class);
         logd("+Setup!");
         doReturn("fake.action_detached").when(mPhone).getActionDetached();
-        doReturn(false).when(mPhone).isUsingNewDataStack();
         replaceInstance(ConnectionParams.class, "mApnContext", mCp, mApnContext);
         replaceInstance(ConnectionParams.class, "mRilRat", mCp,
                 ServiceState.RIL_RADIO_TECHNOLOGY_UMTS);
@@ -296,7 +384,7 @@
 
         mDcp.mApnContext = mApnContext;
 
-        setSuccessfulSetupDataResponse(DEFAULT_DC_CID, DEFAULT_TD_LIST);
+        setSuccessfulSetupDataResponse(DEFAULT_DC_CID);
 
         doAnswer(invocation -> {
             final Message msg = (Message) invocation.getArguments()[2];
@@ -320,15 +408,10 @@
     @After
     public void tearDown() throws Exception {
         logd("tearDown");
-        mDc.quitNow();
         mDc = null;
+        mDcc = null;
         mDataConnectionTestHandler.quit();
         mDataConnectionTestHandler.join();
-        mDataConnectionTestHandler = null;
-        mDcc.removeCallbacksAndMessages(null);
-        mDcc = null;
-        DEFAULT_TD_LIST.clear();
-        waitForMs(100);
         super.tearDown();
     }
 
@@ -399,63 +482,6 @@
                 eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                 anyInt(), any(), tdCaptor.capture(), anyBoolean(), any(Message.class));
 
-        verify(mSimulatedCommandsVerifier, times(0))
-                .allocatePduSessionId(any());
-
-        assertEquals("spmode.ne.jp", dpCaptor.getValue().getApn());
-        if (tdCaptor.getValue() != null) {
-            if (mApnContext.getApnTypeBitmask() == ApnSetting.TYPE_ENTERPRISE) {
-                assertEquals(null, tdCaptor.getValue().getDataNetworkName());
-                assertTrue(Arrays.equals(DataConnection.getEnterpriseOsAppId(),
-                        tdCaptor.getValue().getOsAppId()));
-            } else {
-                assertEquals("spmode.ne.jp", tdCaptor.getValue().getDataNetworkName());
-                assertEquals(null, tdCaptor.getValue().getOsAppId());
-            }
-        }
-        assertTrue(mDc.isActive());
-
-        assertEquals(1, mDc.getPduSessionId());
-        assertEquals(3, mDc.getPcscfAddresses().length);
-        assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c305:1d::8"::equals));
-        assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c202:1d::7"::equals));
-        assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c305:1d::5"::equals));
-    }
-
-    @Test
-    @SmallTest
-    public void testConnectOnIwlan() throws Exception {
-        assertTrue(mDc.isInactive());
-        Field field = DataConnection.class.getDeclaredField("mTransportType");
-        field.setAccessible(true);
-        field.setInt(mDc, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        connectEvent(true);
-
-        verify(mCT, times(1)).registerForVoiceCallStarted(any(Handler.class),
-                eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED), eq(null));
-        verify(mCT, times(1)).registerForVoiceCallEnded(any(Handler.class),
-                eq(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_ENDED), eq(null));
-        verify(mSimulatedCommandsVerifier, times(0))
-                .registerForNattKeepaliveStatus(any(Handler.class),
-                        eq(DataConnection.EVENT_KEEPALIVE_STATUS), eq(null));
-        verify(mSimulatedCommandsVerifier, times(0))
-                .registerForLceInfo(any(Handler.class),
-                        eq(DataConnection.EVENT_LINK_CAPACITY_CHANGED), eq(null));
-        verify(mVcnManager, atLeastOnce())
-                .applyVcnNetworkPolicy(
-                        argThat(caps ->
-                                caps.hasCapability(
-                                        NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)),
-                        any());
-
-        ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
-        ArgumentCaptor<TrafficDescriptor> tdCaptor =
-                ArgumentCaptor.forClass(TrafficDescriptor.class);
-        verify(mDataServiceManager, times(1)).setupDataCall(
-                eq(AccessNetworkType.UTRAN), dpCaptor.capture(), eq(false),
-                eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
-                anyInt(), any(), tdCaptor.capture(), anyBoolean(), any(Message.class));
-
         verify(mSimulatedCommandsVerifier, times(1))
                 .allocatePduSessionId(any());
 
@@ -472,7 +498,7 @@
         }
         assertTrue(mDc.isActive());
 
-        assertEquals(1, mDc.getPduSessionId());
+        assertEquals(mDc.getPduSessionId(), 1);
         assertEquals(3, mDc.getPcscfAddresses().length);
         assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c305:1d::8"::equals));
         assertTrue(Arrays.stream(mDc.getPcscfAddresses()).anyMatch("fd00:976a:c202:1d::7"::equals));
@@ -494,7 +520,7 @@
         assertTrue(mDc.isInactive());
 
         // Change the CID
-        setSuccessfulSetupDataResponse(DEFAULT_DC_CID + 1, DEFAULT_TD_LIST);
+        setSuccessfulSetupDataResponse(DEFAULT_DC_CID + 1);
 
         // Verify that ENTERPRISE was set up
         connectEvent(true);
@@ -503,27 +529,6 @@
     }
 
     @Test
-    public void testConnectEventDuplicateContextIdsDifferentTDs() throws Exception {
-        setUpDefaultData(DEFAULT_DC_CID);
-
-        // Try to connect ENTERPRISE with the same CID as default but different TrafficDescriptors
-        replaceInstance(ConnectionParams.class, "mApnContext", mCp, mEnterpriseApnContext);
-        doReturn(mApn1).when(mEnterpriseApnContext).getApnSetting();
-        doReturn(ApnSetting.TYPE_ENTERPRISE_STRING).when(mEnterpriseApnContext).getApnType();
-        doReturn(ApnSetting.TYPE_ENTERPRISE).when(mEnterpriseApnContext).getApnTypeBitmask();
-        ArrayList<TrafficDescriptor> tdList = new ArrayList<>();
-        tdList.add(new TrafficDescriptor("dnn", DataConnection.getEnterpriseOsAppId()));
-        setSuccessfulSetupDataResponse(DEFAULT_DC_CID, tdList);
-
-        // Verify that ENTERPRISE wasn't set up but the TD list was updated
-        connectEvent(false);
-        assertTrue(mDc.isInactive());
-        ArgumentCaptor<DataCallResponse> captor = ArgumentCaptor.forClass(DataCallResponse.class);
-        verify(mDefaultDc).updateTrafficDescriptors(captor.capture());
-        assertEquals(tdList, captor.getValue().getTrafficDescriptors());
-    }
-
-    @Test
     public void testConnectEventNoDefaultData() throws Exception {
         assertFalse(mDefaultDc.isActive());
 
@@ -570,28 +575,6 @@
                 .unregisterForNattKeepaliveStatus(any(Handler.class));
         verify(mDataServiceManager, times(1)).deactivateDataCall(eq(DEFAULT_DC_CID),
                 eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
-        verify(mSimulatedCommandsVerifier, times(0))
-                .releasePduSessionId(any(), eq(5));
-
-        assertTrue(mDc.isInactive());
-    }
-
-    @Test
-    @SmallTest
-    public void testDisconnectOnIwlan() throws Exception {
-        testConnectEvent();
-
-        Field field = DataConnection.class.getDeclaredField("mTransportType");
-        field.setAccessible(true);
-        field.setInt(mDc, AccessNetworkConstants.TRANSPORT_TYPE_WLAN);
-        mDc.setPduSessionId(5);
-        disconnectEvent();
-
-        verify(mSimulatedCommandsVerifier, times(0)).unregisterForLceInfo(any(Handler.class));
-        verify(mSimulatedCommandsVerifier, times(0))
-                .unregisterForNattKeepaliveStatus(any(Handler.class));
-        verify(mDataServiceManager, times(1)).deactivateDataCall(eq(DEFAULT_DC_CID),
-                eq(DataService.REQUEST_REASON_NORMAL), any(Message.class));
         verify(mSimulatedCommandsVerifier, times(1))
                 .releasePduSessionId(any(), eq(5));
 
@@ -786,50 +769,6 @@
 
     @Test
     @SmallTest
-    public void testVcnNetworkCapability() throws Exception {
-        mContextFixture.getCarrierConfigBundle().putStringArray(
-                CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
-                new String[] { "default" });
-        doReturn(mApn2).when(mApnContext).getApnSetting();
-
-        doAnswer(invocation -> {
-            NetworkCapabilities nc = invocation.getArgument(0);
-            NetworkCapabilities policyNc = new NetworkCapabilities.Builder(nc)
-                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                    .build();
-
-            return new VcnNetworkPolicyResult(
-                    false /* isTearDownRequested */, policyNc);
-        }).when(mVcnManager).applyVcnNetworkPolicy(any(), any());
-        connectEvent(true);
-
-        assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
-                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED));
-        assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
-                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED));
-
-        disconnectEvent();
-
-        doAnswer(invocation -> {
-            NetworkCapabilities nc = invocation.getArgument(0);
-            NetworkCapabilities policyNc = new NetworkCapabilities.Builder(nc)
-                    .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED)
-                    .build();
-
-            return new VcnNetworkPolicyResult(
-                    false /* isTearDownRequested */, policyNc);
-        }).when(mVcnManager).applyVcnNetworkPolicy(any(), any());
-        connectEvent(true);
-
-        assertFalse("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
-                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VCN_MANAGED));
-        assertTrue("capabilities: " + getNetworkCapabilities(), getNetworkCapabilities()
-                .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED));
-    }
-
-    @Test
-    @SmallTest
     public void testEnterpriseNetworkCapability() throws Exception {
         mContextFixture.getCarrierConfigBundle().putStringArray(
                 CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
@@ -944,40 +883,6 @@
     }
 
     @Test
-    public void testOwnerUid() throws Exception {
-        Context mockContext = mContextFixture.getTestDouble();
-        doReturn(mockContext).when(mPhone).getContext();
-
-        String testPkg = "com.android.telephony.test";
-        TelephonyManager telMgr = mockContext.getSystemService(TelephonyManager.class);
-        doReturn(testPkg).when(telMgr).getCarrierServicePackageNameForLogicalSlot(anyInt());
-
-        UserInfo info = new UserInfo(0 /* id */, "TEST_USER", 0 /* flags */);
-        UserManager userMgr = mockContext.getSystemService(UserManager.class);
-        doReturn(Collections.singletonList(info)).when(userMgr).getUsers();
-
-        int carrierConfigPkgUid = 12345;
-        PackageManager pkgMgr = mockContext.getPackageManager();
-        doReturn(carrierConfigPkgUid).when(pkgMgr).getPackageUidAsUser(eq(testPkg), anyInt());
-
-        mContextFixture
-                .getCarrierConfigBundle()
-                .putStringArray(
-                        CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
-                        new String[] {"default"});
-        testConnectEvent();
-        AsyncResult adminUidsResult = new AsyncResult(null, new int[] {carrierConfigPkgUid}, null);
-        mDc.sendMessage(DataConnection.EVENT_CARRIER_PRIVILEGED_UIDS_CHANGED, adminUidsResult);
-        // Wait for carirer privilege UIDs to be updated
-        waitForMs(100);
-
-        assertEquals(carrierConfigPkgUid, getNetworkCapabilities().getOwnerUid());
-        assertEquals(
-                Collections.singleton(carrierConfigPkgUid),
-                getNetworkCapabilities().getAllowedUids());
-    }
-
-    @Test
     public void testSubscriptionIds() throws Exception {
         mContextFixture.getCarrierConfigBundle().putStringArray(
                 CarrierConfigManager.KEY_CARRIER_METERED_APN_TYPES_STRINGS,
@@ -1282,8 +1187,7 @@
         if (useCondensedFlow) {
             // Indicate in the response that the keepalive has failed.
             AsyncResult.forMessage(
-                    kaStarted, new KeepaliveStatus(KeepaliveStatus.ERROR_UNSUPPORTED),
-                    null);
+                    kaStarted, new KeepaliveStatus(KeepaliveStatus.ERROR_UNSUPPORTED), null);
             kaStarted.sendToTarget();
         } else {
             // Indicate that the keepalive is queued, and then signal a failure from the modem
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataEnabledOverrideTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledOverrideTest.java
similarity index 99%
rename from tests/telephonytests/src/com/android/internal/telephony/data/DataEnabledOverrideTest.java
rename to tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledOverrideTest.java
index 252274c..3d0a4e0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataEnabledOverrideTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledOverrideTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony.dataconnection;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledSettingsTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledSettingsTest.java
index ffe4542..08fa5b6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledSettingsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataEnabledSettingsTest.java
@@ -64,7 +64,7 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        doReturn(false).when(mPhone).isUsingNewDataStack();
+
         doReturn(mRules).when(mSubscriptionController).getDataEnabledOverrideRules(anyInt());
 
         doAnswer(invocation -> {
@@ -82,10 +82,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mDataEnabledSettingsTestHandler.quit();
-        mDataEnabledSettingsTestHandler.join();
-        mDataEnabledSettingsTestHandler = null;
-        mDataEnabledSettingsUT = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/DataFailCauseTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataFailCauseTest.java
similarity index 98%
rename from tests/telephonytests/src/com/android/internal/telephony/data/DataFailCauseTest.java
rename to tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataFailCauseTest.java
index 3590ae6..24d9bd6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/DataFailCauseTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataFailCauseTest.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony.dataconnection;
 
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
@@ -153,8 +153,6 @@
     @After
     public void tearDown() throws Exception {
         mPersistableBundle = null;
-        mFailCauseDataList.clear();
-        mFailCauseDataList = null;
         super.tearDown();
     }
 
@@ -184,8 +182,8 @@
         for (int i = 0; i < 2; i++) {
             for (DcFailCauseData data : mFailCauseDataList) {
                 if (DataFailCause.getFailCause(data.mCause) == (
-                        DataFailCause.SERVICE_OPTION_NOT_SUBSCRIBED)
-                        || DataFailCause.getFailCause(data.mCause) == (
+                        DataFailCause.SERVICE_OPTION_NOT_SUBSCRIBED) ||
+                        DataFailCause.getFailCause(data.mCause) == (
                                 DataFailCause.TETHERED_CALL_ACTIVE)) {
                     assertTrue("cause = " + data.mCause,
                             DataFailCause.isPermanentFailure(mContext,
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataProfileTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataProfileTest.java
new file mode 100644
index 0000000..b641ecd
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataProfileTest.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2010 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.dataconnection;
+
+import android.telephony.data.ApnSetting;
+import android.telephony.data.DataProfile;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.internal.telephony.RILConstants;
+
+import junit.framework.TestCase;
+
+public class DataProfileTest extends TestCase {
+
+    private ApnSetting mApn1 = ApnSetting.makeApnSetting(
+            2163,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "fake_apn",             // apn
+            null,                     // proxy
+            -1,                     // port
+            null,                     // mmsc
+            null,                     // mmsproxy
+            -1,                     // mmsport
+            "user",                 // user
+            "passwd",               // password
+            -1,                     // authtype
+            ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL,     // types
+            ApnSetting.PROTOCOL_IPV6,                 // protocol
+            ApnSetting.PROTOCOL_IP,                   // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            1234,                   // profile_id
+            false,                  // modem_cognitive
+            321,                    // max_conns
+            456,                    // wait_time
+            789,                    // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "");                    // mnvo_match_data
+
+    private ApnSetting mApn2 = ApnSetting.makeApnSetting(
+            2163,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "fake_apn",             // apn
+            null,                     // proxy
+            -1,                     // port
+            null,                     // mmsc
+            null,                     // mmsproxy
+            -1,                     // mmsport
+            "user",                 // user
+            "passwd",               // password
+            -1,                     // authtype
+            ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL,     // types
+            ApnSetting.PROTOCOL_IP,                 // protocol
+            ApnSetting.PROTOCOL_IP,                   // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            1234,                   // profile_id
+            false,                  // modem_cognitive
+            111,                    // max_conns
+            456,                    // wait_time
+            789,                    // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "");                    // mnvo_match_data
+
+    private ApnSetting mApn3 = ApnSetting.makeApnSetting(
+            2163,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "fake_apn",             // apn
+            null,                     // proxy
+            -1,                     // port
+            null,                     // mmsc
+            null,                     // mmsproxy
+            -1,                     // mmsport
+            "user",                 // user
+            "passwd",               // password
+            -1,                     // authtype
+            ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL,     // types
+            ApnSetting.PROTOCOL_IP,                 // protocol
+            ApnSetting.PROTOCOL_IP,                   // roaming_protocol
+            true,                   // carrier_enabled
+            276600,                      // networktype_bitmask
+            1234,                   // profile_id
+            false,                  // modem_cognitive
+            111,                    // max_conns
+            456,                    // wait_time
+            789,                    // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "");                    // mnvo_match_data
+
+    private ApnSetting mApn4 = ApnSetting.makeApnSetting(
+            2163,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "fake_apn",             // apn
+            null,                   // proxy
+            -1,                     // port
+            null,                   // mmsc
+            null,                   // mmsproxy
+            -1,                     // mmsport
+            "user",                 // user
+            "passwd",               // password
+            -1,                     // authtype
+            ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL,   // types
+            ApnSetting.PROTOCOL_IP,                 // protocol
+            ApnSetting.PROTOCOL_IP,                 // roaming_protocol
+            true,                   // carrier_enabled
+            10360,                  // networktype_bitmask
+            1234,                   // profile_id
+            false,                  // modem_cognitive
+            111,                    // max_conns
+            456,                    // wait_time
+            789,                    // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "");                    // mnvo_match_data
+
+    @SmallTest
+    public void testCreateFromApnSetting() throws Exception {
+        DataProfile dp = DcTracker.createDataProfile(mApn1, mApn1.getProfileId(), false);
+        assertEquals(mApn1.getProfileId(), dp.getProfileId());
+        assertEquals(mApn1.getApnName(), dp.getApn());
+        assertEquals(mApn1.getProtocol(), dp.getProtocolType());
+        assertEquals(RILConstants.SETUP_DATA_AUTH_PAP_CHAP, dp.getAuthType());
+        assertEquals(mApn1.getUser(), dp.getUserName());
+        assertEquals(mApn1.getPassword(), dp.getPassword());
+        assertEquals(0, dp.getType());  // TYPE_COMMON
+        assertEquals(mApn1.getWaitTime(), dp.getWaitTime());
+        assertEquals(mApn1.isEnabled(), dp.isEnabled());
+        assertFalse(dp.isPersistent());
+        assertFalse(dp.isPreferred());
+    }
+
+    @SmallTest
+    public void testCreateFromApnSettingWithNetworkTypeBitmask() throws Exception {
+        DataProfile dp = DcTracker.createDataProfile(mApn3, mApn3.getProfileId(), false);
+        assertEquals(mApn3.getProfileId(), dp.getProfileId());
+        assertEquals(mApn3.getApnName(), dp.getApn());
+        assertEquals(mApn3.getProtocol(), dp.getProtocolType());
+        assertEquals(RILConstants.SETUP_DATA_AUTH_PAP_CHAP, dp.getAuthType());
+        assertEquals(mApn3.getUser(), dp.getUserName());
+        assertEquals(mApn3.getPassword(), dp.getPassword());
+        assertEquals(0, dp.getType());  // TYPE_COMMON
+        assertEquals(mApn3.getWaitTime(), dp.getWaitTime());
+        assertEquals(mApn3.isEnabled(), dp.isEnabled());
+        int expectedBearerBitmap = mApn3.getNetworkTypeBitmask();
+        assertEquals(expectedBearerBitmap, dp.getBearerBitmask());
+        dp = DcTracker.createDataProfile(mApn4, mApn4.getProfileId(), false);
+        assertEquals(2, dp.getType());  // TYPE_3GPP2
+    }
+
+    @SmallTest
+    public void testEquals() throws Exception {
+        DataProfile dp1 = DcTracker.createDataProfile(mApn1, mApn1.getProfileId(), false);
+        DataProfile dp2 = DcTracker.createDataProfile(mApn1, mApn1.getProfileId(), false);
+        assertEquals(dp1, dp2);
+
+        dp2 = DcTracker.createDataProfile(mApn2, mApn2.getProfileId(), false);
+        assertFalse(dp1.equals(dp2));
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataThrottlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataThrottlerTest.java
index d03bc8c..fb9a8b6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataThrottlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DataThrottlerTest.java
@@ -20,8 +20,6 @@
 import static com.android.internal.telephony.dataconnection.DcTracker.REQUEST_TYPE_NORMAL;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -40,6 +38,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
 import java.util.Comparator;
@@ -55,23 +54,23 @@
     private static final boolean DBG = true;
     private DataThrottler mDataThrottler;
 
-    // Mocked classes
+    @Mock
     private DataThrottler.Callback mMockChangedCallback1;
+
+    @Mock
     private DataThrottler.Callback mMockChangedCallback2;
 
+    private static final int DEFAULT_APN_TYPE = ApnSetting.TYPE_DEFAULT & ~(ApnSetting.TYPE_HIPRI);
+
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mMockChangedCallback1 = mock(DataThrottler.Callback.class);
-        mMockChangedCallback2 = mock(DataThrottler.Callback.class);
         mDataThrottler = new DataThrottler(mPhone, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
         mDataThrottler.registerForThrottleStatusChanges(mMockChangedCallback1);
-        doReturn(false).when(mPhone).isUsingNewDataStack();
     }
 
     @After
     public void tearDown() throws Exception {
-        mDataThrottler = null;
         super.tearDown();
     }
 
@@ -98,9 +97,16 @@
         processAllMessages();
         expectedStatuses.add(List.of(
                 new ThrottleStatus.Builder()
+                        .setSlotIndex(0)
+                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                        .setApnType(ApnSetting.TYPE_HIPRI)
+                        .setThrottleExpiryTimeMillis(1234567890L)
+                        .setRetryType(ThrottleStatus.RETRY_TYPE_NEW_CONNECTION)
+                        .build(),
+                new ThrottleStatus.Builder()
                     .setSlotIndex(0)
                     .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                    .setApnType(ApnSetting.TYPE_DEFAULT)
+                    .setApnType(DEFAULT_APN_TYPE)
                     .setThrottleExpiryTimeMillis(1234567890L)
                     .setRetryType(ThrottleStatus.RETRY_TYPE_NEW_CONNECTION)
                     .build())
@@ -118,6 +124,13 @@
                 new ThrottleStatus.Builder()
                         .setSlotIndex(0)
                         .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
+                        .setApnType(ApnSetting.TYPE_HIPRI)
+                        .setThrottleExpiryTimeMillis(13579L)
+                        .setRetryType(ThrottleStatus.RETRY_TYPE_HANDOVER)
+                        .build(),
+                new ThrottleStatus.Builder()
+                        .setSlotIndex(0)
+                        .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                         .setApnType(ApnSetting.TYPE_DUN)
                         .setThrottleExpiryTimeMillis(13579L)
                         .setRetryType(ThrottleStatus.RETRY_TYPE_HANDOVER)
@@ -125,7 +138,7 @@
                 new ThrottleStatus.Builder()
                         .setSlotIndex(0)
                         .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
-                        .setApnType(ApnSetting.TYPE_DEFAULT)
+                        .setApnType(DEFAULT_APN_TYPE)
                         .setThrottleExpiryTimeMillis(13579L)
                         .setRetryType(ThrottleStatus.RETRY_TYPE_HANDOVER)
                         .build())
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
index bddfdb4..003f74e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcControllerTest.java
@@ -23,11 +23,11 @@
 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_PCSCF_ADDRESS;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -48,13 +48,17 @@
 import com.android.internal.telephony.DctConstants;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.dataconnection.DataConnection.UpdateLinkPropertyResult;
+import com.android.internal.util.IState;
+import com.android.internal.util.StateMachine;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
@@ -67,30 +71,39 @@
     private static final int DATA_CONNECTION_ACTIVE_PH_LINK_ACTIVE = 2;
 
     private static final int EVENT_DATA_STATE_CHANGED = 0x00040007;
-    private static final int EVENT_PHYSICAL_LINK_STATUS_CHANGED = 1;
+    private static final int EVENT_PHYSICAL_LINK_STATE_CHANGED = 1;
 
-    // Mocked classes
-    private List<ApnContext> mApnContexts;
+    @Mock
     private DataConnection mDc;
+    @Mock
+    private List<ApnContext> mApnContexts;
+    @Mock
     private DataServiceManager mDataServiceManager;
+    @Mock
     private Handler mTestHandler;
 
     UpdateLinkPropertyResult mResult;
 
     private DcController mDcc;
 
+    private IState getCurrentState() {
+        try {
+            Method method = StateMachine.class.getDeclaredMethod("getCurrentState");
+            method.setAccessible(true);
+            return (IState) method.invoke(mDcc);
+        } catch (Exception e) {
+            fail(e.toString());
+            return null;
+        }
+    }
+
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mApnContexts = mock(List.class);
-        mDc = mock(DataConnection.class);
-        mDataServiceManager = mock(DataServiceManager.class);
-        mTestHandler = mock(Handler.class);
 
         doReturn("fake.action_detached").when(mPhone).getActionDetached();
         doReturn(1).when(mApnContexts).size();
         doReturn(mApnContexts).when(mDc).getApnContexts();
-        doReturn(false).when(mPhone).isUsingNewDataStack();
 
         LinkProperties lp = new LinkProperties();
         mResult = new UpdateLinkPropertyResult(lp);
@@ -105,9 +118,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mDcc.removeCallbacksAndMessages(null);
-        mDcc = null;
-        mResult = null;
         super.tearDown();
     }
 
@@ -145,7 +155,7 @@
 
     @Test
     @SmallTest
-    public void testPhysicalLinkStatusChanged_defaultApnTypeAndDormant_registrantNotifyResult()
+    public void testPhysicalLinkStateChanged_defaultApnTypeAndDormant_registrantNotifyResult()
             throws Exception {
         ArrayList<DataCallResponse> l = new ArrayList<>();
         DataCallResponse dcResponse = new DataCallResponse.Builder()
@@ -172,7 +182,7 @@
         apnContextList.add(apnContext);
         doReturn(apnContextList).when(mDc).getApnContexts();
         doReturn(true).when(mDcTracker).getLteEndcUsingUserDataForIdleDetection();
-        mDcc.registerForPhysicalLinkStatusChanged(mTestHandler, EVENT_PHYSICAL_LINK_STATUS_CHANGED);
+        mDcc.registerForPhysicalLinkStateChanged(mTestHandler, EVENT_PHYSICAL_LINK_STATE_CHANGED);
 
         mDcc.sendMessage(mDcc.obtainMessage(EVENT_DATA_STATE_CHANGED,
                 new AsyncResult(null, l, null)));
@@ -181,16 +191,16 @@
         ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
         verify(mTestHandler, times(1)).sendMessageDelayed(messageCaptor.capture(), anyLong());
         Message message = messageCaptor.getValue();
-        assertEquals(EVENT_PHYSICAL_LINK_STATUS_CHANGED, message.what);
+        assertEquals(EVENT_PHYSICAL_LINK_STATE_CHANGED, message.what);
         AsyncResult ar = (AsyncResult) message.obj;
-        assertEquals(DataCallResponse.LINK_STATUS_DORMANT, (int) ar.result);
+        assertEquals(DcController.PHYSICAL_LINK_NOT_ACTIVE, (int) ar.result);
     }
 
     @Test
     @SmallTest
-    public void testPhysicalLinkStatusChanged_imsApnTypeAndDormant_NoNotifyResult()
+    public void testPhysicalLinkStateChanged_imsApnTypeAndDormant_NoNotifyResult()
             throws Exception {
-        testPhysicalLinkStatusChanged_defaultApnTypeAndDormant_registrantNotifyResult();
+        testPhysicalLinkStateChanged_defaultApnTypeAndDormant_registrantNotifyResult();
 
         ArrayList<DataCallResponse> l = new ArrayList<>();
         DataCallResponse dcResponse = new DataCallResponse.Builder()
@@ -228,9 +238,9 @@
 
     @Test
     @SmallTest
-    public void testPhysicalLinkStatusChanged_defaultApnTypeAndStateChanged_registrantNotifyResult()
+    public void testPhysicalLinkStateChanged_defaultApnTypeAndStateChanged_registrantNotifyResult()
             throws Exception {
-        testPhysicalLinkStatusChanged_imsApnTypeAndDormant_NoNotifyResult();
+        testPhysicalLinkStateChanged_imsApnTypeAndDormant_NoNotifyResult();
 
         ArrayList<DataCallResponse> l = new ArrayList<>();
         DataCallResponse dcResponse = new DataCallResponse.Builder()
@@ -265,8 +275,8 @@
         ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
         verify(mTestHandler, times(2)).sendMessageDelayed(messageCaptor.capture(), anyLong());
         Message message = messageCaptor.getValue();
-        assertEquals(EVENT_PHYSICAL_LINK_STATUS_CHANGED, message.what);
+        assertEquals(EVENT_PHYSICAL_LINK_STATE_CHANGED, message.what);
         AsyncResult ar = (AsyncResult) message.obj;
-        assertEquals(DataCallResponse.LINK_STATUS_ACTIVE, (int) ar.result);
+        assertEquals(DcController.PHYSICAL_LINK_ACTIVE, (int) ar.result);
     }
 }
\ No newline at end of file
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcNetworkAgentTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcNetworkAgentTest.java
deleted file mode 100644
index 78438e4..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcNetworkAgentTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.dataconnection;
-
-import static junit.framework.Assert.assertEquals;
-
-import static org.mockito.Mockito.doReturn;
-
-import android.net.ConnectivityManager;
-import android.net.LinkProperties;
-import android.net.NetworkAgent;
-import android.net.NetworkAgentConfig;
-import android.net.NetworkInfo;
-import android.net.NetworkProvider;
-import android.os.Looper;
-import android.telephony.AccessNetworkConstants;
-import android.telephony.TelephonyManager;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import com.android.internal.telephony.TelephonyTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mockito;
-
-import java.lang.reflect.Field;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class DcNetworkAgentTest extends TelephonyTest {
-
-    private DcNetworkAgent mDcNetworkAgent;
-    private DataConnection mDc;
-    private DcController mDcc;
-    private DcFailBringUp mDcFailBringUp;
-
-    private DataServiceManager mDataServiceManager;
-    private DcTesterFailBringUpAll mDcTesterFailBringUpAll;
-    private NetworkProvider mNetworkProvider;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        logd("+Setup!");
-        if (Looper.myLooper() == null) {
-            Looper.prepare();
-        }
-
-        doReturn(false).when(mPhone).isUsingNewDataStack();
-        mDataServiceManager = Mockito.mock(DataServiceManager.class);
-        mDcTesterFailBringUpAll = Mockito.mock(DcTesterFailBringUpAll.class);
-        mNetworkProvider = Mockito.mock(NetworkProvider.class);
-
-        final NetworkAgentConfig.Builder configBuilder = new NetworkAgentConfig.Builder();
-        configBuilder.setLegacyType(ConnectivityManager.TYPE_MOBILE);
-        configBuilder.setLegacyTypeName("MOBILE");
-        configBuilder.setLegacySubType(TelephonyManager.NETWORK_TYPE_LTE);
-        configBuilder.setLegacySubTypeName("LTE");
-        configBuilder.setLegacyExtraInfo("apn");
-
-        doReturn("fake.action_detached").when(mPhone).getActionDetached();
-        mDcFailBringUp = new DcFailBringUp();
-        mDcFailBringUp.saveParameters(0, 0, -2);
-        doReturn(mDcFailBringUp).when(mDcTesterFailBringUpAll).getDcFailBringUp();
-
-        mDcc = DcController.makeDcc(mPhone, mDcTracker, mDataServiceManager, Looper.myLooper(),
-                "");
-        mDc = DataConnection.makeDataConnection(mPhone, 0, mDcTracker, mDataServiceManager,
-                mDcTesterFailBringUpAll, mDcc);
-
-        LinkProperties linkProperties = new LinkProperties();
-        linkProperties.setInterfaceName("fake_iface");
-        Field field = DataConnection.class.getDeclaredField("mLinkProperties");
-        field.setAccessible(true);
-        field.set(mDc, linkProperties);
-
-        mDcNetworkAgent = new DcNetworkAgent(mDc, mPhone, 45, configBuilder.build(),
-                mNetworkProvider, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-        logd("-Setup!");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    private void verifyDisconnected() throws Exception {
-        Field field = NetworkAgent.class.getDeclaredField("mNetworkInfo");
-        field.setAccessible(true);
-        NetworkInfo networkInfo = (NetworkInfo) field.get(mDcNetworkAgent);
-        assertEquals(NetworkInfo.DetailedState.DISCONNECTED, networkInfo.getDetailedState());
-    }
-
-    @Test
-    public void testUnwantedTimeout() throws Exception {
-        mDcNetworkAgent.markConnected();
-        mDcNetworkAgent.onNetworkUnwanted();
-        processAllFutureMessages();
-        verifyDisconnected();
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcRequestTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcRequestTest.java
index b08a680..108f87b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcRequestTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcRequestTest.java
@@ -18,8 +18,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.net.NetworkCapabilities;
@@ -32,76 +30,79 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
+
 
 public class DcRequestTest extends TelephonyTest {
-    NetworkRequest mNetworkRequest;
 
-    // Mocked classes
+    @Mock
     ApnConfigTypeRepository mApnConfigTypeRepo;
 
     @Before
     public void setUp() throws Exception {
-        mApnConfigTypeRepo = mock(ApnConfigTypeRepository.class);
         super.setUp(getClass().getSimpleName());
-        doReturn(false).when(mPhone).isUsingNewDataStack();
     }
 
     @After
     public void tearDown() throws Exception {
-        mNetworkRequest = null;
         super.tearDown();
     }
 
     @Test
     public void whenNetworkRequestInternetThenPriorityZero() {
-        mNetworkRequest = new NetworkRequest.Builder()
-                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .build();
+        NetworkRequest request =
+                new NetworkRequest.Builder()
+                        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+                        .build();
 
         when(mApnConfigTypeRepo.getByType(ApnSetting.TYPE_DEFAULT))
                 .thenReturn(new ApnConfigType(ApnSetting.TYPE_DEFAULT, 0));
-        DcRequest dcRequest = DcRequest.create(mNetworkRequest, mApnConfigTypeRepo);
+        DcRequest dcRequest = DcRequest.create(request, mApnConfigTypeRepo);
 
         assertEquals(0, dcRequest.priority);
     }
 
     @Test
     public void whenNetworkRequestMcxThenApnConfigTypeMcxPriorityReturned() {
-        mNetworkRequest = new NetworkRequest.Builder()
-                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
-                //Testing out multiple transport types here
-                .addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_MCX)
-                .build();
+        NetworkRequest request =
+                new NetworkRequest.Builder()
+                        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+                        //Testing out multiple transport types here
+                        .addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH)
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_MCX)
+                        .build();
 
         when(mApnConfigTypeRepo.getByType(ApnSetting.TYPE_MCX))
                 .thenReturn(new ApnConfigType(ApnSetting.TYPE_MCX, 21));
-        DcRequest dcRequest = DcRequest.create(mNetworkRequest, mApnConfigTypeRepo);
+        DcRequest dcRequest = DcRequest.create(request, mApnConfigTypeRepo);
         assertEquals(21, dcRequest.priority);
     }
 
     @Test
     public void whenNetworkRequestNotCellularThenDcRequestIsNull() {
-        mNetworkRequest = new NetworkRequest.Builder()
-                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_MCX)
-                .build();
-        when(mApnConfigTypeRepo.getByType(ApnSetting.TYPE_NONE)).thenReturn(null);
-        DcRequest dcRequest = DcRequest.create(mNetworkRequest, mApnConfigTypeRepo);
+        NetworkRequest request =
+                new NetworkRequest.Builder()
+                        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_MCX)
+                        .build();
+        when(mApnConfigTypeRepo.getByType(ApnSetting.TYPE_NONE))
+                .thenReturn(null);
+        DcRequest dcRequest = DcRequest.create(request, mApnConfigTypeRepo);
         assertNull(dcRequest);
     }
 
     @Test
     public void whenNetworkRequestHasNoTransportThenPriorityStays() {
         //This seems like an invalid case that should be handled differently.
-        mNetworkRequest = new NetworkRequest.Builder()
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_MCX)
-                .build();
+        NetworkRequest request =
+                new NetworkRequest.Builder()
+                        .addCapability(NetworkCapabilities.NET_CAPABILITY_MCX)
+                        .build();
 
         when(mApnConfigTypeRepo.getByType(ApnSetting.TYPE_MCX))
                 .thenReturn(new ApnConfigType(ApnSetting.TYPE_MCX, 11));
-        DcRequest dcRequest = DcRequest.create(mNetworkRequest, mApnConfigTypeRepo);
+        DcRequest dcRequest = DcRequest.create(request, mApnConfigTypeRepo);
         assertEquals(11, dcRequest.priority);
     }
 
@@ -111,14 +112,16 @@
                 new TelephonyNetworkSpecifier.Builder().setSubscriptionId(5).build();
 
         //This seems like an invalid case that should be handled differently.
-        mNetworkRequest = new NetworkRequest.Builder()
-                .addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH)
-                .setNetworkSpecifier(telephonyNetworkSpecifier)
-                .build();
+        NetworkRequest request =
+                new NetworkRequest.Builder()
+                        .addTransportType(NetworkCapabilities.TRANSPORT_BLUETOOTH)
+                        .setNetworkSpecifier(telephonyNetworkSpecifier)
+                        .build();
 
-        when(mApnConfigTypeRepo.getByType(ApnSetting.TYPE_NONE)).thenReturn(null);
+        when(mApnConfigTypeRepo.getByType(ApnSetting.TYPE_NONE))
+                .thenReturn(null);
 
-        DcRequest dcRequest = DcRequest.create(mNetworkRequest, mApnConfigTypeRepo);
+        DcRequest dcRequest = DcRequest.create(request, mApnConfigTypeRepo);
 
         assertNull(dcRequest);
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
index 549c587..89a59b4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/DcTrackerTest.java
@@ -35,6 +35,7 @@
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -101,7 +102,6 @@
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.RetryManager;
 import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.data.CellularDataService;
 import com.android.internal.telephony.dataconnection.DataConnectionReasons.DataDisallowedReasonType;
 
 import org.junit.After;
@@ -109,7 +109,9 @@
 import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 import java.lang.reflect.Field;
@@ -154,13 +156,19 @@
     private static final String FAKE_PLMN = "44010";
     private static final long TEST_TIMEOUT = 1000;
 
-    // Mocked classes
+    @Mock
     ISub mIsub;
+    @Mock
     IBinder mBinder;
+    @Mock
     SubscriptionInfo mSubscriptionInfo;
+    @Mock
     ApnContext mApnContext;
+    @Mock
     DataConnection mDataConnection;
+    @Mock
     Handler mHandler;
+    @Mock
     NetworkPolicyManager mNetworkPolicyManager;
 
     private DcTracker mDct;
@@ -226,16 +234,12 @@
                 Telephony.Carriers.WAIT_TIME_RETRY,
                 Telephony.Carriers.TIME_LIMIT_FOR_MAX_CONNECTIONS,
                 Telephony.Carriers.MTU,
-                Telephony.Carriers.MTU_V4,
-                Telephony.Carriers.MTU_V6,
                 Telephony.Carriers.MVNO_TYPE,
                 Telephony.Carriers.MVNO_MATCH_DATA,
                 Telephony.Carriers.NETWORK_TYPE_BITMASK,
-                Telephony.Carriers.LINGERING_NETWORK_TYPE_BITMASK,
                 Telephony.Carriers.APN_SET_ID,
                 Telephony.Carriers.CARRIER_ID,
-                Telephony.Carriers.SKIP_464XLAT,
-                Telephony.Carriers.ALWAYS_ON
+                Telephony.Carriers.SKIP_464XLAT
         };
 
         private int mPreferredApnSet = 0;
@@ -296,16 +300,12 @@
                     0,                      // wait_time
                     0,                      // max_conns_time
                     0,                      // mtu
-                    0,                      // mtu_v4
-                    0,                      // mtu_v6
                     "",                     // mvno_type
                     "",                     // mnvo_match_data
                     mFakeApn1Bitmask,       // network_type_bitmask
-                    0,                      // lingering_network_type_bitmask
                     0,                      // apn_set_id
                     -1,                     // carrier_id
-                    -1,                     // skip_464xlat
-                    0                       // always_on
+                    -1                      // skip_464xlat
             };
         }
 
@@ -335,16 +335,12 @@
                     0,                      // wait_time
                     0,                      // max_conns_time
                     0,                      // mtu
-                    0,                      // mtu_v4
-                    0,                      // mtu_v6
                     "",                     // mvno_type
                     "",                     // mnvo_match_data
                     NETWORK_TYPE_LTE_BITMASK, // network_type_bitmask
-                    0,                      // lingering_network_type_bitmask
                     0,                      // apn_set_id
                     -1,                     // carrier_id
-                    -1,                     // skip_464xlat
-                    0                       // always_on
+                    -1                      // skip_464xlat
             };
         }
 
@@ -368,22 +364,18 @@
                     1,                      // carrier_enabled
                     0,                      // bearer
                     0,                      // bearer_bitmask
-                    2,                      // profile_id
+                    0,                      // profile_id
                     1,                      // modem_cognitive
                     0,                      // max_conns
                     0,                      // wait_time
                     0,                      // max_conns_time
                     0,                      // mtu
-                    0,                      // mtu_v4
-                    0,                      // mtu_v6
                     "",                     // mvno_type
                     "",                     // mnvo_match_data
                     0,                      // network_type_bitmask
-                    0,                      // lingering_network_type_bitmask
                     0,                      // apn_set_id
                     -1,                     // carrier_id
-                    -1,                     // skip_464xlat
-                    0                       // always_on
+                    -1                      // skip_464xlat
             };
         }
 
@@ -413,16 +405,12 @@
                     0,                      // wait_time
                     0,                      // max_conns_time
                     0,                      // mtu
-                    0,                      // mtu_v4
-                    0,                      // mtu_v6
                     "",                     // mvno_type
                     "",                     // mnvo_match_data
                     NETWORK_TYPE_EHRPD_BITMASK, // network_type_bitmask
-                    0,                      // lingering_network_type_bitmask
                     0,                      // apn_set_id
                     -1,                     // carrier_id
-                    -1,                     // skip_464xlat
-                    0                       // always_on
+                    -1                      // skip_464xlat
             };
         }
 
@@ -452,16 +440,12 @@
                     0,                      // wait_time
                     0,                      // max_conns_time
                     0,                      // mtu
-                    0,                      // mtu_v4
-                    0,                      // mtu_v6
                     "",                     // mvno_type
                     "",                     // mnvo_match_data
                     0,                      // network_type_bitmask
-                    0,                      // lingering_network_type_bitmask
                     0,                      // apn_set_id
                     -1,                     // carrier_id
-                    -1,                     // skip_464xlat
-                    0                       // always_on
+                    -1                      // skip_464xlat
             };
         }
 
@@ -491,16 +475,12 @@
                     0,                      // wait_time
                     0,                      // max_conns_time
                     0,                      // mtu
-                    0,                      // mtu_v4
-                    0,                      // mtu_v6
                     "",                     // mvno_type
                     "",                     // mnvo_match_data
                     NETWORK_TYPE_LTE_BITMASK, // network_type_bitmask
-                    0,                      // lingering_network_type_bitmask
                     0,                      // apn_set_id
                     -1,                     // carrier_id
-                    -1,                     // skip_464xlat
-                    0                       // always_on
+                    -1                      // skip_464xlat
             };
         }
 
@@ -530,16 +510,12 @@
                     0,                      // wait_time
                     0,                      // max_conns_time
                     0,                      // mtu
-                    0,                      // mtu_v4
-                    0,                      // mtu_v6
                     "",                     // mvno_type
                     "",                     // mnvo_match_data
                     NETWORK_TYPE_LTE_BITMASK,  // network_type_bitmask
-                    0,                      // lingering_network_type_bitmask
                     1,                      // apn_set_id
                     -1,                     // carrier_id
-                    -1,                     // skip_464xlat
-                    0                       // always_on
+                    -1                      // skip_464xlat
             };
         }
 
@@ -563,22 +539,18 @@
                     1,                      // carrier_enabled
                     ServiceState.RIL_RADIO_TECHNOLOGY_LTE, // bearer
                     0,                      // bearer_bitmask
-                    2,                      // profile_id
+                    0,                      // profile_id
                     1,                      // modem_cognitive
                     0,                      // max_conns
                     0,                      // wait_time
                     0,                      // max_conns_time
                     0,                      // mtu
-                    0,                      // mtu_v4
-                    0,                      // mtu_v6
                     "",                     // mvno_type
                     "",                     // mnvo_match_data
-                    NETWORK_TYPE_LTE_BITMASK, // network_type_bitmask
-                    0,                      // lingering_network_type_bitmask
-                    -1,                     // apn_set_id
+                    NETWORK_TYPE_LTE_BITMASK,  // network_type_bitmask
+                    -1,                      // apn_set_id
                     -1,                     // carrier_id
-                    -1,                     // skip_464xlat
-                    0                       // always_on
+                    -1                      // skip_464xlat
             };
         }
 
@@ -608,16 +580,12 @@
                     0,                      // wait_time
                     0,                      // max_conns_time
                     0,                      // mtu
-                    0,                      // mtu_v4
-                    0,                      // mtu_v6
                     "",                     // mvno_type
                     "",                     // mnvo_match_data
                     NETWORK_TYPE_NR_BITMASK, // network_type_bitmask
-                    0,                      // lingering_network_type_bitmask
                     0,                      // apn_set_id
                     -1,                     // carrier_id
-                    -1,                     // skip_464xlat
-                    0                       // always_on
+                    -1                      // skip_464xlat
             };
         }
 
@@ -695,17 +663,9 @@
     public void setUp() throws Exception {
         logd("DcTrackerTest +Setup!");
         super.setUp(getClass().getSimpleName());
-        mIsub = Mockito.mock(ISub.class);
-        mBinder = Mockito.mock(IBinder.class);
-        mSubscriptionInfo = Mockito.mock(SubscriptionInfo.class);
-        mApnContext = Mockito.mock(ApnContext.class);
-        mDataConnection = Mockito.mock(DataConnection.class);
-        mHandler = Mockito.mock(Handler.class);
-        mNetworkPolicyManager = Mockito.mock(NetworkPolicyManager.class);
 
         doReturn("fake.action_detached").when(mPhone).getActionDetached();
         doReturn("fake.action_attached").when(mPhone).getActionAttached();
-        doReturn(false).when(mPhone).isUsingNewDataStack();
         doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_LTE).when(mServiceState)
                 .getRilDataRadioTechnology();
 
@@ -730,17 +690,20 @@
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.DATA_STALL_RECOVERY_ON_BAD_NETWORK, 0);
 
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mAccessNetworksManager)
+        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WWAN).when(mTransportManager)
                 .getPreferredTransport(anyInt());
         doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
         doReturn(true).when(mSST).getDesiredPowerState();
         doReturn(true).when(mSST).getPowerStateFromCarrier();
         doAnswer(
-                (Answer<Void>) invocation -> {
-                    mOnSubscriptionsChangedListener =
-                            (SubscriptionManager.OnSubscriptionsChangedListener)
-                                    invocation.getArguments()[0];
-                    return null;
+                new Answer<Void>() {
+                    @Override
+                    public Void answer(InvocationOnMock invocation) throws Throwable {
+                        mOnSubscriptionsChangedListener =
+                                (SubscriptionManager.OnSubscriptionsChangedListener)
+                                        invocation.getArguments()[0];
+                        return null;
+                    }
                 }
         ).when(mSubscriptionManager).addOnSubscriptionsChangedListener(any());
         doReturn(mSubscriptionInfo).when(mSubscriptionManager).getActiveSubscriptionInfo(anyInt());
@@ -783,12 +746,7 @@
         mDct = null;
         mDcTrackerTestHandler.quit();
         mDcTrackerTestHandler.join();
-        mDcTrackerTestHandler = null;
         mCellularDataService.onDestroy();
-        mCellularDataService = null;
-        mAlarmManager = null;
-        mBundle = null;
-        mCellularDataService = null;
         waitForMs(100);
         super.tearDown();
     }
@@ -1699,7 +1657,7 @@
     @Test
     @SmallTest
     public void testTrySetupDefaultOnIWLAN() {
-        doReturn(true).when(mAccessNetworksManager).isInLegacyMode();
+        doReturn(true).when(mTransportManager).isInLegacyMode();
         initApns(ApnSetting.TYPE_DEFAULT_STRING, new String[]{ApnSetting.TYPE_ALL_STRING});
         mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
                 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN)
@@ -1801,6 +1759,101 @@
         assertTrue(mDct.isAnyDataConnected());
     }
 
+    // Test for fetchDunApns()
+    @Test
+    @SmallTest
+    public void testFetchDunApn() {
+
+        sendInitializationEvents();
+
+        String dunApnString = "[ApnSettingV3]HOT mobile PC,pc.hotm,,,,,,,,,440,10,,DUN,,,true,"
+                + "0,,,,,,,,";
+        ApnSetting dunApnExpected = ApnSetting.fromString(dunApnString);
+
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.TETHER_DUN_APN, dunApnString);
+        // should return APN from Setting
+        ApnSetting dunApn = mDct.fetchDunApns().get(0);
+        assertTrue(dunApnExpected.equals(dunApn));
+
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.TETHER_DUN_APN, null);
+        // should return APN from db
+        dunApn = mDct.fetchDunApns().get(0);
+        assertEquals(FAKE_APN5, dunApn.getApnName());
+    }
+
+    // Test for fetchDunApns() with apn set id
+    @Test
+    @SmallTest
+    public void testFetchDunApnWithPreferredApnSet() {
+        sendCarrierConfigChanged("testFetchDunApnWithPreferredApnSet: ");
+
+        // apnSetId=1
+        String dunApnString1 = "[ApnSettingV5]HOT mobile PC,pc.hotm,,,,,,,,,440,10,,DUN,,,true,"
+                + "0,,,,,,,,,,1";
+        // apnSetId=0
+        String dunApnString2 = "[ApnSettingV5]HOT mobile PC,pc.coldm,,,,,,,,,440,10,,DUN,,,true,"
+                + "0,,,,,,,,,,2";
+
+        ApnSetting dunApnExpected = ApnSetting.fromString(dunApnString1);
+
+        ContentResolver cr = mContext.getContentResolver();
+        Settings.Global.putString(cr, Settings.Global.TETHER_DUN_APN,
+                dunApnString1 + ";" + dunApnString2);
+
+        // set that we prefer apn set 1
+        ContentValues values = new ContentValues();
+        values.put(Telephony.Carriers.APN_SET_ID, 1);
+        cr.update(PREFERAPN_URI, values, null, null);
+
+        // return APN from Setting with apnSetId=1
+        ArrayList<ApnSetting> dunApns = mDct.fetchDunApns();
+        assertEquals(1, dunApns.size());
+        assertEquals(1, dunApns.get(0).getApnSetId());
+        assertTrue(dunApnExpected.equals(dunApns.get(0)));
+
+        // set that we prefer apn set 2
+        values = new ContentValues();
+        values.put(Telephony.Carriers.APN_SET_ID, 2);
+        cr.update(PREFERAPN_URI, values, null, null);
+
+        // return APN from Setting with apnSetId=2
+        dunApns = mDct.fetchDunApns();
+        assertEquals(1, dunApns.size());
+        assertEquals(2, dunApns.get(0).getApnSetId());
+        dunApnExpected = ApnSetting.fromString(dunApnString2);
+        assertTrue(dunApnExpected.equals(dunApns.get(0)));
+    }
+
+    @Test
+    @SmallTest
+    public void testFetchDunApnWhileRoaming() {
+        doReturn(true).when(mServiceState).getRoaming();
+        mBundle.putBoolean(CarrierConfigManager
+                .KEY_DISABLE_DUN_APN_WHILE_ROAMING_WITH_PRESET_APN_BOOL, true);
+
+        sendInitializationEvents();
+
+        String dunApnString = "[ApnSettingV3]HOT mobile PC,pc.hotm,,,,,,,,,440,10,,DUN,,,true,"
+                + "0,,,,,,,,";
+
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.TETHER_DUN_APN, dunApnString);
+
+        DcTracker spyDct = spy(mDct);
+        doReturn(true).when(spyDct).isPreferredApnUserEdited();
+        // Expect non-empty DUN APN list
+        assertEquals(1, spyDct.fetchDunApns().size());
+
+        doReturn(false).when(spyDct).isPreferredApnUserEdited();
+        // Expect empty DUN APN list
+        assertEquals(0, spyDct.fetchDunApns().size());
+
+        Settings.Global.putString(mContext.getContentResolver(),
+                Settings.Global.TETHER_DUN_APN, null);
+    }
+
     /**
      * Test that fetchDunApns() returns list that prioritize the preferred APN when the preferred
      * APN including DUN type.
@@ -2323,8 +2376,6 @@
                 .setDataUsage(500_000_000, System.currentTimeMillis())
                 .build());
         replaceInstance(DcTracker.class, "mSubscriptionPlans", mDct, plans);
-        doReturn(plans.toArray(new SubscriptionPlan[0])).when(mNetworkPolicyManager)
-                .getSubscriptionPlans(anyInt(), any());
     }
 
     private void resetSubscriptionPlans() throws Exception {
@@ -2479,7 +2530,6 @@
                 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA))
                 .when(mDisplayInfoController).getTelephonyDisplayInfo();
         setUpTempNotMetered();
-        clearInvocations(mDataConnection);
 
         // NetCapability should be metered when connected to 5G with no unmetered plan or frequency
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
@@ -2501,12 +2551,11 @@
         intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
         mContext.sendBroadcast(intent);
         waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-        clearInvocations(mDataConnection);
 
         // NetCapability should switch to metered without fr=MMWAVE
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
         waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-        verify(mDataConnection, times(1)).onMeterednessChanged(false);
+        verify(mDataConnection, times(2)).onMeterednessChanged(false);
 
         // NetCapability should switch to unmetered with fr=MMWAVE
         doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
@@ -2514,7 +2563,7 @@
                 .when(mDisplayInfoController).getTelephonyDisplayInfo();
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
         waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-        verify(mDataConnection, times(1)).onMeterednessChanged(true);
+        verify(mDataConnection, times(2)).onMeterednessChanged(true);
 
         resetDataConnection(id);
         resetSubscriptionPlans();
@@ -2530,7 +2579,6 @@
                 TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA))
                 .when(mDisplayInfoController).getTelephonyDisplayInfo();
         setUpTempNotMetered();
-        clearInvocations(mDataConnection);
 
         // NetCapability should be metered when connected to 5G with no unmetered plan or frequency
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
@@ -2545,7 +2593,6 @@
         intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
         mContext.sendBroadcast(intent);
         waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-        clearInvocations(mDataConnection);
 
         // NetCapability should switch to unmetered when fr=MMWAVE and MMWAVE unmetered
         doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
@@ -2561,7 +2608,7 @@
                 .when(mDisplayInfoController).getTelephonyDisplayInfo();
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
         waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-        verify(mDataConnection, times(1)).onMeterednessChanged(false);
+        verify(mDataConnection, times(2)).onMeterednessChanged(false);
 
         // Set SUB6 frequency to unmetered
         doReturn(2).when(mPhone).getSubId();
@@ -2572,14 +2619,13 @@
         intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
         mContext.sendBroadcast(intent);
         waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
-        clearInvocations(mDataConnection);
 
         // NetCapability should switch to unmetered when fr=SUB6 and SUB6 unmetered
         mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_TELEPHONY_DISPLAY_INFO_CHANGED));
         waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
         // Data connection is running on a different thread. Have to wait.
         waitForMs(200);
-        verify(mDataConnection, times(1)).onMeterednessChanged(true);
+        verify(mDataConnection, times(2)).onMeterednessChanged(true);
 
         resetDataConnection(id);
         resetSubscriptionPlans();
@@ -2592,7 +2638,6 @@
         setUpSubscriptionPlans(true);
         setUpWatchdogTimer();
         setUpTempNotMetered();
-        clearInvocations(mDataConnection);
 
         // NetCapability should be unmetered when connected to 5G
         doReturn(new TelephonyDisplayInfo(TelephonyManager.NETWORK_TYPE_LTE,
@@ -2969,7 +3014,7 @@
     @Test
     public void testPreferenceChangedFallback() {
         Handler handler = Mockito.mock(Handler.class);
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
+        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mTransportManager)
                 .getPreferredTransport(anyInt());
         Message handoverCompleteMessage = Message.obtain(handler);
         addHandoverCompleteMsg(handoverCompleteMessage, ApnSetting.TYPE_IMS);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/LinkBandwidthEstimatorTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/LinkBandwidthEstimatorTest.java
similarity index 85%
rename from tests/telephonytests/src/com/android/internal/telephony/data/LinkBandwidthEstimatorTest.java
rename to tests/telephonytests/src/com/android/internal/telephony/dataconnection/LinkBandwidthEstimatorTest.java
index 6cd7542..80fe817 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/LinkBandwidthEstimatorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/LinkBandwidthEstimatorTest.java
@@ -14,29 +14,26 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony.dataconnection;
 
 import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
 
-import static com.android.internal.telephony.data.LinkBandwidthEstimator.BW_STATS_COUNT_THRESHOLD;
-import static com.android.internal.telephony.data.LinkBandwidthEstimator.LINK_RX;
-import static com.android.internal.telephony.data.LinkBandwidthEstimator.LINK_TX;
-import static com.android.internal.telephony.data.LinkBandwidthEstimator.MSG_ACTIVE_PHONE_CHANGED;
-import static com.android.internal.telephony.data.LinkBandwidthEstimator.MSG_DEFAULT_NETWORK_CHANGED;
-import static com.android.internal.telephony.data.LinkBandwidthEstimator.MSG_MODEM_ACTIVITY_RETURNED;
-import static com.android.internal.telephony.data.LinkBandwidthEstimator.MSG_NR_FREQUENCY_CHANGED;
-import static com.android.internal.telephony.data.LinkBandwidthEstimator.MSG_SCREEN_STATE_CHANGED;
-import static com.android.internal.telephony.data.LinkBandwidthEstimator.MSG_SIGNAL_STRENGTH_CHANGED;
-import static com.android.internal.telephony.data.LinkBandwidthEstimator.UNKNOWN_TAC;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.BW_STATS_COUNT_THRESHOLD;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.LINK_RX;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.LINK_TX;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.MSG_ACTIVE_PHONE_CHANGED;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.MSG_DEFAULT_NETWORK_CHANGED;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.MSG_MODEM_ACTIVITY_RETURNED;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.MSG_NR_FREQUENCY_CHANGED;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.MSG_SCREEN_STATE_CHANGED;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.MSG_SIGNAL_STRENGTH_CHANGED;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.UNKNOWN_TAC;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -57,14 +54,13 @@
 
 import com.android.internal.telephony.TelephonyFacade;
 import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.data.LinkBandwidthEstimator.LinkBandwidthEstimatorCallback;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
-import org.mockito.Mockito;
+import org.mockito.Mock;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -86,17 +82,15 @@
     private long mElapsedTimeMs = 0;
     private long mTxBytes = 0;
     private long mRxBytes = 0;
-    private NetworkRegistrationInfo mNri;
-
-    // Mocked classes
+    @Mock
     TelephonyFacade mTelephonyFacade;
+    @Mock
     private Handler mTestHandler;
+    private NetworkRegistrationInfo mNri;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mTelephonyFacade = mock(TelephonyFacade.class);
-        mTestHandler = mock(Handler.class);
         mNetworkCapabilities = new NetworkCapabilities.Builder()
                 .addTransportType(TRANSPORT_CELLULAR)
                 .build();
@@ -111,7 +105,6 @@
         when(mTelephonyFacade.getMobileTxBytes()).thenReturn(0L);
         when(mTelephonyFacade.getMobileTxBytes()).thenReturn(0L);
         when(mPhone.getCurrentCellIdentity()).thenReturn(mCellIdentity);
-        // Note that signal level is 0 before 1st MSG_SIGNAL_STRENGTH_CHANGED
         when(mPhone.getSubId()).thenReturn(1);
         when(mSignalStrength.getDbm()).thenReturn(-100);
         when(mSignalStrength.getLevel()).thenReturn(1);
@@ -145,10 +138,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mLBE = null;
-        mNri = null;
-        mNetworkCapabilities = null;
-        mCellIdentity = null;
         super.tearDown();
     }
 
@@ -341,43 +330,17 @@
 
         verifyUpdateBandwidth(-1, 19_597);
 
-        when(mSignalStrength.getLevel()).thenReturn(1);
+        addTxBytes(20_000L);
+        addRxBytes(50_000L);
         when(mSignalStrength.getDbm()).thenReturn(-110);
         mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
         addElapsedTime(6000);
         moveTimeForward(6000);
         processAllMessages();
-        verifyUpdateBandwidth(-1, 19_535);
 
-        when(mSignalStrength.getLevel()).thenReturn(2);
-        when(mSignalStrength.getDbm()).thenReturn(-90);
-        mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
-        addElapsedTime(6000);
-        moveTimeForward(6000);
-        processAllMessages();
         verifyUpdateBandwidth(-1, -1);
-
-        for (int i = 0; i < BW_STATS_COUNT_THRESHOLD + 2; i++) {
-            addTxBytes(10_000L);
-            addRxBytes(1000_000L);
-            addElapsedTime(5_100);
-            moveTimeForward(5_100);
-            processAllMessages();
-            mLBE.obtainMessage(MSG_MODEM_ACTIVITY_RETURNED, new ModemActivityInfo(
-                    i * 5_100L, 0, 0, TX_TIME_2_MS, i * RX_TIME_2_MS)).sendToTarget();
-            processAllMessages();
-        }
-
-        when(mSignalStrength.getLevel()).thenReturn(1);
-        when(mSignalStrength.getDbm()).thenReturn(-110);
-        mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
-        addElapsedTime(6000);
-        moveTimeForward(6000);
-        processAllMessages();
-        verifyUpdateBandwidth(-1, 30_821);
     }
 
-
     @Test
     public void testAvgBwForAllPossibleRat() throws Exception {
         Pair<Integer, Integer> values = mLBE.getStaticAvgBw(TelephonyManager.NETWORK_TYPE_GPRS);
@@ -438,6 +401,7 @@
         addRxBytes(19_000L);
         when(mServiceState.getNrState()).thenReturn(NetworkRegistrationInfo.NR_STATE_CONNECTED);
         when(mServiceState.getNrFrequencyRange()).thenReturn(ServiceState.FREQUENCY_RANGE_MMWAVE);
+        when(mSignalStrength.getLevel()).thenReturn(2);
         mLBE.obtainMessage(MSG_NR_FREQUENCY_CHANGED).sendToTarget();
         addElapsedTime(6000);
         moveTimeForward(6000);
@@ -670,7 +634,7 @@
 
 
     @Test
-    public void testVeryHighRxLinkBandwidthEstimationIgnored() throws Exception {
+    public void testVeryHighByteCountReturnNonNegativeValue() throws Exception {
         mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
         processAllMessages();
         mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
@@ -686,48 +650,11 @@
             processAllMessages();
         }
 
-        // This will result in link bandwidth estimation value 128Gbps which is too high for LTE.
-        // So it will be ignored by the estimator.
         LinkBandwidthEstimator.NetworkBandwidth network = mLBE.lookupNetwork("310260", 366, "LTE");
 
-        assertEquals(0, network.getCount(LINK_RX, 1));
+        assertEquals(BW_STATS_COUNT_THRESHOLD + 4, network.getCount(LINK_RX, 1));
         assertEquals(0, network.getValue(LINK_TX, 1));
-        assertEquals(0, network.getValue(LINK_RX, 1));
-    }
-
-    @Test
-    public void testDataActivity() {
-        LinkBandwidthEstimatorCallback callback = Mockito.mock(
-                LinkBandwidthEstimatorCallback.class);
-        doAnswer(invocation -> {
-            ((Runnable) invocation.getArguments()[0]).run();
-            return null;
-        }).when(callback).invokeFromExecutor(any(Runnable.class));
-        mLBE.registerCallback(callback);
-
-        mLBE.obtainMessage(MSG_SCREEN_STATE_CHANGED, true).sendToTarget();
-        addTxBytes(10_000L);
-        addRxBytes(19_000L);
-        addElapsedTime(2000);
-        moveTimeForward(2000);
-        processAllMessages();
-        verify(callback).onDataActivityChanged(eq(TelephonyManager.DATA_ACTIVITY_INOUT));
-        Mockito.clearInvocations(callback);
-
-        mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
-        addTxBytes(10_000L);
-        addElapsedTime(2000);
-        moveTimeForward(2000);
-        processAllMessages();
-        verify(callback).onDataActivityChanged(eq(TelephonyManager.DATA_ACTIVITY_OUT));
-        Mockito.clearInvocations(callback);
-
-        mLBE.obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, mSignalStrength).sendToTarget();
-        addRxBytes(10_000L);
-        addElapsedTime(2000);
-        moveTimeForward(2000);
-        processAllMessages();
-        verify(callback).onDataActivityChanged(eq(TelephonyManager.DATA_ACTIVITY_IN));
-        Mockito.clearInvocations(callback);
+        assertEquals(16_000_000_000L * 8 / 1024 * (BW_STATS_COUNT_THRESHOLD + 4),
+                network.getValue(LINK_RX, 1));
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/QosCallbackTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/QosCallbackTrackerTest.java
similarity index 74%
rename from tests/telephonytests/src/com/android/internal/telephony/data/QosCallbackTrackerTest.java
rename to tests/telephonytests/src/com/android/internal/telephony/dataconnection/QosCallbackTrackerTest.java
index 00bca4d..5a8b540 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/QosCallbackTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/QosCallbackTrackerTest.java
@@ -14,10 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony.dataconnection;
 
-import static org.mockito.Mockito.any;
+import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.anyInt;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.mock;
@@ -30,94 +32,89 @@
 import android.net.InetAddresses;
 import android.net.LinkAddress;
 import android.net.Network;
+import android.net.NetworkAgent;
 import android.telephony.data.EpsBearerQosSessionAttributes;
 import android.telephony.data.EpsQos;
-import android.telephony.data.Qos;
 import android.telephony.data.QosBearerFilter;
 import android.telephony.data.QosBearerSession;
+
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
-import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.metrics.RcsStats;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
+import java.lang.reflect.Field;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class QosCallbackTrackerTest extends TelephonyTest {
 
     class Filter implements QosCallbackTracker.IFilter {
-        InetSocketAddress mLocalAddress;
-        InetSocketAddress mRemoteAddress;
+        InetSocketAddress localAddress;
+        InetSocketAddress remoteAddress;
 
         Filter(@NonNull final InetSocketAddress localAddress) {
-            this.mLocalAddress = localAddress;
-            this.mRemoteAddress = null;
+            this.localAddress = localAddress;
+            this.remoteAddress = null;
         }
 
         Filter(@NonNull final InetSocketAddress localAddress,
                 @NonNull final InetSocketAddress remoteAddress) {
-            this.mLocalAddress = localAddress;
-            this.mRemoteAddress = remoteAddress;
+            this.localAddress = localAddress;
+            this.remoteAddress = remoteAddress;
         }
 
-        public boolean matchesLocalAddress(final @NonNull InetAddress address,
-                final int startPort, final int endPort) {
-            return startPort <= mLocalAddress.getPort()
-                    && endPort >= mLocalAddress.getPort()
-                    && mLocalAddress.getAddress().equals(address);
+        public boolean matchesLocalAddress(@NonNull final InetAddress address,
+            final int startPort, final int endPort) {
+                return startPort <= localAddress.getPort()
+                    && endPort >= localAddress.getPort()
+                    && localAddress.getAddress().equals(address);
         }
 
-        public boolean matchesRemoteAddress(final @NonNull InetAddress address,
-                final int startPort, final int endPort) {
-            return mRemoteAddress != null
-                    && startPort <= mRemoteAddress.getPort()
-                    && endPort >= mRemoteAddress.getPort()
-                    && mRemoteAddress.getAddress().equals(address);
+        public boolean matchesRemoteAddress(@NonNull final InetAddress address,
+            final int startPort, final int endPort) {
+                return remoteAddress != null
+                    && startPort <= remoteAddress.getPort()
+                    && endPort >= remoteAddress.getPort()
+                    && remoteAddress.getAddress().equals(address);
         }
     }
 
-    // Mocked classes
-    private Phone mPhone;
-    private TelephonyNetworkAgent mNetworkAgent;
+    @Mock
+    private DcNetworkAgent mDcNetworkAgent;
+    @Mock
     private Network mNetwork;
-    private RcsStats mRcsStats;
 
     private QosCallbackTracker mQosCallbackTracker;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mPhone = mock(Phone.class);
-        mNetworkAgent = mock(TelephonyNetworkAgent.class);
-        mNetwork = mock(Network.class);
-        mRcsStats = mock(RcsStats.class);
-        doReturn(mNetwork).when(mNetworkAgent).getNetwork();
+        doReturn(mNetwork).when(mDcNetworkAgent).getNetwork();
         doReturn(100).when(mNetwork).getNetId();
-        doReturn(0).when(mPhone).getPhoneId();
-        mQosCallbackTracker = new QosCallbackTracker(mNetworkAgent, mPhone);
-        replaceInstance(QosCallbackTracker.class, "mRcsStats", mQosCallbackTracker, mRcsStats);
+        mQosCallbackTracker = new QosCallbackTracker(mDcNetworkAgent);
         processAllMessages();
     }
 
     @After
     public void tearDown() throws Exception {
-        mQosCallbackTracker = null;
         super.tearDown();
     }
 
-    public static EpsQos createEpsQos(int dlMbr, int ulMbr, int dlGbr, int ulGbr) {
+    private EpsQos createEpsQos(int dlMbr, int ulMbr, int dlGbr, int ulGbr) {
         // Build android.hardware.radio.V1_6.EpsQos
         android.hardware.radio.V1_6.EpsQos halEpsQos = new android.hardware.radio.V1_6.EpsQos();
         halEpsQos.qci = 4;
@@ -126,20 +123,19 @@
         halEpsQos.uplink.maxBitrateKbps = ulMbr;
         halEpsQos.uplink.guaranteedBitrateKbps = ulGbr;
 
-        return new EpsQos(
-                new Qos.QosBandwidth(dlMbr, dlGbr), new Qos.QosBandwidth(ulMbr, ulGbr), 4);
+        return new EpsQos(halEpsQos);
     }
 
-    public static QosBearerFilter createIpv4QosFilter(String localAddress,
+    private QosBearerFilter createIpv4QosFilter(String localAddress,
             QosBearerFilter.PortRange localPort, int precedence) {
         return new QosBearerFilter(
                 Arrays.asList(
                         new LinkAddress(InetAddresses.parseNumericAddress(localAddress), 32)),
-                new ArrayList<>(), localPort, null, QosBearerFilter.QOS_PROTOCOL_TCP,
+                new ArrayList<LinkAddress>(), localPort, null, QosBearerFilter.QOS_PROTOCOL_TCP,
                 7, 987, 678, QosBearerFilter.QOS_FILTER_DIRECTION_BIDIRECTIONAL, precedence);
     }
 
-    private static QosBearerFilter createIpv4QosFilter(String localAddress, String remoteAddress,
+    private QosBearerFilter createIpv4QosFilter(String localAddress, String remoteAddress,
             QosBearerFilter.PortRange localPort, QosBearerFilter.PortRange remotePort,
             int precedence) {
         return new QosBearerFilter(
@@ -168,9 +164,8 @@
         qosSessions.add(new QosBearerSession(1234, createEpsQos(5, 6, 7, 8), qosFilters1));
 
         mQosCallbackTracker.updateSessions(qosSessions);
-        processAllMessages();
 
-        verify(mNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
+        verify(mDcNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
                 eq(1234), any(EpsBearerQosSessionAttributes.class));
 
         // Matching QosBearerFilter
@@ -180,9 +175,8 @@
         qosSessions.add(new QosBearerSession(1235, createEpsQos(5, 6, 7, 8), qosFilters2));
 
         mQosCallbackTracker.updateSessions(qosSessions);
-        processAllMessages();
 
-        verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
                 eq(1235), any(EpsBearerQosSessionAttributes.class));
 
     }
@@ -211,9 +205,8 @@
         Filter filter = new Filter(new InetSocketAddress(
                 InetAddresses.parseNumericAddress("122.22.22.22"), 2222));
         mQosCallbackTracker.addFilter(1, filter);
-        processAllMessages();
 
-        verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
                 eq(1235), any(EpsBearerQosSessionAttributes.class));
 
     }
@@ -235,9 +228,8 @@
         qosSessions.add(new QosBearerSession(1234, createEpsQos(5, 6, 7, 8), qosFilters1));
 
         mQosCallbackTracker.updateSessions(qosSessions);
-        processAllMessages();
 
-        verify(mNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
+        verify(mDcNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
                 eq(1234), any(EpsBearerQosSessionAttributes.class));
 
         // Remove the filter
@@ -250,10 +242,9 @@
         qosSessions.add(new QosBearerSession(1235, createEpsQos(5, 6, 7, 8), qosFilters2));
 
         mQosCallbackTracker.updateSessions(qosSessions);
-        processAllMessages();
 
         // Verify that notifyQosSessionAvailable is not invoked as the filter is already removed
-        verify(mNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
+        verify(mDcNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
                 eq(1235), any(EpsBearerQosSessionAttributes.class));
 
     }
@@ -278,24 +269,21 @@
         qosSessions.add(new QosBearerSession(1235, createEpsQos(5, 6, 7, 8), qosFilters2));
 
         mQosCallbackTracker.updateSessions(qosSessions);
-        processAllMessages();
 
         // Add filter after updateSessions
         Filter filter = new Filter(new InetSocketAddress(
                 InetAddresses.parseNumericAddress("122.22.22.22"), 2222),
                 new InetSocketAddress(InetAddresses.parseNumericAddress("144.44.44.44"), 2223));
         mQosCallbackTracker.addFilter(1, filter);
-        processAllMessages();
 
-        verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
                 eq(1235), any(EpsBearerQosSessionAttributes.class));
 
         // Remove the matching QosBearerFilter
         qosSessions.remove(1);
         mQosCallbackTracker.updateSessions(qosSessions);
-        processAllMessages();
 
-        verify(mNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1235), eq(1));
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1235), eq(1));
     }
 
     @Test
@@ -324,20 +312,18 @@
                 InetAddresses.parseNumericAddress("122.22.22.22"), 2222),
                 new InetSocketAddress(InetAddresses.parseNumericAddress("144.44.44.44"), 2223));
         mQosCallbackTracker.addFilter(1, filter);
-        processAllMessages();
 
-        verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
                 eq(1235), any(EpsBearerQosSessionAttributes.class));
 
-        reset(mNetworkAgent);
+        reset(mDcNetworkAgent);
 
         // Update the QOS
         qosSessions.remove(1);
         qosSessions.add(new QosBearerSession(1235, createEpsQos(10, 12, 14, 16), qosFilters2));
         mQosCallbackTracker.updateSessions(qosSessions);
-        processAllMessages();
 
-        verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
                 eq(1235), any(EpsBearerQosSessionAttributes.class));
     }
 
@@ -367,20 +353,18 @@
                 InetAddresses.parseNumericAddress("122.22.22.22"), 2222),
                 new InetSocketAddress(InetAddresses.parseNumericAddress("144.44.44.44"), 2223));
         mQosCallbackTracker.addFilter(1, filter);
-        processAllMessages();
 
-        verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
                 eq(1235), any(EpsBearerQosSessionAttributes.class));
 
-        reset(mNetworkAgent);
+        reset(mDcNetworkAgent);
 
         // Update the same QOS
         qosSessions.remove(1);
         qosSessions.add(new QosBearerSession(1235, createEpsQos(5, 6, 7, 8), qosFilters2));
         mQosCallbackTracker.updateSessions(qosSessions);
-        processAllMessages();
 
-        verify(mNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
+        verify(mDcNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
                 eq(1235), any(EpsBearerQosSessionAttributes.class));
     }
 
@@ -416,19 +400,17 @@
                 InetAddresses.parseNumericAddress("122.22.22.22"), 2222),
                 new InetSocketAddress(InetAddresses.parseNumericAddress("144.44.44.44"), 2223));
         mQosCallbackTracker.addFilter(2, filter2);
-        processAllMessages();
 
-        verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
                 eq(1234), any(EpsBearerQosSessionAttributes.class));
-        verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(2),
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionAvailable(eq(2),
                 eq(1235), any(EpsBearerQosSessionAttributes.class));
 
         // Update empty QOS sessions list
         mQosCallbackTracker.updateSessions(new ArrayList<>());
-        processAllMessages();
 
-        verify(mNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1234), eq(1));
-        verify(mNetworkAgent, times(1)).notifyQosSessionLost(eq(2), eq(1235), eq(1));
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1234), eq(1));
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(2), eq(1235), eq(1));
     }
 
     @Test
@@ -463,19 +445,17 @@
         qosSessions.add(new QosBearerSession(1235, createEpsQos(7, 8, 9, 10), qosFilters2));
 
         mQosCallbackTracker.updateSessions(qosSessions);
-        processAllMessages();
 
-        verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionAvailable(eq(1),
                 eq(1234), any(EpsBearerQosSessionAttributes.class));
-        verify(mNetworkAgent, times(1)).notifyQosSessionAvailable(eq(2),
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionAvailable(eq(2),
                 eq(1235), any(EpsBearerQosSessionAttributes.class));
 
         // Update empty QOS sessions list
         mQosCallbackTracker.updateSessions(new ArrayList<>());
-        processAllMessages();
 
-        verify(mNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1234), eq(1));
-        verify(mNetworkAgent, times(1)).notifyQosSessionLost(eq(2), eq(1235), eq(1));
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(1), eq(1234), eq(1));
+        verify(mDcNetworkAgent, times(1)).notifyQosSessionLost(eq(2), eq(1235), eq(1));
     }
 
     @Test
@@ -484,7 +464,7 @@
         // Non-matching QosBearerFilter
         ArrayList<QosBearerFilter> qosFilters1 = new ArrayList<>();
         qosFilters1.add(createIpv4QosFilter("155.55.55.55",
-                new QosBearerFilter.PortRange(0, 0), 45));
+                new QosBearerFilter.PortRange(0,0), 45));
 
         ArrayList<QosBearerSession> qosSessions = new ArrayList<>();
         qosSessions.add(new QosBearerSession(1234, createEpsQos(5, 6, 7, 8), qosFilters1));
@@ -501,52 +481,10 @@
         Filter filter = new Filter(new InetSocketAddress(
                 InetAddresses.parseNumericAddress("122.22.22.22"), 2222));
         mQosCallbackTracker.addFilter(1, filter);
-        processAllMessages();
 
-        verify(mNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
+        verify(mDcNetworkAgent, never()).notifyQosSessionAvailable(eq(1),
                 eq(1235), any(EpsBearerQosSessionAttributes.class));
 
     }
-
-    @Test
-    @SmallTest
-    public void testQosMetrics() throws Exception {
-        final int callbackId = 1;
-        final int slotId = mPhone.getPhoneId();
-        // Add filter before update session
-        Filter filter1 = new Filter(new InetSocketAddress(
-                InetAddresses.parseNumericAddress("155.55.55.55"), 2222),
-                new InetSocketAddress(InetAddresses.parseNumericAddress("144.44.44.44"), 2223));
-
-        mQosCallbackTracker.addFilter(callbackId, filter1);
-        processAllMessages();
-        verify(mRcsStats, never()).onImsDedicatedBearerListenerAdded(eq(callbackId), eq(slotId),
-                anyInt(), anyInt());
-
-        // QosBearerFilter
-        ArrayList<QosBearerFilter> qosFilters1 = new ArrayList<>();
-        qosFilters1.add(createIpv4QosFilter("155.55.55.55", "144.44.44.44",
-                new QosBearerFilter.PortRange(2222, 2222),
-                new QosBearerFilter.PortRange(2223, 2223), 45));
-
-        ArrayList<QosBearerSession> qosSessions = new ArrayList<>();
-        qosSessions.add(new QosBearerSession(1234, createEpsQos(5, 6, 7, 8), qosFilters1));
-        mQosCallbackTracker.updateSessions(qosSessions);
-        processAllMessages();
-
-        verify(mRcsStats, times(1))
-                .onImsDedicatedBearerListenerUpdateSession(
-                        eq(callbackId), eq(slotId), anyInt(), anyInt(), eq(true));
-
-        mQosCallbackTracker.addFilter(callbackId, filter1);
-        processAllMessages();
-        verify(mRcsStats, times(1)).onImsDedicatedBearerListenerAdded(
-                anyInt(), anyInt(), anyInt(), anyInt());
-
-        mQosCallbackTracker.removeFilter(callbackId);
-        processAllMessages();
-        verify(mRcsStats, times(1))
-                .onImsDedicatedBearerListenerRemoved(callbackId);
-    }
 }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java
index 4acfefb..159e204 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java
@@ -44,38 +44,86 @@
 public class RetryManagerTest extends TelephonyTest {
 
     // This is the real APN data for the Japanese carrier NTT Docomo.
-    private final ApnSetting mApn1 = new ApnSetting.Builder()
-            .setId(2163)
-            .setOperatorNumeric("44010")
-            .setEntryName("sp-mode")
-            .setApnName("spmode.ne.jp")
-            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
-            .setProtocol(ApnSetting.PROTOCOL_IP)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .build();
+    private ApnSetting mApn1 = ApnSetting.makeApnSetting(
+            2163,                   // id
+            "44010",                // numeric
+            "sp-mode",              // name
+            "spmode.ne.jp",         // apn
+            null,                     // proxy
+            -1,                     // port
+            null,                     // mmsc
+            null,                     // mmsproxy
+            -1,                     // mmsport
+            "",                     // user
+            "",                     // password
+            -1,                     // authtype
+            ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL, // types
+            ApnSetting.PROTOCOL_IP, // protocol
+            ApnSetting.PROTOCOL_IP, // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            0,                      // profile_id
+            false,                  // modem_cognitive
+            0,                      // max_conns
+            0,                      // wait_time
+            0,                      // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "");                    // mnvo_match_data
 
-    private final ApnSetting mApn2 = new ApnSetting.Builder()
-            .setId(2164)
-            .setOperatorNumeric("44010")
-            .setEntryName("mopera U")
-            .setApnName("mopera.net")
-            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
-            .setProtocol(ApnSetting.PROTOCOL_IP)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .build();
+    private ApnSetting mApn2 = ApnSetting.makeApnSetting(
+            2164,                   // id
+            "44010",                // numeric
+            "mopera U",             // name
+            "mopera.net",           // apn
+            null,                     // proxy
+            -1,                     // port
+            null,                     // mmsc
+            null,                     // mmsproxy
+            -1,                     // mmsport
+            "",                     // user
+            "",                     // password
+            -1,                     // authtype
+            ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL,     // types
+            ApnSetting.PROTOCOL_IP,                   // protocol
+            ApnSetting.PROTOCOL_IP,                   // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            0,                      // profile_id
+            false,                  // modem_cognitive
+            0,                      // max_conns
+            0,                      // wait_time
+            0,                      // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "");                    // mnvo_match_data
 
-    private final ApnSetting mApn3 = new ApnSetting.Builder()
-            .setId(2165)
-            .setOperatorNumeric("44010")
-            .setEntryName("b-mobile for Nexus")
-            .setApnName("bmobile.ne.jp")
-            .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL)
-            .setProtocol(ApnSetting.PROTOCOL_IP)
-            .setRoamingProtocol(ApnSetting.PROTOCOL_IP)
-            .setCarrierEnabled(true)
-            .build();
+    private ApnSetting mApn3 = ApnSetting.makeApnSetting(
+            2165,                   // id
+            "44010",                // numeric
+            "b-mobile for Nexus",   // name
+            "bmobile.ne.jp",        // apn
+            null,                     // proxy
+            -1,                     // port
+            null,                     // mmsc
+            null,                     // mmsproxy
+            -1,                     // mmsport
+            "",                     // user
+            "",                     // password
+            3,                      // authtype
+            ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_SUPL,     // types
+            ApnSetting.PROTOCOL_IP,                   // protocol
+            ApnSetting.PROTOCOL_IP,                   // roaming_protocol
+            true,                   // carrier_enabled
+            0,                      // networktype_bitmask
+            0,                      // profile_id
+            false,                  // modem_cognitive
+            0,                      // max_conns
+            0,                      // wait_time
+            0,                      // max_conns_time
+            0,                      // mtu
+            -1,                     // mvno_type
+            "");                    // mnvo_match_data
 
     private PersistableBundle mBundle;
 
@@ -83,14 +131,13 @@
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
         mBundle = mContextFixture.getCarrierConfigBundle();
-        doReturn(false).when(mPhone).isUsingNewDataStack();
+
         replaceInstance(SubscriptionController.class, "sInstance", null, mSubscriptionController);
         replaceInstance(UiccController.class, "mInstance", null, mUiccController);
     }
 
     @After
     public void tearDown() throws Exception {
-        mBundle = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
similarity index 82%
rename from tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java
rename to tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
index d109ee9..30bd8b2 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/data/TelephonyNetworkFactoryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TelephonyNetworkFactoryTest.java
@@ -14,10 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.internal.telephony.data;
+package com.android.internal.telephony.dataconnection;
 
 import static com.android.internal.telephony.NetworkFactory.CMD_CANCEL_REQUEST;
 import static com.android.internal.telephony.NetworkFactory.CMD_REQUEST_NETWORK;
+import static com.android.internal.telephony.dataconnection.TelephonyNetworkFactory.EVENT_ACTIVE_PHONE_SWITCH;
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
@@ -47,9 +48,9 @@
 
 import androidx.test.filters.FlakyTest;
 
+import com.android.internal.telephony.PhoneSwitcher;
 import com.android.internal.telephony.RadioConfig;
 import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.dataconnection.DataConnection;
 import com.android.internal.telephony.dataconnection.TransportManager.HandoverParams;
 import com.android.internal.telephony.dataconnection.TransportManager.HandoverParams.HandoverCallback;
 import com.android.telephony.Rlog;
@@ -59,6 +60,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 import org.mockito.Mockito;
 
 import java.lang.reflect.Field;
@@ -69,21 +71,24 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class TelephonyNetworkFactoryTest extends TelephonyTest {
-    private static final String LOG_TAG = "TelephonyNetworkFactoryTest";
+    private final static String LOG_TAG = "TelephonyNetworkFactoryTest";
 
-    // Mocked classes
+    @Mock
     PhoneSwitcher mPhoneSwitcher;
+    @Mock
     private RadioConfig mMockRadioConfig;
+
+    @Mock
     private DataConnection mDataConnection;
 
     private String mTestName = "";
 
     // List of all requests filed by a test
-    private final ArraySet<TelephonyNetworkRequest> mAllNetworkRequestSet = new ArraySet<>();
+    private final ArraySet<NetworkRequest> mAllNetworkRequestSet = new ArraySet<>();
     // List of requests active in DcTracker
-    private final ArrayList<TelephonyNetworkRequest> mNetworkRequestList = new ArrayList<>();
+    private final ArrayList<NetworkRequest> mNetworkRequestList = new ArrayList<>();
     // List of complete messages associated with the network requests
-    private final Map<TelephonyNetworkRequest, Message> mNetworkRequestMessageMap = new HashMap<>();
+    private final Map<NetworkRequest, Message> mNetworkRequestMessageMap = new HashMap<>();
 
     private TelephonyNetworkFactory mTelephonyNetworkFactoryUT;
     private int mRequestId = 0;
@@ -93,10 +98,10 @@
     }
 
     private NetworkRequest makeSubSpecificInternetRequest(int subId) {
-        NetworkCapabilities netCap = (new NetworkCapabilities())
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+        NetworkCapabilities netCap = (new NetworkCapabilities()).
+                addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).
+                addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED).
+                addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
         netCap.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
                 .setSubscriptionId(subId).build());
         NetworkRequest networkRequest = new NetworkRequest(netCap, -1,
@@ -119,10 +124,10 @@
     }
 
     private NetworkRequest makeSubSpecificMmsRequest(int subId) {
-        NetworkCapabilities netCap = (new NetworkCapabilities())
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_MMS)
-                .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
-                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+        NetworkCapabilities netCap = (new NetworkCapabilities()).
+                addCapability(NetworkCapabilities.NET_CAPABILITY_MMS).
+                addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED).
+                addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
         netCap.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
                 .setSubscriptionId(subId).build());
         NetworkRequest networkRequest = new NetworkRequest(netCap, -1,
@@ -139,24 +144,17 @@
 
     private void activatePhoneInPhoneSwitcher(int phoneId, boolean active) {
         doReturn(active).when(mPhoneSwitcher).shouldApplyNetworkRequest(any(), eq(phoneId));
-        mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
-                TelephonyNetworkFactory.EVENT_ACTIVE_PHONE_SWITCH);
+        mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(EVENT_ACTIVE_PHONE_SWITCH);
     }
 
     private void activatePhoneInPhoneSwitcher(int phoneId, NetworkRequest nr, boolean active) {
-        TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(nr, mPhone);
-        doReturn(active).when(mPhoneSwitcher).shouldApplyNetworkRequest(
-                eq(networkRequest), eq(phoneId));
-        mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
-                TelephonyNetworkFactory.EVENT_ACTIVE_PHONE_SWITCH);
+        doReturn(active).when(mPhoneSwitcher).shouldApplyNetworkRequest(eq(nr), eq(phoneId));
+        mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(EVENT_ACTIVE_PHONE_SWITCH);
     }
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mPhoneSwitcher = mock(PhoneSwitcher.class);
-        mMockRadioConfig = mock(RadioConfig.class);
-        mDataConnection = mock(DataConnection.class);
         replaceInstance(RadioConfig.class, "sRadioConfig", null, mMockRadioConfig);
 
         mContextFixture.putStringArrayResource(com.android.internal.R.array.networkAttributes,
@@ -168,27 +166,22 @@
                         "mobile_ia,14,0,2,-1,true", "mobile_emergency,15,0,2,-1,true"});
 
         doAnswer(invocation -> {
-            final TelephonyNetworkRequest req =
-                    (TelephonyNetworkRequest) invocation.getArguments()[0];
-            //final Message msg = (Message) invocation.getArguments()[2];
+            final NetworkRequest req = (NetworkRequest) invocation.getArguments()[0];
+            final Message msg = (Message) invocation.getArguments()[2];
             mNetworkRequestList.add(req);
             mAllNetworkRequestSet.add(req);
-            //mNetworkRequestMessageMap.put(req, msg);
+            mNetworkRequestMessageMap.put(req, msg);
             return null;
-        }).when(mDataNetworkController).addNetworkRequest(any());
+        }).when(mDcTracker).requestNetwork(any(), anyInt(), any());
 
         doAnswer(invocation -> {
-            mNetworkRequestList.remove((TelephonyNetworkRequest) invocation.getArguments()[0]);
+            mNetworkRequestList.remove((NetworkRequest) invocation.getArguments()[0]);
             return null;
-        }).when(mDataNetworkController).removeNetworkRequest(any());
+        }).when(mDcTracker).releaseNetwork(any(), anyInt());
     }
 
     @After
     public void tearDown() throws Exception {
-        mAllNetworkRequestSet.clear();
-        mNetworkRequestList.clear();
-        mNetworkRequestMessageMap.clear();
-        mTelephonyNetworkFactoryUT = null;
         super.tearDown();
     }
 
@@ -219,11 +212,10 @@
             final NetworkCapabilities capabilitiesFilter =
                     mTelephonyNetworkFactoryUT.makeNetworkFilter(
                             mSubscriptionController.getSubIdUsingPhoneId(0));
-            for (final TelephonyNetworkRequest request : mAllNetworkRequestSet) {
+            for (final NetworkRequest request : mAllNetworkRequestSet) {
                 final int message = request.canBeSatisfiedBy(capabilitiesFilter)
                         ? CMD_REQUEST_NETWORK : CMD_CANCEL_REQUEST;
-                mTelephonyNetworkFactoryUT.obtainMessage(message, 0, 0,
-                        request.getNativeNetworkRequest()).sendToTarget();
+                mTelephonyNetworkFactoryUT.obtainMessage(message, 0, 0, request).sendToTarget();
             }
             return null;
         }).when(mConnectivityManager).offerNetwork(anyInt(), any(), any(), any());
@@ -335,8 +327,7 @@
         assertEquals(1, mNetworkRequestList.size());
 
         activatePhoneInPhoneSwitcher(phoneId, false);
-        mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
-                TelephonyNetworkFactory.EVENT_ACTIVE_PHONE_SWITCH);
+        mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(EVENT_ACTIVE_PHONE_SWITCH);
         processAllMessages();
         assertEquals(0, mNetworkRequestList.size());
 
@@ -394,7 +385,7 @@
         h.sendMessage(h.obtainMessage(5, ar));
         processAllMessages();
 
-        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mAccessNetworksManager)
+        doReturn(AccessNetworkConstants.TRANSPORT_TYPE_WLAN).when(mTransportManager)
                 .getCurrentTransport(anyInt());
 
         hp = new HandoverParams(ApnSetting.TYPE_MMS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
@@ -426,7 +417,7 @@
         Handler h = (Handler) f.get(mTelephonyNetworkFactoryUT);
 
         HandoverCallback handoverCallback = mock(HandoverCallback.class);
-        Mockito.reset(mDataNetworkController);
+        Mockito.reset(mDcTracker);
         doReturn(mDataConnection).when(mDcTracker).getDataConnectionByApnType(anyString());
         doReturn(false).when(mDataConnection).isActive();
 
@@ -436,7 +427,44 @@
         h.sendMessage(h.obtainMessage(5, ar));
         processAllMessages();
 
-        verify(mDataNetworkController, times(1)).removeNetworkRequest(any());
-        verify(mDataNetworkController, times(1)).addNetworkRequest(any());
+        verify(mDcTracker, times(1)).releaseNetwork(any(), eq(1));
+        verify(mDcTracker, times(1)).requestNetwork(any(), eq(1), any());
+    }
+
+    @Test
+    @SmallTest
+    public void testNetworkRequestReleasedDuringHandover() throws Exception {
+        createMockedTelephonyComponents();
+        doReturn(0).when(mSubscriptionController).getSubIdUsingPhoneId(0);
+        mTelephonyNetworkFactoryUT.mInternalHandler.sendEmptyMessage(
+                TelephonyNetworkFactory.EVENT_SUBSCRIPTION_CHANGED);
+
+        activatePhoneInPhoneSwitcher(0, true);
+        makeDefaultInternetRequest();
+
+        NetworkRequest mmsNetworkRequest = makeSubSpecificMmsRequest(0);
+        processAllMessages();
+
+        Field f = TelephonyNetworkFactory.class.getDeclaredField("mInternalHandler");
+        f.setAccessible(true);
+        Handler h = (Handler) f.get(mTelephonyNetworkFactoryUT);
+
+        HandoverCallback handoverCallback = mock(HandoverCallback.class);
+        //Mockito.reset(mDcTracker);
+        doReturn(mDataConnection).when(mDcTracker).getDataConnectionByApnType(anyString());
+        doReturn(true).when(mDataConnection).isActive();
+
+        HandoverParams hp = new HandoverParams(ApnSetting.TYPE_MMS,
+                AccessNetworkConstants.TRANSPORT_TYPE_WLAN, handoverCallback);
+        AsyncResult ar = new AsyncResult(null, hp, null);
+        h.sendMessage(h.obtainMessage(5 /* EVENT_DATA_HANDOVER_NEEDED */, ar));
+        processAllMessages();
+
+        // Now release the network request while handover is still ongoing.
+        mTelephonyNetworkFactoryUT.releaseNetworkFor(mmsNetworkRequest);
+        processAllMessages();
+
+        // Ensure the release is called one more time after the normal release
+        verify(mDcTracker, times(2)).releaseNetwork(any(), eq(1));
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TransportManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TransportManagerTest.java
new file mode 100644
index 0000000..1e79ae1
--- /dev/null
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/TransportManagerTest.java
@@ -0,0 +1,256 @@
+/*
+ * 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.dataconnection;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.os.AsyncResult;
+import android.os.Handler;
+import android.os.Message;
+import android.telephony.AccessNetworkConstants;
+import android.telephony.AccessNetworkConstants.AccessNetworkType;
+import android.telephony.data.ApnSetting;
+import android.test.suitebuilder.annotation.SmallTest;
+import android.testing.AndroidTestingRunner;
+import android.testing.TestableLooper;
+
+import com.android.internal.telephony.TelephonyTest;
+import com.android.internal.telephony.dataconnection.AccessNetworksManager.QualifiedNetworks;
+import com.android.internal.telephony.dataconnection.TransportManager.HandoverParams;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+
+import java.lang.reflect.Field;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+@RunWith(AndroidTestingRunner.class)
+@TestableLooper.RunWithLooper
+public class TransportManagerTest extends TelephonyTest {
+    private static final int EVENT_HANDOVER_NEEDED = 1;
+
+    @Mock
+    private Handler mTestHandler;
+
+    private TransportManager mTransportManager;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp(getClass().getSimpleName());
+        mTransportManager = new TransportManager(mPhone);
+        processAllMessages();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    @Test
+    @SmallTest
+    public void testHandoverNeeded() throws Exception {
+        mTransportManager.registerForHandoverNeededEvent(mTestHandler, EVENT_HANDOVER_NEEDED);
+
+        // Initial qualified networks
+        List<QualifiedNetworks> networkList = new ArrayList<>(Arrays.asList(
+                new QualifiedNetworks(ApnSetting.TYPE_IMS,
+                        new int[]{AccessNetworkType.EUTRAN, AccessNetworkType.UTRAN,
+                                AccessNetworkType.IWLAN})));
+        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
+                new AsyncResult(null, networkList, null)).sendToTarget();
+        processAllMessages();
+        // Verify handover needed event was not sent
+        verify(mTestHandler, never()).sendMessageAtTime(any(Message.class), anyLong());
+
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                mTransportManager.getCurrentTransport(ApnSetting.TYPE_IMS));
+
+        // Now change the order of qualified networks by putting IWLAN first
+        networkList = new ArrayList<>(Arrays.asList(
+                new QualifiedNetworks(ApnSetting.TYPE_IMS,
+                        new int[]{AccessNetworkType.IWLAN, AccessNetworkType.UTRAN,
+                                AccessNetworkType.EUTRAN})));
+        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
+                new AsyncResult(null, networkList, null)).sendToTarget();
+        processAllMessages();
+
+        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
+
+        // Verify handover needed event was sent and the the target transport is WLAN.
+        verify(mTestHandler, times(1)).sendMessageAtTime(messageArgumentCaptor.capture(),
+                anyLong());
+        Message message = messageArgumentCaptor.getValue();
+        assertEquals(EVENT_HANDOVER_NEEDED, message.what);
+        AsyncResult ar = (AsyncResult) message.obj;
+        HandoverParams params = (HandoverParams) ar.result;
+        assertEquals(ApnSetting.TYPE_IMS, params.apnType);
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, params.targetTransport);
+
+        // Notify handover succeeded.
+        params.callback.onCompleted(true, false);
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
+                mTransportManager.getCurrentTransport(ApnSetting.TYPE_IMS));
+
+        // Now change the order of qualified networks by putting UTRAN first
+        networkList = new ArrayList<>(Arrays.asList(
+                new QualifiedNetworks(ApnSetting.TYPE_IMS,
+                        new int[]{AccessNetworkType.UTRAN, AccessNetworkType.EUTRAN,
+                                AccessNetworkType.IWLAN})));
+        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
+                new AsyncResult(null, networkList, null)).sendToTarget();
+        processAllMessages();
+
+        messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
+
+        // Verify handover needed event was sent and the the target transport is WWAN.
+        verify(mTestHandler, times(2)).sendMessageAtTime(messageArgumentCaptor.capture(),
+                anyLong());
+        message = messageArgumentCaptor.getValue();
+        assertEquals(EVENT_HANDOVER_NEEDED, message.what);
+        ar = (AsyncResult) message.obj;
+        params = (HandoverParams) ar.result;
+        assertEquals(ApnSetting.TYPE_IMS, params.apnType);
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN, params.targetTransport);
+
+        // The transport should not change before handover complete callback is called.
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
+                mTransportManager.getCurrentTransport(ApnSetting.TYPE_IMS));
+        // Notify handover succeeded.
+        params.callback.onCompleted(true, false);
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                mTransportManager.getCurrentTransport(ApnSetting.TYPE_IMS));
+    }
+
+    @Test
+    @SmallTest
+    public void testHandoverNotNeeded() throws Exception {
+        mTransportManager.registerForHandoverNeededEvent(mTestHandler, EVENT_HANDOVER_NEEDED);
+
+        // Initial qualified networks
+        List<QualifiedNetworks> networkList = new ArrayList<>(Arrays.asList(
+                new QualifiedNetworks(ApnSetting.TYPE_IMS,
+                        new int[]{AccessNetworkType.EUTRAN, AccessNetworkType.UTRAN,
+                                AccessNetworkType.IWLAN})));
+        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
+                new AsyncResult(null, networkList, null)).sendToTarget();
+        processAllMessages();
+        // Verify handover needed event was not sent
+        verify(mTestHandler, never()).sendMessageAtTime(any(Message.class), anyLong());
+
+        // Now change the order of qualified networks by swapping EUTRAN and UTRAN.
+        networkList = new ArrayList<>(Arrays.asList(
+                new QualifiedNetworks(ApnSetting.TYPE_IMS,
+                        new int[]{AccessNetworkType.UTRAN, AccessNetworkType.EUTRAN,
+                                AccessNetworkType.IWLAN})));
+        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
+                new AsyncResult(null, networkList, null)).sendToTarget();
+        processAllMessages();
+        // Verify handover needed event was not sent
+        verify(mTestHandler, never()).sendMessageAtTime(any(Message.class), anyLong());
+    }
+
+    private ArrayDeque<List<QualifiedNetworks>> getQueuedNetworksList() throws Exception {
+        Field f = TransportManager.class.getDeclaredField("mQueuedNetworksList");
+        f.setAccessible(true);
+        return (ArrayDeque<List<QualifiedNetworks>>) f.get(mTransportManager);
+    }
+
+    @Test
+    @SmallTest
+    public void testBackToBackHandoverNeeded() throws Exception {
+        mTransportManager.registerForHandoverNeededEvent(mTestHandler, EVENT_HANDOVER_NEEDED);
+
+        // Initial qualified networks
+        List<QualifiedNetworks> networkList = new ArrayList<>(Arrays.asList(
+                new QualifiedNetworks(ApnSetting.TYPE_IMS,
+                        new int[]{AccessNetworkType.EUTRAN, AccessNetworkType.UTRAN,
+                                AccessNetworkType.IWLAN})));
+        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
+                new AsyncResult(null, networkList, null)).sendToTarget();
+        processAllMessages();
+        // Verify handover needed event was not sent
+        verify(mTestHandler, never()).sendMessageAtTime(any(Message.class), anyLong());
+
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
+                mTransportManager.getCurrentTransport(ApnSetting.TYPE_IMS));
+
+        // Now change the order of qualified networks by putting IWLAN first
+        networkList = new ArrayList<>(Arrays.asList(
+                new QualifiedNetworks(ApnSetting.TYPE_IMS,
+                        new int[]{AccessNetworkType.IWLAN, AccessNetworkType.UTRAN,
+                                AccessNetworkType.EUTRAN})));
+        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
+                new AsyncResult(null, networkList, null)).sendToTarget();
+        processAllMessages();
+
+        ArgumentCaptor<Message> messageArgumentCaptor = ArgumentCaptor.forClass(Message.class);
+
+        // Verify handover needed event was sent and the the target transport is WLAN.
+        verify(mTestHandler, times(1)).sendMessageAtTime(messageArgumentCaptor.capture(),
+                anyLong());
+        Message message = messageArgumentCaptor.getValue();
+        assertEquals(EVENT_HANDOVER_NEEDED, message.what);
+        AsyncResult ar = (AsyncResult) message.obj;
+        HandoverParams params = (HandoverParams) ar.result;
+        assertEquals(ApnSetting.TYPE_IMS, params.apnType);
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, params.targetTransport);
+
+        // Before handover is completed, update the available networks again.
+        // This time change the order of qualified networks by putting EUTRAN first
+        networkList = new ArrayList<>(Arrays.asList(
+                new QualifiedNetworks(ApnSetting.TYPE_IMS,
+                        new int[]{AccessNetworkType.EUTRAN, AccessNetworkType.UTRAN,
+                                AccessNetworkType.IWLAN})));
+        mTransportManager.obtainMessage(1 /* EVENT_QUALIFIED_NETWORKS_CHANGED */,
+                new AsyncResult(null, networkList, null)).sendToTarget();
+        processAllMessages();
+
+        // Verify handover needed event was sent only once (for the previous change)
+        verify(mTestHandler, times(1)).sendMessageAtTime(messageArgumentCaptor.capture(),
+                anyLong());
+
+        ArrayDeque<List<QualifiedNetworks>> listQueue = getQueuedNetworksList();
+        // Verify the list has been queued.
+        assertEquals(1, listQueue.size());
+
+        // Notify handover succeeded.
+        params.callback.onCompleted(true, false);
+        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
+                mTransportManager.getCurrentTransport(ApnSetting.TYPE_IMS));
+        processAllMessages();
+
+        listQueue = getQueuedNetworksList();
+        // Verify the queue is empty.
+        assertEquals(0, listQueue.size());
+
+        // Verify handover 2nd needed event was sent
+        verify(mTestHandler, times(2)).sendMessageAtTime(messageArgumentCaptor.capture(),
+                anyLong());
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java
index 39ff133..2aa3f18 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyNumberTrackerTest.java
@@ -19,17 +19,11 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
 
 import android.os.AsyncResult;
 import android.os.Environment;
 import android.os.ParcelFileDescriptor;
-import android.telephony.SubscriptionManager;
 import android.telephony.emergency.EmergencyNumber;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -39,20 +33,17 @@
 import com.android.internal.telephony.HalVersion;
 import com.android.internal.telephony.Phone;
 import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.SubscriptionController;
 import com.android.internal.telephony.TelephonyTest;
 
-import com.google.i18n.phonenumbers.ShortNumberInfo;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 
 import java.io.BufferedInputStream;
 import java.io.File;
 import java.io.FileNotFoundException;
-import java.io.IOException;
 import java.io.InputStream;
 import java.nio.file.Files;
 import java.nio.file.Path;
@@ -75,7 +66,6 @@
     private static final String CONFIG_EMERGENCY_NUMBER_ADDRESS = "54321";
     private static final String CONFIG_EMERGENCY_NUMBER_COUNTRY = "us";
     private static final String CONFIG_EMERGENCY_NUMBER_MNC = "";
-    private static final String NON_3GPP_EMERGENCY_TEST_NUMBER = "9876543";
     private static final int CONFIG_EMERGENCY_NUMBER_SERVICE_CATEGORIES =
             EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_POLICE
                     | EmergencyNumber.EMERGENCY_SERVICE_CATEGORY_AMBULANCE
@@ -94,14 +84,8 @@
                                             EmergencyNumber.EMERGENCY_CALL_ROUTING_UNKNOWN);
     private static final int OTA_UNIT_TEST_EMERGENCY_NUMBER_DB_VERSION = 999999;
     private static final String OTA_EMERGENCY_NUMBER_ADDRESS = "98765";
-    private static final int SUB_ID_PHONE_1 = 1;
-    private static final int SUB_ID_PHONE_2 = 2;
-    private static final int VALID_SLOT_INDEX_VALID_1 = 1;
-    private static final int VALID_SLOT_INDEX_VALID_2 = 2;
-    private static final int INVALID_SLOT_INDEX_VALID = SubscriptionManager.INVALID_SIM_SLOT_INDEX;
-    private ParcelFileDescriptor mOtaPracelFileDescriptor = null;
-    // Mocked classes
-    private SubscriptionController mSubControllerMock;
+
+    @Mock
     private Phone mPhone2; // mPhone as phone 1 is already defined in TelephonyTest.
 
     // mEmergencyNumberTrackerMock for mPhone
@@ -114,24 +98,18 @@
     private String[] mEmergencyNumberPrefixTestSample = {"123", "456"};
 
     private File mLocalDownloadDirectory;
-    private ShortNumberInfo mShortNumberInfo;
 
     @Before
     public void setUp() throws Exception {
         logd("EmergencyNumberTrackerTest +Setup!");
-        super.setUp(getClass().getSimpleName());
-        mShortNumberInfo = mock(ShortNumberInfo.class);
-        mSubControllerMock = mock(SubscriptionController.class);
-        mPhone2 = mock(Phone.class);
+        super.setUp("EmergencyNumberTrackerTest");
         mContext = InstrumentationRegistry.getTargetContext();
 
         doReturn(mContext).when(mPhone).getContext();
         doReturn(0).when(mPhone).getPhoneId();
-        doReturn(SUB_ID_PHONE_1).when(mPhone).getSubId();
 
         doReturn(mContext).when(mPhone2).getContext();
         doReturn(1).when(mPhone2).getPhoneId();
-        doReturn(SUB_ID_PHONE_2).when(mPhone2).getSubId();
 
         initializeEmergencyNumberListTestSamples();
         mEmergencyNumberTrackerMock = new EmergencyNumberTracker(mPhone, mSimulatedCommands);
@@ -153,19 +131,6 @@
         Path target = Paths.get(mLocalDownloadDirectory.getPath(), EMERGENCY_NUMBER_DB_OTA_FILE);
         Files.deleteIfExists(target);
         mLocalDownloadDirectory.delete();
-        mLocalDownloadDirectory = null;
-        mEmergencyNumberTrackerMock = null;
-        mEmergencyNumberTrackerMock2 = null;
-        mEmergencyNumberListTestSample.clear();
-        mEmergencyNumberListTestSample = null;
-        if (mOtaPracelFileDescriptor != null) {
-            try {
-                mOtaPracelFileDescriptor.close();
-                mOtaPracelFileDescriptor = null;
-            } catch (IOException e) {
-                logd("Failed to close emergency number db file folder for testing " + e.toString());
-            }
-        }
         super.tearDown();
     }
 
@@ -192,15 +157,6 @@
         processAllMessages();
     }
 
-    private void sendEmptyEmergencyNumberListFromRadio(
-        EmergencyNumberTracker emergencyNumberTrackerMock) {
-        emergencyNumberTrackerMock.sendMessage(
-            emergencyNumberTrackerMock.obtainMessage(
-                1 /* EVENT_UNSOL_EMERGENCY_NUMBER_LIST */,
-                new AsyncResult(null, new ArrayList<>(), null)));
-        processAllMessages();
-    }
-
     private void cacheEmergencyNumberListFromDatabaseByCountry(String countryIso) {
         mEmergencyNumberTrackerMock.updateEmergencyNumberDatabaseCountryChange(countryIso);
         processAllMessages();
@@ -219,11 +175,11 @@
         File file = new File(Environment.getExternalStorageDirectory(), LOCAL_DOWNLOAD_DIRECTORY
                 + "/" + EMERGENCY_NUMBER_DB_OTA_FILE);
         try {
-            mOtaPracelFileDescriptor = ParcelFileDescriptor.open(
+            final ParcelFileDescriptor otaParcelFileDescriptor = ParcelFileDescriptor.open(
                     file, ParcelFileDescriptor.MODE_READ_ONLY);
             emergencyNumberTrackerMock.obtainMessage(
                 EmergencyNumberTracker.EVENT_OVERRIDE_OTA_EMERGENCY_NUMBER_DB_FILE_PATH,
-                    mOtaPracelFileDescriptor).sendToTarget();
+                otaParcelFileDescriptor).sendToTarget();
             logd("Changed emergency number db file folder for testing ");
         } catch (FileNotFoundException e) {
             logd("Failed to open emergency number db file folder for testing " + e.toString());
@@ -292,36 +248,6 @@
         replaceInstance(PhoneFactory.class, "sPhones", null, mPhones);
     }
 
-    /**
-     * Test EmergencyNumberTracker.isSimAbsent().
-     */
-    @Test
-    public void testIsSimAbsent() throws Exception {
-        setDsdsPhones();
-        replaceInstance(SubscriptionController.class, "sInstance", null, mSubControllerMock);
-
-        // Both sim slots are active
-        doReturn(VALID_SLOT_INDEX_VALID_1).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_1));
-        doReturn(VALID_SLOT_INDEX_VALID_2).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_2));
-        assertFalse(mEmergencyNumberTrackerMock.isSimAbsent());
-
-        // One sim slot is active; the other one is not active
-        doReturn(VALID_SLOT_INDEX_VALID_1).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_1));
-        doReturn(INVALID_SLOT_INDEX_VALID).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_2));
-        assertFalse(mEmergencyNumberTrackerMock.isSimAbsent());
-
-        // Both sim slots are not active
-        doReturn(INVALID_SLOT_INDEX_VALID).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_1));
-        doReturn(INVALID_SLOT_INDEX_VALID).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_2));
-        assertTrue(mEmergencyNumberTrackerMock.isSimAbsent());
-    }
-
     @Test
     public void testEmergencyNumberListFromRadio() throws Exception {
         sendEmergencyNumberListFromRadio();
@@ -366,84 +292,6 @@
     }
 
     @Test
-    public void testIsEmergencyNumber_FallbackToShortNumberXml_NoSims() throws Exception {
-        // Set up the Hal version as 1.4
-        doReturn(new HalVersion(1, 4)).when(mPhone).getHalVersion();
-        doReturn(new HalVersion(1, 4)).when(mPhone2).getHalVersion();
-
-        setDsdsPhones();
-        replaceInstance(SubscriptionController.class, "sInstance", null, mSubControllerMock);
-
-        // Both sim slots are not active
-        doReturn(INVALID_SLOT_INDEX_VALID).when(mSubControllerMock).getSlotIndex(
-            eq(SUB_ID_PHONE_1));
-        doReturn(INVALID_SLOT_INDEX_VALID).when(mSubControllerMock).getSlotIndex(
-            eq(SUB_ID_PHONE_2));
-        assertTrue(mEmergencyNumberTrackerMock.isSimAbsent());
-
-        sendEmptyEmergencyNumberListFromRadio(mEmergencyNumberTrackerMock);
-        sendEmptyEmergencyNumberListFromRadio(mEmergencyNumberTrackerMock2);
-
-        mEmergencyNumberTrackerMock.updateEmergencyCountryIsoAllPhones("JP");
-        processAllMessages();
-
-        replaceInstance(ShortNumberInfo.class, "INSTANCE", null, mShortNumberInfo);
-        mEmergencyNumberTrackerMock.isEmergencyNumber(NON_3GPP_EMERGENCY_TEST_NUMBER, true);
-
-        //verify that we fall back to shortnumber xml when there are no SIMs
-        verify(mShortNumberInfo).isEmergencyNumber(NON_3GPP_EMERGENCY_TEST_NUMBER, "JP");
-    }
-
-    @Test
-    public void testIsEmergencyNumber_NoFallbackToShortNumberXml_OneSimActive() throws Exception {
-        testIsEmergencyNumber_NoFallbackToShortNumberXml(1);
-    }
-
-    @Test
-    public void testIsEmergencyNumber_NoFallbackToShortNumberXml_TwoSimsActive() throws Exception {
-        testIsEmergencyNumber_NoFallbackToShortNumberXml(2);
-    }
-
-    private void testIsEmergencyNumber_NoFallbackToShortNumberXml(int numSims) throws Exception {
-        // Set up the Hal version as 1.4
-        doReturn(new HalVersion(1, 4)).when(mPhone).getHalVersion();
-        doReturn(new HalVersion(1, 4)).when(mPhone2).getHalVersion();
-
-        assertTrue((numSims > 0 && numSims < 3));
-        setDsdsPhones();
-        replaceInstance(SubscriptionController.class, "sInstance", null, mSubControllerMock);
-
-        if (numSims == 1) {
-            // One sim slot is active; the other one is not active
-            doReturn(VALID_SLOT_INDEX_VALID_1).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_1));
-            doReturn(INVALID_SLOT_INDEX_VALID).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_2));
-        } else {
-            //both slots active
-            doReturn(VALID_SLOT_INDEX_VALID_1).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_1));
-            doReturn(VALID_SLOT_INDEX_VALID_2).when(mSubControllerMock).getSlotIndex(
-                eq(SUB_ID_PHONE_2));
-        }
-        assertFalse(mEmergencyNumberTrackerMock.isSimAbsent());
-
-        //still send empty list from modem for both sims, else we always end up using that
-        sendEmptyEmergencyNumberListFromRadio(mEmergencyNumberTrackerMock);
-        sendEmptyEmergencyNumberListFromRadio(mEmergencyNumberTrackerMock2);
-
-        mEmergencyNumberTrackerMock.updateEmergencyCountryIsoAllPhones("JP");
-        processAllMessages();
-
-        replaceInstance(ShortNumberInfo.class, "INSTANCE", null, mShortNumberInfo);
-        mEmergencyNumberTrackerMock.isEmergencyNumber(NON_3GPP_EMERGENCY_TEST_NUMBER, true);
-
-        //verify we do not use ShortNumber xml
-        verify(mShortNumberInfo, never()).isEmergencyNumber(anyString(), anyString());
-
-    }
-
-    @Test
     public void testUpdateEmergencyCountryIsoFromAnotherSimOrNot() throws Exception {
         setDsdsPhones();
         sendEmergencyNumberPrefix(mEmergencyNumberTrackerMock);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccCardControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccCardControllerTest.java
index 242c9f8..770f34a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccCardControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccCardControllerTest.java
@@ -22,7 +22,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.content.Intent;
@@ -43,6 +42,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
@@ -57,26 +58,26 @@
     private int mLastBootCount;
     private EuiccCardController mEuiccCardController;
     private SharedPreferences mSp;
+    @Mock
+    private UiccSlot mInactivatedEsimSlot;
+    @Mock
+    private UiccSlot mActivatedEsimSlot;
+    @Mock
+    private UiccSlot mNotPresentEsimSlot;
+    @Mock
+    private UiccSlot mActivatedRemovableSlot;
+    @Mock
+    private EuiccController mEuiccController;
+    @Mock
+    private UiccController mUiccController;
     private boolean mOtaStarted;
     private CountDownLatch mOtaLatch;
 
-    // Mocked classes
-    private UiccSlot mInactivatedEsimSlot;
-    private UiccSlot mActivatedEsimSlot;
-    private UiccSlot mNotPresentEsimSlot;
-    private UiccSlot mActivatedRemovableSlot;
-    private EuiccController mEuiccController;
-    private UiccController mUiccController;
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mInactivatedEsimSlot = mock(UiccSlot.class);
-        mActivatedEsimSlot = mock(UiccSlot.class);
-        mNotPresentEsimSlot = mock(UiccSlot.class);
-        mActivatedRemovableSlot = mock(UiccSlot.class);
-        mEuiccController = mock(EuiccController.class);
-        mUiccController = mock(UiccController.class);
+        super.setUp("EuiccCardControllerTest");
+        MockitoAnnotations.initMocks(this);
         mSp = PreferenceManager.getDefaultSharedPreferences(mContext);
 
         mLastBootCount = mSp.getInt(KEY_LAST_BOOT_COUNT, -1);
@@ -112,6 +113,7 @@
 
     @After
     public void tearDown() throws Exception {
+        super.tearDown();
         if (mBootCount == -1) {
             Settings.Global.resetToDefaults(mContext.getContentResolver(), KEY_LAST_BOOT_COUNT);
         } else {
@@ -120,9 +122,6 @@
         }
         SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
         sp.edit().putInt(KEY_LAST_BOOT_COUNT, mLastBootCount).apply();
-        mEuiccCardController = null;
-        mSp = null;
-        super.tearDown();
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccConnectorTest.java b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccConnectorTest.java
index 93c9142..a19882a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccConnectorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccConnectorTest.java
@@ -50,7 +50,9 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
@@ -63,17 +65,14 @@
 
     private TestLooper mLooper;
     private EuiccConnector mConnector;
-
-    // Mocked classes
-    private IEuiccService.Stub mEuiccService;
+    @Mock private IEuiccService.Stub mEuiccService;
 
     private static final int CARD_ID = 15;
-    private static final int PORT_INDEX = 0;
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mEuiccService = Mockito.mock(IEuiccService.Stub.class);
+        super.setUp("EuiccConnectorTest");
+        MockitoAnnotations.initMocks(this);
         when(mEuiccService.queryLocalInterface(anyString())).thenReturn(mEuiccService);
         when(mEuiccService.asBinder()).thenReturn(mEuiccService);
         mLooper = new TestLooper();
@@ -81,8 +80,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mLooper = null;
-        mConnector = null;
         super.tearDown();
     }
 
@@ -140,7 +137,7 @@
                 false /* hasPriority */);
         mConnector = new EuiccConnector(mContext, mLooper.getLooper());
         final AtomicBoolean called = new AtomicBoolean(false);
-        mConnector.switchToSubscription(CARD_ID, PORT_INDEX, "12345", true, new
+        mConnector.switchToSubscription(CARD_ID, "12345", true, new
                 EuiccConnector.SwitchCommandCallback() {
             @Override
             public void onSwitchComplete(int result) {
@@ -151,7 +148,7 @@
             public void onEuiccServiceUnavailable() {
                 assertTrue("Callback called twice", called.compareAndSet(false, true));
             }
-        }, false /* usePortIndex */);
+        });
         mLooper.dispatchAll();
         assertTrue(called.get());
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
index 491c690..43de6f6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/euicc/EuiccControllerTest.java
@@ -17,7 +17,6 @@
 
 import static android.telephony.euicc.EuiccCardManager.RESET_OPTION_DELETE_OPERATIONAL_PROFILES;
 import static android.telephony.euicc.EuiccManager.EUICC_OTA_STATUS_UNAVAILABLE;
-import static android.telephony.euicc.EuiccManager.SWITCH_WITHOUT_PORT_INDEX_EXCEPTION_ON_DISABLE;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -40,7 +39,6 @@
 import android.Manifest;
 import android.annotation.Nullable;
 import android.app.PendingIntent;
-import android.compat.testing.PlatformCompatChangeRule;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageInfo;
@@ -58,7 +56,6 @@
 import android.telephony.TelephonyManager;
 import android.telephony.UiccAccessRule;
 import android.telephony.UiccCardInfo;
-import android.telephony.UiccPortInfo;
 import android.telephony.euicc.DownloadableSubscription;
 import android.telephony.euicc.EuiccInfo;
 import android.telephony.euicc.EuiccManager;
@@ -68,17 +65,12 @@
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.euicc.EuiccConnector.GetOtaStatusCommandCallback;
 import com.android.internal.telephony.euicc.EuiccConnector.OtaStatusChangedCallback;
-import com.android.internal.telephony.uicc.UiccSlot;
-
-import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
-import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.TestRule;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
@@ -92,14 +84,11 @@
 
 @RunWith(AndroidJUnit4.class)
 public class EuiccControllerTest extends TelephonyTest {
-    @Rule
-    public TestRule compatChangeRule = new PlatformCompatChangeRule();
     private static final DownloadableSubscription SUBSCRIPTION =
             DownloadableSubscription.forActivationCode("abcde");
 
     private static final String PACKAGE_NAME = "test.package";
     private static final String CARRIER_NAME = "test name";
-    private static final String TEST_PACKAGE_NAME = "com.android.frameworks.telephonytests";
     private static final byte[] SIGNATURE_BYTES = new byte[] {1, 2, 3, 4, 5};
 
     private static final UiccAccessRule ACCESS_RULE;
@@ -128,12 +117,8 @@
     private static final int SUBSCRIPTION_ID = 12345;
     private static final String ICC_ID = "54321";
     private static final int CARD_ID = 25;
-    private static final int PORT_INDEX = 0;
 
-    // Mocked classes
-    private EuiccConnector mMockConnector;
-    private UiccSlot mUiccSlot;
-
+    @Mock private EuiccConnector mMockConnector;
     private TestEuiccController mController;
     private int mSavedEuiccProvisionedValue;
 
@@ -162,7 +147,7 @@
         public void addResolutionIntent(
                 Intent extrasIntent, String resolutionAction, String callingPackage,
                 int resolvableErrors, boolean confirmationCodeRetried, EuiccOperation op,
-                int cardId, int portIndex, boolean usePortIndex, int subscriptionId) {
+                int cardId) {
             mResolutionAction = resolutionAction;
             mOp = op;
         }
@@ -190,9 +175,7 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mMockConnector = Mockito.mock(EuiccConnector.class);
-        mUiccSlot = Mockito.mock(UiccSlot.class);
+        super.setUp("EuiccControllerTest");
         mController = new TestEuiccController(mContext, mMockConnector);
 
         PackageInfo pi = new PackageInfo();
@@ -208,10 +191,9 @@
 
     @After
     public void tearDown() throws Exception {
+        super.tearDown();
         Settings.Global.putInt(mContext.getContentResolver(),
                 Settings.Global.EUICC_PROVISIONED, mSavedEuiccProvisionedValue);
-        mController = null;
-        super.tearDown();
     }
 
     @Test(expected = SecurityException.class)
@@ -415,21 +397,18 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_serviceUnavailable() throws Exception {
         setHasWriteEmbeddedPermission(true);
-        setUpUiccSlotData();
         callDownloadSubscription(
                 SUBSCRIPTION, true /* switchAfterDownload */, false /* complete */,
                 0 /* result */,  0 /* resolvableError */, "whatever" /* callingPackage */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector).downloadSubscription(anyInt(), anyInt(),
+        verify(mMockConnector).downloadSubscription(anyInt(),
                     any(), anyBoolean(), anyBoolean(), any(), any());
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_error() throws Exception {
         setHasWriteEmbeddedPermission(true);
         callDownloadSubscription(SUBSCRIPTION, false /* switchAfterDownload */, true /* complete */,
@@ -439,7 +418,6 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_mustDeactivateSim() throws Exception {
         setHasWriteEmbeddedPermission(true);
         callDownloadSubscription(SUBSCRIPTION, false /* switchAfterDownload */, true /* complete */,
@@ -452,7 +430,6 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_needConfirmationCode() throws Exception {
         setHasWriteEmbeddedPermission(true);
         callDownloadSubscription(SUBSCRIPTION, false /* switchAfterDownload */, true /* complete */,
@@ -465,10 +442,8 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_success() throws Exception {
         setHasWriteEmbeddedPermission(true);
-        setUpUiccSlotData();
         callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */,
                 EuiccService.RESULT_OK, 0 /* resolvableError */, "whatever" /* callingPackage */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK, 0 /* detailedCode */);
@@ -477,7 +452,6 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noSwitch_success() throws Exception {
         setHasWriteEmbeddedPermission(true);
         callDownloadSubscription(SUBSCRIPTION, false /* switchAfterDownload */, true /* complete */,
@@ -487,42 +461,36 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPrivileges_getMetadata_serviceUnavailable()
             throws Exception {
         setHasWriteEmbeddedPermission(false);
-        setUpUiccSlotData();
         prepareGetDownloadableSubscriptionMetadataCall(false /* complete */, null /* result */);
         callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */,
                 12345, 0 /* resolvableError */, PACKAGE_NAME /* callingPackage */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector, never()).downloadSubscription(anyInt(), anyInt(),
+        verify(mMockConnector, never()).downloadSubscription(anyInt(),
                 any(), anyBoolean(), anyBoolean(), any(), any());
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPrivileges_getMetadata_serviceUnavailable_canManageSim()
             throws Exception {
         setHasWriteEmbeddedPermission(false);
-        setUpUiccSlotData();
         prepareGetDownloadableSubscriptionMetadataCall(false /* complete */, null /* result */);
         setCanManageSubscriptionOnTargetSim(true /* isTargetEuicc */, true /* hasPrivileges */);
         callDownloadSubscription(SUBSCRIPTION, true /* switchAfterDownload */, true /* complete */,
                 12345, 0 /* resolvableError */, PACKAGE_NAME /* callingPackage */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector, never()).downloadSubscription(anyInt(), anyInt(),
+        verify(mMockConnector, never()).downloadSubscription(anyInt(),
                 any(), anyBoolean(), anyBoolean(), any(), any());
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPrivileges_getMetadata_error()
             throws Exception {
         setHasWriteEmbeddedPermission(false);
-        setUpUiccSlotData();
         GetDownloadableSubscriptionMetadataResult result =
                 new GetDownloadableSubscriptionMetadataResult(42, null /* subscription */);
         prepareGetDownloadableSubscriptionMetadataCall(true /* complete */, result);
@@ -530,16 +498,14 @@
                 12345, 0 /* resolvableError */, PACKAGE_NAME /* callingPackage */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector, never()).downloadSubscription(anyInt(), anyInt(),
+        verify(mMockConnector, never()).downloadSubscription(anyInt(),
                 any(), anyBoolean(), anyBoolean(), any(), any());
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPrivileges_getMetadata_error_canManageSim()
             throws Exception {
         setHasWriteEmbeddedPermission(false);
-        setUpUiccSlotData();
         GetDownloadableSubscriptionMetadataResult result =
                 new GetDownloadableSubscriptionMetadataResult(42, null /* subscription */);
         prepareGetDownloadableSubscriptionMetadataCall(true /* complete */, result);
@@ -548,16 +514,14 @@
                 12345, 0 /* resolvableError */, PACKAGE_NAME /* callingPackage */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
                 42 /* detailedCode */);
-        verify(mMockConnector, never()).downloadSubscription(anyInt(), anyInt(),
+        verify(mMockConnector, never()).downloadSubscription(anyInt(),
                 any(), anyBoolean(), anyBoolean(), any(), any());
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPrivileges_getMetadata_mustDeactivateSim()
             throws Exception {
         setHasWriteEmbeddedPermission(false);
-        setUpUiccSlotData();
         GetDownloadableSubscriptionMetadataResult result =
                 new GetDownloadableSubscriptionMetadataResult(
                         EuiccService.RESULT_MUST_DEACTIVATE_SIM, null /* subscription */);
@@ -573,11 +537,9 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPrivileges_getMetadata_mustDeactivateSim_canManageSim()
             throws Exception {
         setHasWriteEmbeddedPermission(false);
-        setUpUiccSlotData();
         GetDownloadableSubscriptionMetadataResult result =
                 new GetDownloadableSubscriptionMetadataResult(
                     EuiccService.RESULT_MUST_DEACTIVATE_SIM, null /* subscription */);
@@ -594,10 +556,8 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPrivileges_hasCarrierPrivileges() throws Exception {
         setHasWriteEmbeddedPermission(false);
-        setUpUiccSlotData();
         GetDownloadableSubscriptionMetadataResult result =
                 new GetDownloadableSubscriptionMetadataResult(
                         EuiccService.RESULT_OK, SUBSCRIPTION_WITH_METADATA);
@@ -612,11 +572,9 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPrivileges_hasCarrierPrivileges_multiSim()
             throws Exception {
         setHasWriteEmbeddedPermission(false);
-        setUpUiccSlotData();
         GetDownloadableSubscriptionMetadataResult result =
                 new GetDownloadableSubscriptionMetadataResult(
                     EuiccService.RESULT_OK, SUBSCRIPTION_WITH_METADATA);
@@ -631,11 +589,9 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPrivileges_hasCarrierPrivileges_needsConsent()
             throws Exception {
         setHasWriteEmbeddedPermission(false);
-        setUpUiccSlotData();
         GetDownloadableSubscriptionMetadataResult result =
                 new GetDownloadableSubscriptionMetadataResult(
                         EuiccService.RESULT_OK, SUBSCRIPTION_WITH_METADATA);
@@ -646,18 +602,16 @@
                 12345, 0 /* resolvableError */, PACKAGE_NAME /* callingPackage */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector, never()).downloadSubscription(anyInt(), anyInt(),
+        verify(mMockConnector, never()).downloadSubscription(anyInt(),
                 any(), anyBoolean(), anyBoolean(), any(), any());
         verifyResolutionIntent(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                 EuiccOperation.ACTION_DOWNLOAD_NO_PRIVILEGES_OR_DEACTIVATE_SIM_CHECK_METADATA);
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPrivileges_hasCarrierPrivileges_needsConsent_multiSim()
             throws Exception {
         setHasWriteEmbeddedPermission(false);
-        setUpUiccSlotData();
         GetDownloadableSubscriptionMetadataResult result =
                 new GetDownloadableSubscriptionMetadataResult(
                     EuiccService.RESULT_OK, SUBSCRIPTION_WITH_METADATA);
@@ -668,18 +622,16 @@
                 12345, 0 /* resolvableError */, PACKAGE_NAME /* callingPackage */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector, never()).downloadSubscription(anyInt(), anyInt(),
+        verify(mMockConnector, never()).downloadSubscription(anyInt(),
                 any(), anyBoolean(), anyBoolean(), any(), any());
         verifyResolutionIntent(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                 EuiccOperation.ACTION_DOWNLOAD_NO_PRIVILEGES_OR_DEACTIVATE_SIM_CHECK_METADATA);
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPriv_hasCarrierPrivi_needsConsent_multiSim_targetPsim()
             throws Exception {
         setHasWriteEmbeddedPermission(false);
-        setUpUiccSlotData();
         GetDownloadableSubscriptionMetadataResult result =
                 new GetDownloadableSubscriptionMetadataResult(
                     EuiccService.RESULT_OK, SUBSCRIPTION_WITH_METADATA);
@@ -690,17 +642,15 @@
                 12345, 0 /* resolvableError */, PACKAGE_NAME /* callingPackage */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector, never()).downloadSubscription(anyInt(), anyInt(),
+        verify(mMockConnector, never()).downloadSubscription(anyInt(),
                 any(), anyBoolean(), anyBoolean(), any(), any());
         verifyResolutionIntent(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                 EuiccOperation.ACTION_DOWNLOAD_NO_PRIVILEGES_OR_DEACTIVATE_SIM_CHECK_METADATA);
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPrivileges_noCarrierPrivileges() throws Exception {
         setHasWriteEmbeddedPermission(false);
-        setUpUiccSlotData();
         GetDownloadableSubscriptionMetadataResult result =
                 new GetDownloadableSubscriptionMetadataResult(
                         EuiccService.RESULT_OK, SUBSCRIPTION_WITH_METADATA);
@@ -714,16 +664,14 @@
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
                 0 /* detailedCode */);
         verify(mTelephonyManager, never()).checkCarrierPrivilegesForPackage(PACKAGE_NAME);
-        verify(mMockConnector, never()).downloadSubscription(anyInt(), anyInt(),
+        verify(mMockConnector, never()).downloadSubscription(anyInt(),
                 any(), anyBoolean(), anyBoolean(), any(), any());
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testDownloadSubscription_noPrivileges_noCarrierPrivileges_canManagerTargetSim()
             throws Exception {
         setHasWriteEmbeddedPermission(false);
-        setUpUiccSlotData();
         GetDownloadableSubscriptionMetadataResult result =
                 new GetDownloadableSubscriptionMetadataResult(
                     EuiccService.RESULT_OK, SUBSCRIPTION_WITH_METADATA);
@@ -738,7 +686,7 @@
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
                 0 /* detailedCode */);
         verify(mTelephonyManager, never()).checkCarrierPrivilegesForPackage(PACKAGE_NAME);
-        verify(mMockConnector, never()).downloadSubscription(anyInt(), anyInt(),
+        verify(mMockConnector, never()).downloadSubscription(anyInt(),
                 any(), anyBoolean(), anyBoolean(), any(), any());
     }
 
@@ -809,7 +757,6 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testSwitchToSubscription_noSuchSubscription() throws Exception {
         setHasWriteEmbeddedPermission(true);
         callSwitchToSubscription(
@@ -817,12 +764,11 @@
                 "whatever" /* callingPackage */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyInt(), anyString(),
-                anyBoolean(), any(), anyBoolean());
+        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyString(), anyBoolean(),
+                any());
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testSwitchToSubscription_emptySubscription_noPrivileges() throws Exception {
         setHasWriteEmbeddedPermission(false);
         callSwitchToSubscription(
@@ -830,31 +776,26 @@
                 0 /* result */, "whatever" /* callingPackage */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyInt(), anyString(),
-                anyBoolean(), any(), anyBoolean());
+        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyString(), anyBoolean(),
+                any());
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testSwitchToSubscription_serviceUnavailable() throws Exception {
         setHasWriteEmbeddedPermission(true);
         prepareOperationSubscription(false /* hasPrivileges */);
-        setUpUiccSlotData();
         callSwitchToSubscription(
                 SUBSCRIPTION_ID, ICC_ID, false /* complete */, 0 /* result */,
                 "whatever" /* callingPackage */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector).switchToSubscription(anyInt(), anyInt(), anyString(), anyBoolean(),
-                any(), anyBoolean());
+        verify(mMockConnector).switchToSubscription(anyInt(), anyString(), anyBoolean(), any());
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testSwitchToSubscription_error() throws Exception {
         setHasWriteEmbeddedPermission(true);
         prepareOperationSubscription(false /* hasPrivileges */);
-        setUpUiccSlotData();
         callSwitchToSubscription(
                 SUBSCRIPTION_ID, ICC_ID, true /* complete */, 42 /* result */,
                 "whatever" /* callingPackage */);
@@ -863,11 +804,9 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testSwitchToSubscription_success() throws Exception {
         setHasWriteEmbeddedPermission(true);
         prepareOperationSubscription(false /* hasPrivileges */);
-        setUpUiccSlotData();
         callSwitchToSubscription(
                 SUBSCRIPTION_ID, ICC_ID, true /* complete */, EuiccService.RESULT_OK,
                 "whatever" /* callingPackage */);
@@ -875,23 +814,8 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
-    public void testSwitchToSubscription_emptySubscription_noActiveSubscription() throws Exception {
-        setHasWriteEmbeddedPermission(true);
-        callSwitchToSubscription(
-                SubscriptionManager.INVALID_SUBSCRIPTION_ID, null /* iccid */, true /* complete */,
-                EuiccService.RESULT_OK, "whatever" /* callingPackage */);
-        verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
-                0 /* detailedCode */);
-        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyInt(), anyString(),
-                anyBoolean(), any(), anyBoolean());
-    }
-
-    @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testSwitchToSubscription_emptySubscription_success() throws Exception {
         setHasWriteEmbeddedPermission(true);
-        setHasCarrierPrivilegesOnActiveSubscription(false);
         callSwitchToSubscription(
                 SubscriptionManager.INVALID_SUBSCRIPTION_ID, null /* iccid */, true /* complete */,
                 EuiccService.RESULT_OK, "whatever" /* callingPackage */);
@@ -899,7 +823,6 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testSwitchToSubscription_noPrivileges() throws Exception {
         setHasWriteEmbeddedPermission(false);
         prepareOperationSubscription(false /* hasPrivileges */);
@@ -908,16 +831,14 @@
                 "whatever" /* callingPackage */);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyInt(), anyString(),
-                anyBoolean(), any(), anyBoolean());
+        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyString(), anyBoolean(),
+                any());
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testSwitchToSubscription_hasCarrierPrivileges() throws Exception {
         setHasWriteEmbeddedPermission(false);
         prepareOperationSubscription(true /* hasPrivileges */);
-        setUpUiccSlotData();
         when(mTelephonyManager.getPhoneCount()).thenReturn(1);
         setHasCarrierPrivilegesOnActiveSubscription(true);
         callSwitchToSubscription(
@@ -926,11 +847,9 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testSwitchToSubscription_hasCarrierPrivileges_multiSim() throws Exception {
         setHasWriteEmbeddedPermission(false);
         prepareOperationSubscription(true /* hasPrivileges */);
-        setUpUiccSlotData();
         when(mTelephonyManager.getPhoneCount()).thenReturn(2);
         setCanManageSubscriptionOnTargetSim(true /* isTargetEuicc */, true /* hasPrivileges */);
         callSwitchToSubscription(
@@ -939,57 +858,51 @@
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testSwitchToSubscription_hasCarrierPrivileges_needsConsent() throws Exception {
         setHasWriteEmbeddedPermission(false);
         prepareOperationSubscription(true /* hasPrivileges */);
-        setUpUiccSlotData();
         setHasCarrierPrivilegesOnActiveSubscription(false);
         when(mTelephonyManager.getPhoneCount()).thenReturn(1);
         callSwitchToSubscription(
                 SUBSCRIPTION_ID, ICC_ID, false /* complete */, 0 /* result */, PACKAGE_NAME);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyInt(), anyString(),
-                anyBoolean(), any(), anyBoolean());
+        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyString(), anyBoolean(),
+                any());
         verifyResolutionIntent(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                 EuiccOperation.ACTION_SWITCH_NO_PRIVILEGES);
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testSwitchToSubscription_hasCarrierPrivileges_needsConsent_multiSim()
             throws Exception {
         setHasWriteEmbeddedPermission(false);
         prepareOperationSubscription(true /* hasPrivileges */);
-        setUpUiccSlotData();
         when(mTelephonyManager.getPhoneCount()).thenReturn(2);
         setCanManageSubscriptionOnTargetSim(true /* isTargetEuicc */, false /* hasPrivileges */);
         callSwitchToSubscription(
                 SUBSCRIPTION_ID, ICC_ID, false /* complete */, 0 /* result */, PACKAGE_NAME);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyInt(), anyString(),
-                anyBoolean(), any(), anyBoolean());
+        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyString(), anyBoolean(),
+                any());
         verifyResolutionIntent(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                 EuiccOperation.ACTION_SWITCH_NO_PRIVILEGES);
     }
 
     @Test
-    @DisableCompatChanges({EuiccManager.SHOULD_RESOLVE_PORT_INDEX_FOR_APPS})
     public void testSwitchToSubscription_hasCarrierPrivileges_needsConsent_multiSim_targetPsim()
             throws Exception {
         setHasWriteEmbeddedPermission(false);
         prepareOperationSubscription(true /* hasPrivileges */);
-        setUpUiccSlotData();
         when(mTelephonyManager.getPhoneCount()).thenReturn(2);
         setCanManageSubscriptionOnTargetSim(false /* isTargetEuicc */, true /* hasPrivileges */);
         callSwitchToSubscription(
                 SUBSCRIPTION_ID, ICC_ID, false /* complete */, 0 /* result */, PACKAGE_NAME);
         verifyIntentSent(EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_RESOLVABLE_ERROR,
                 0 /* detailedCode */);
-        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyInt(), anyString(),
-                anyBoolean(), any(), anyBoolean());
+        verify(mMockConnector, never()).switchToSubscription(anyInt(), anyString(), anyBoolean(),
+                any());
         verifyResolutionIntent(EuiccService.ACTION_RESOLVE_NO_PRIVILEGES,
                 EuiccOperation.ACTION_SWITCH_NO_PRIVILEGES);
     }
@@ -1213,26 +1126,6 @@
                 EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_ERROR_CODE, -1), 0x345678);
     }
 
-    @Test
-    @DisableCompatChanges({SWITCH_WITHOUT_PORT_INDEX_EXCEPTION_ON_DISABLE})
-    public void testIsCompactChangeEnabled_disable() {
-        assertFalse(mController.isCompatChangeEnabled(TEST_PACKAGE_NAME,
-                SWITCH_WITHOUT_PORT_INDEX_EXCEPTION_ON_DISABLE));
-    }
-
-    @Test
-    @EnableCompatChanges({SWITCH_WITHOUT_PORT_INDEX_EXCEPTION_ON_DISABLE})
-    public void testIsCompactChangeEnabled_enable() {
-        assertTrue(mController.isCompatChangeEnabled(TEST_PACKAGE_NAME,
-                SWITCH_WITHOUT_PORT_INDEX_EXCEPTION_ON_DISABLE));
-    }
-
-    private void setUpUiccSlotData() {
-        when(mUiccController.getUiccSlot(anyInt())).thenReturn(mUiccSlot);
-        // TODO(b/199559633): Add test cases for isMultipleEnabledProfileSupported true case
-        when(mUiccSlot.isMultipleEnabledProfileSupported()).thenReturn(false);
-    }
-
     private void setGetEidPermissions(
             boolean hasPhoneStatePrivileged, boolean hasCarrierPrivileges) throws Exception {
         doReturn(hasPhoneStatePrivileged
@@ -1261,7 +1154,7 @@
         SubscriptionInfo subInfo = new SubscriptionInfo(
                 0, "", 0, "", "", 0, 0, "", 0, null, "", "", "", true /* isEmbedded */,
                 hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null, "", CARD_ID,
-                false, null, false, 0, 0, 0, null, null, true, 0);
+                false, null, false, 0, 0, 0, null, null, true);
         when(mSubscriptionManager.canManageSubscription(subInfo, PACKAGE_NAME)).thenReturn(
                 hasPrivileges);
         when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(
@@ -1270,18 +1163,10 @@
 
     private void setCanManageSubscriptionOnTargetSim(boolean isTargetEuicc, boolean hasPrivileges)
             throws Exception {
-        UiccCardInfo cardInfo1 = new UiccCardInfo(isTargetEuicc, CARD_ID, "", 0,
-                false /* isRemovable */,
-                false /* isMultipleEnabledProfileSupported */,
-                Collections.singletonList(
-                        new UiccPortInfo("" /* iccId */, 0 /* portIdx */,
-                                -1 /* logicalSlotIdx */, false /* isActive */)));
+        UiccCardInfo cardInfo1 = new UiccCardInfo(isTargetEuicc, CARD_ID, "", "", 0,
+                false /* isRemovable */);
         UiccCardInfo cardInfo2 = new UiccCardInfo(true /* isEuicc */, 1 /* cardId */,
-                "", 0, false /* isRemovable */,
-                false /* isMultipleEnabledProfileSupported */,
-                Collections.singletonList(
-                        new UiccPortInfo("" /* iccId */, 0 /* portIdx */,
-                                -1 /* logicalSlotIdx */, false /* isActive */)));
+                "", "", 0, false /* isRemovable */);
         ArrayList<UiccCardInfo> cardInfos = new ArrayList<>();
         cardInfos.add(cardInfo1);
         cardInfos.add(cardInfo2);
@@ -1290,11 +1175,11 @@
         SubscriptionInfo subInfo1 = new SubscriptionInfo(
                 0, "", 0, "", "", 0, 0, "", 0, null, "", "", "", true /* isEmbedded */,
                 hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null, "", CARD_ID,
-                false, null, false, 0, 0, 0, null, null, true, 0);
+                false, null, false, 0, 0, 0, null, null, true);
         SubscriptionInfo subInfo2 = new SubscriptionInfo(
                 0, "", 0, "", "", 0, 0, "", 0, null, "", "", "", true /* isEmbedded */,
                 hasPrivileges ? new UiccAccessRule[] { ACCESS_RULE } : null, "",
-                1 /* cardId */, false, null, false, 0, 0, 0, null, null, true, 0);
+                1 /* cardId */, false, null, false, 0, 0, 0, null, null, true);
         when(mSubscriptionManager.canManageSubscription(subInfo1, PACKAGE_NAME)).thenReturn(
                 hasPrivileges);
         when(mSubscriptionManager.canManageSubscription(subInfo2, PACKAGE_NAME)).thenReturn(
@@ -1441,7 +1326,7 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Exception {
                 EuiccConnector.DownloadCommandCallback cb = invocation
-                        .getArgument(6 /* resultCallback */);
+                        .getArgument(5 /* resultCallback */);
                 if (complete) {
                     DownloadSubscriptionResult downloadRes = new DownloadSubscriptionResult(
                             result, resolvableError, -1 /* cardId */);
@@ -1451,7 +1336,7 @@
                 }
                 return null;
             }
-        }).when(mMockConnector).downloadSubscription(anyInt(), anyInt(),
+        }).when(mMockConnector).downloadSubscription(anyInt(),
                 any(), eq(switchAfterDownload), anyBoolean(), any(), any());
         mController.downloadSubscription(CARD_ID, subscription, switchAfterDownload, callingPackage,
                 null /* resolvedBundle */, resultCallback);
@@ -1489,7 +1374,7 @@
             @Override
             public Void answer(InvocationOnMock invocation) throws Exception {
                 EuiccConnector.SwitchCommandCallback cb = invocation
-                        .getArgument(4 /* resultCallback */);
+                        .getArgument(3 /* resultCallback */);
                 if (complete) {
                     cb.onSwitchComplete(result);
                 } else {
@@ -1497,10 +1382,8 @@
                 }
                 return null;
             }
-        }).when(mMockConnector).switchToSubscription(anyInt(), anyInt(), eq(iccid), anyBoolean(),
-                any(), anyBoolean());
-        mController.switchToSubscription(CARD_ID, subscriptionId, callingPackage,
-                resultCallback);
+        }).when(mMockConnector).switchToSubscription(anyInt(), eq(iccid), anyBoolean(), any());
+        mController.switchToSubscription(CARD_ID, subscriptionId, callingPackage, resultCallback);
     }
 
     private void callUpdateSubscriptionNickname(int subscriptionId, String iccid, String nickname,
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
index a847a24..298c3e4 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmInboundSmsHandlerTest.java
@@ -75,6 +75,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.stubbing.Answer;
 import org.mockito.verification.VerificationMode;
@@ -87,19 +88,24 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class GsmInboundSmsHandlerTest extends TelephonyTest {
-    // Mocked classes
+    @Mock
     private SmsStorageMonitor mSmsStorageMonitor;
+    @Mock
     private android.telephony.SmsMessage mSmsMessage;
+    @Mock
     private SmsMessage mGsmSmsMessage;
+    @Mock
     private SmsHeader mSmsHeader;
-    private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
-    private InboundSmsHandler.SmsFilter mSmsFilter;
-    private InboundSmsHandler.SmsFilter mSmsFilter2;
-
     private InboundSmsTracker mInboundSmsTracker;
     private InboundSmsTracker mInboundSmsTrackerSub1;
     private InboundSmsTracker mInboundSmsTrackerPart1;
     private InboundSmsTracker mInboundSmsTrackerPart2;
+    @Mock
+    private CdmaInboundSmsHandler mCdmaInboundSmsHandler;
+    @Mock
+    private InboundSmsHandler.SmsFilter mSmsFilter;
+    @Mock
+    private InboundSmsHandler.SmsFilter mSmsFilter2;
     private List<InboundSmsHandler.SmsFilter> mSmsFilters;
 
     private GsmInboundSmsHandler mGsmInboundSmsHandler;
@@ -109,13 +115,13 @@
     private static final Uri sRawUri = Uri.withAppendedPath(Telephony.Sms.CONTENT_URI,
             RAW_TABLE_NAME);
 
-    private final String mMessageBody = "This is the message body of a single-part message";
-    private final String mMessageBodyPart1 = "This is the first part of a multi-part message";
-    private final String mMessageBodyPart2 = "This is the second part of a multi-part message";
-    private final int mSubId0 = 0;
-    private final int mSubId1 = 0;
+    private String mMessageBody = "This is the message body of a single-part message";
+    private String mMessageBodyPart1 = "This is the first part of a multi-part message";
+    private String mMessageBodyPart2 = "This is the second part of a multi-part message";
+    private int mSubId0 = 0;
+    private int mSubId1 = 0;
 
-    final byte[] mSmsPdu = new byte[]{(byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
+    byte[] mSmsPdu = new byte[]{(byte)0xFF, (byte)0xFF, (byte)0xFF};
 
     private IState getCurrentState() {
         try {
@@ -155,14 +161,7 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mSmsStorageMonitor = Mockito.mock(SmsStorageMonitor.class);
-        mSmsMessage = Mockito.mock(android.telephony.SmsMessage.class);
-        mGsmSmsMessage = Mockito.mock(SmsMessage.class);
-        mSmsHeader = Mockito.mock(SmsHeader.class);
-        mCdmaInboundSmsHandler = Mockito.mock(CdmaInboundSmsHandler.class);
-        mSmsFilter = Mockito.mock(InboundSmsHandler.SmsFilter.class);
-        mSmsFilter2 = Mockito.mock(InboundSmsHandler.SmsFilter.class);
+        super.setUp("GsmInboundSmsHandlerTest");
 
         doReturn(true).when(mTelephonyManager).getSmsReceiveCapableForPhone(anyInt(), anyBoolean());
         doReturn(true).when(mSmsStorageMonitor).isStorageAvailable();
@@ -230,12 +229,6 @@
         mGsmInboundSmsHandler.quit();
         mGsmInboundSmsHandler = null;
         mContentProvider.shutdown();
-        mContentProvider = null;
-        mInboundSmsTracker = null;
-        mInboundSmsTrackerSub1 = null;
-        mInboundSmsTrackerPart1 = null;
-        mInboundSmsTrackerPart2 = null;
-        mSmsFilters = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java
index 8c1caa5..ee4f6e5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmMmiCodeTest.java
@@ -50,7 +50,12 @@
     private GsmMmiCode mGsmMmiCode;
     private GsmCdmaPhone mGsmCdmaPhoneUT;
 
-    private final Executor mExecutor = Runnable::run;
+    private Executor mExecutor = new Executor() {
+        @Override
+        public void execute(Runnable r) {
+            r.run();
+        }
+    };
 
     @Before
     public void setUp() throws Exception {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
index 19cacf0..3fdbe79 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
@@ -29,7 +29,6 @@
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -42,6 +41,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.PackageManager;
 import android.content.pm.ServiceInfo;
 import android.location.Country;
 import android.location.CountryDetector;
@@ -76,6 +76,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
@@ -86,20 +87,31 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class GsmSmsDispatcherTest extends TelephonyTest {
+
+    private static final long TIMEOUT_MS = 500;
     private static final String CARRIER_APP_PACKAGE_NAME = "com.android.carrier";
 
-    // Mocked classes
+    @Mock
+    private android.telephony.SmsMessage mSmsMessage;
+    @Mock
+    private SmsMessage mGsmSmsMessage;
+    @Mock
     private SmsDispatchersController mSmsDispatchersController;
+    @Mock
     private GsmInboundSmsHandler mGsmInboundSmsHandler;
+    @Mock
     private CountryDetector mCountryDetector;
+    @Mock
     private SMSDispatcher.SmsTracker mSmsTracker;
+    @Mock
     private ISub.Stub mISubStub;
+    @Mock
     private ICarrierMessagingService.Stub mICarrierAppMessagingService;
 
     private Object mLock = new Object();
     private boolean mReceivedTestIntent;
     private static final String TEST_INTENT = "com.android.internal.telephony.TEST_INTENT";
-    private final BroadcastReceiver mTestReceiver = new BroadcastReceiver() {
+    private BroadcastReceiver mTestReceiver = new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             logd("onReceive");
@@ -129,13 +141,8 @@
 
     @Before
     public void setUp() throws Exception {
+
         super.setUp(getClass().getSimpleName());
-        mSmsDispatchersController = mock(SmsDispatchersController.class);
-        mGsmInboundSmsHandler = mock(GsmInboundSmsHandler.class);
-        mCountryDetector = mock(CountryDetector.class);
-        mSmsTracker = mock(SMSDispatcher.SmsTracker.class);
-        mISubStub = mock(ISub.Stub.class);
-        mICarrierAppMessagingService = mock(ICarrierMessagingService.Stub.class);
 
         // Note that this replaces only cached services in ServiceManager. If a service is not found
         // in the cache, a real instance is used.
@@ -152,10 +159,9 @@
 
     @After
     public void tearDown() throws Exception {
+        mGsmSmsDispatcher = null;
         mGsmSmsDispatcherTestHandler.quit();
         mGsmSmsDispatcherTestHandler.join();
-        mGsmSmsDispatcherTestHandler = null;
-        mGsmSmsDispatcher = null;
         super.tearDown();
     }
 
@@ -329,10 +335,11 @@
     }
 
     private void mockUiccWithCarrierApp() {
+        when(mUiccController.getUiccCard(mPhone.getPhoneId())).thenReturn(mUiccCard);
         List<String> carrierPackages = new ArrayList<>();
         carrierPackages.add(CARRIER_APP_PACKAGE_NAME);
-        when(mCarrierPrivilegesTracker.getCarrierPackageNamesForIntent(any()))
-                .thenReturn(carrierPackages);
+        when(mUiccCard.getCarrierPackageNamesForIntent(
+                any(PackageManager.class), any(Intent.class))).thenReturn(carrierPackages);
     }
 
     private void mockCarrierAppStubResults(final int result, ICarrierMessagingService.Stub stub,
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
index 02484ce..d5c88e3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsResolverTest.java
@@ -20,6 +20,7 @@
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
 import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
 import static junit.framework.TestCase.assertFalse;
 
 import static org.mockito.ArgumentMatchers.argThat;
@@ -43,7 +44,6 @@
 import android.content.pm.ServiceInfo;
 import android.net.Uri;
 import android.os.Bundle;
-import android.os.Looper;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.os.UserManager;
@@ -57,7 +57,6 @@
 import android.testing.TestableLooper;
 import android.util.ArrayMap;
 import android.util.ArraySet;
-import android.util.SparseIntArray;
 
 import com.android.ims.ImsFeatureBinderRepository;
 import com.android.internal.telephony.PhoneConfigurationManager;
@@ -67,6 +66,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -95,37 +95,36 @@
     private static final int NUM_MAX_SLOTS = 2;
     private static final String TAG = ImsResolverTest.class.getSimpleName();
 
-    // Mocked classes
+    @Mock
     Context mMockContext;
+    @Mock
     PackageManager mMockPM;
+    @Mock
     ImsResolver.SubscriptionManagerProxy mTestSubscriptionManagerProxy;
+    @Mock
     ImsResolver.TelephonyManagerProxy mTestTelephonyManagerProxy;
+    @Mock
     CarrierConfigManager mMockCarrierConfigManager;
+    @Mock
     UserManager mMockUserManager;
+    @Mock
     ImsResolver.ImsDynamicQueryManagerFactory mMockQueryManagerFactory;
+    @Mock
     ImsServiceFeatureQueryManager mMockQueryManager;
+    @Mock
     ImsFeatureBinderRepository mMockRepo;
-
     private ImsResolver mTestImsResolver;
     private BroadcastReceiver mTestPackageBroadcastReceiver;
     private BroadcastReceiver mTestCarrierConfigReceiver;
     private BroadcastReceiver mTestBootCompleteReceiver;
     private ImsServiceFeatureQueryManager.Listener mDynamicQueryListener;
     private PersistableBundle[] mCarrierConfigs;
+    private TestableLooper mLooper;
 
     @Before
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        mMockContext = mock(Context.class);
-        mMockPM = mock(PackageManager.class);
-        mTestSubscriptionManagerProxy = mock(ImsResolver.SubscriptionManagerProxy.class);
-        mTestTelephonyManagerProxy = mock(ImsResolver.TelephonyManagerProxy.class);
-        mMockCarrierConfigManager = mock(CarrierConfigManager.class);
-        mMockUserManager = mock(UserManager.class);
-        mMockQueryManagerFactory = mock(ImsResolver.ImsDynamicQueryManagerFactory.class);
-        mMockQueryManager = mock(ImsServiceFeatureQueryManager.class);
-        mMockRepo = mock(ImsFeatureBinderRepository.class);
     }
 
     @After
@@ -133,11 +132,6 @@
     public void tearDown() throws Exception {
         mTestImsResolver.destroy();
         mTestImsResolver = null;
-        mTestPackageBroadcastReceiver = null;
-        mTestCarrierConfigReceiver = null;
-        mTestBootCompleteReceiver = null;
-        mDynamicQueryListener = null;
-        mCarrierConfigs = null;
         super.tearDown();
     }
 
@@ -218,11 +212,15 @@
 
         // device package name should be returned for both features.
         final Boolean[] isConfigured = new Boolean[1];
-        isConfigured[0] = mTestImsResolver.isImsServiceConfiguredForFeature(0,
-                ImsFeature.FEATURE_MMTEL);
+        // Calling this method will block us until the looper processes the command, so use
+        // runWithLooper to allow the message to be processed.
+        mLooper.runWithLooper(() ->
+                isConfigured[0] = mTestImsResolver.isImsServiceConfiguredForFeature(0,
+                        ImsFeature.FEATURE_MMTEL));
         assertTrue(isConfigured[0]);
-        isConfigured[0] = mTestImsResolver.isImsServiceConfiguredForFeature(0,
-                ImsFeature.FEATURE_RCS);
+        mLooper.runWithLooper(() ->
+                isConfigured[0] = mTestImsResolver.isImsServiceConfiguredForFeature(0,
+                        ImsFeature.FEATURE_RCS));
         assertTrue(isConfigured[0]);
     }
 
@@ -247,11 +245,15 @@
 
         // device package name should be returned for both features.
         final String[] packageName = new String[1];
-        packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
-                ImsFeature.FEATURE_MMTEL);
+        // Calling this method will block us until the looper processes the command, so use
+        // runWithLooper to allow the message to be processed.
+        mLooper.runWithLooper(() ->
+                packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
+                        ImsFeature.FEATURE_MMTEL));
         assertEquals(TEST_DEVICE_DEFAULT_NAME.getPackageName(), packageName[0]);
-        packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
-                ImsFeature.FEATURE_RCS);
+        mLooper.runWithLooper(() ->
+                packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
+                        ImsFeature.FEATURE_RCS));
         assertEquals(TEST_DEVICE_DEFAULT_NAME.getPackageName(), packageName[0]);
     }
 
@@ -271,11 +273,15 @@
 
         // device package name should be returned for both features.
         final String[] packageName = new String[1];
-        packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
-                ImsFeature.FEATURE_MMTEL);
+        // Calling this method will block us until the looper processes the command, so use
+        // runWithLooper to allow the message to be processed.
+        mLooper.runWithLooper(() ->
+                packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
+                        ImsFeature.FEATURE_MMTEL));
         assertNull(packageName[0]);
-        packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
-                ImsFeature.FEATURE_RCS);
+        mLooper.runWithLooper(() ->
+                packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
+                        ImsFeature.FEATURE_RCS));
         assertNull(packageName[0]);
     }
 
@@ -300,11 +306,15 @@
 
         // device package name should be returned for both features.
         final String[] packageName = new String[1];
-        packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
-                ImsFeature.FEATURE_MMTEL);
+        // Calling this method will block us until the looper processes the command, so use
+        // runWithLooper to allow the message to be processed.
+        mLooper.runWithLooper(() ->
+                packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
+                        ImsFeature.FEATURE_MMTEL));
         assertNull(packageName[0]);
-        packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
-                ImsFeature.FEATURE_RCS);
+        mLooper.runWithLooper(() ->
+                packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
+                        ImsFeature.FEATURE_RCS));
         assertNull(packageName[0]);
     }
 
@@ -340,11 +350,15 @@
 
         // carrier package name should be returned for both features.
         final String[] packageName = new String[1];
-        packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
-                ImsFeature.FEATURE_MMTEL);
+        // Calling this method will block us until the looper processes the command, so use
+        // runWithLooper to allow the message to be processed.
+        mLooper.runWithLooper(() ->
+                packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
+                        ImsFeature.FEATURE_MMTEL));
         assertEquals(TEST_CARRIER_DEFAULT_NAME.getPackageName(), packageName[0]);
-        packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
-                ImsFeature.FEATURE_RCS);
+        mLooper.runWithLooper(() ->
+                packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
+                        ImsFeature.FEATURE_RCS));
         assertEquals(TEST_CARRIER_DEFAULT_NAME.getPackageName(), packageName[0]);
     }
 
@@ -374,11 +388,15 @@
         startBindCarrierConfigAlreadySet();
 
         final String[] packageName = new String[1];
-        packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
-                ImsFeature.FEATURE_MMTEL);
+        // Calling this method will block us until the looper processes the command, so use
+        // runWithLooper to allow the message to be processed.
+        mLooper.runWithLooper(() ->
+                packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
+                        ImsFeature.FEATURE_MMTEL));
         assertEquals(TEST_DEVICE_DEFAULT_NAME.getPackageName(), packageName[0]);
-        packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
-                ImsFeature.FEATURE_RCS);
+        mLooper.runWithLooper(() ->
+                packageName[0] = mTestImsResolver.getConfiguredImsServicePackageName(0,
+                        ImsFeature.FEATURE_RCS));
         assertEquals(TEST_DEVICE_DEFAULT_NAME.getPackageName(), packageName[0]);
     }
 
@@ -405,16 +423,7 @@
         // setup features response
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, features, 1);
 
-        ArgumentCaptor<SparseIntArray> arrayCaptor =
-                        ArgumentCaptor.forClass(SparseIntArray.class);
-        verify(controller).bind(eq(features), arrayCaptor.capture());
-        SparseIntArray slotIdToSubIdMap = arrayCaptor.getValue();
-        SparseIntArray compareMap = new SparseIntArray();
-        compareMap.put(0, 0);
-        //ensure that slotIdToSubIdMap was delivered properly.
-        for (int i = 0; i < slotIdToSubIdMap.size(); i++) {
-            assertEquals(slotIdToSubIdMap.get(i), compareMap.get(i));
-        }
+        verify(controller).bind(features);
         verify(controller, never()).unbind();
         assertEquals(TEST_CARRIER_DEFAULT_NAME, controller.getComponentName());
     }
@@ -465,11 +474,11 @@
         when(mMockQueryManager.isQueryInProgress()).thenReturn(false);
         setupDynamicQueryFeatures(TEST_CARRIER_2_DEFAULT_NAME, featuresAll, 1);
 
-        verify(deviceController).bind(eq(featuresDevice), any(SparseIntArray.class));
+        verify(deviceController).bind(featuresDevice);
         verify(deviceController, never()).unbind();
-        verify(carrierController1).bind(eq(featuresMmTel), any(SparseIntArray.class));
+        verify(carrierController1).bind(featuresMmTel);
         verify(carrierController1, never()).unbind();
-        verify(carrierController2).bind(eq(featuresRcs), any(SparseIntArray.class));
+        verify(carrierController2).bind(featuresRcs);
         verify(carrierController2, never()).unbind();
         assertEquals(TEST_CARRIER_DEFAULT_NAME, carrierController1.getComponentName());
         assertEquals(TEST_CARRIER_2_DEFAULT_NAME, carrierController2.getComponentName());
@@ -517,11 +526,11 @@
         when(mMockQueryManager.isQueryInProgress()).thenReturn(false);
         setupDynamicQueryFeatures(TEST_CARRIER_2_DEFAULT_NAME, allFeatures, 1);
 
-        verify(deviceController, never()).bind(any(), any(SparseIntArray.class));
+        verify(deviceController, never()).bind(any());
         verify(deviceController, never()).unbind();
-        verify(carrierController1).bind(eq(featuresMmTel), any(SparseIntArray.class));
+        verify(carrierController1).bind(featuresMmTel);
         verify(carrierController1, never()).unbind();
-        verify(carrierController2).bind(eq(featuresRcs), any(SparseIntArray.class));
+        verify(carrierController2).bind(featuresRcs);
         verify(carrierController2, never()).unbind();
         assertEquals(TEST_CARRIER_DEFAULT_NAME, carrierController1.getComponentName());
         assertEquals(TEST_CARRIER_2_DEFAULT_NAME, carrierController2.getComponentName());
@@ -549,7 +558,7 @@
         startBindCarrierConfigAlreadySet();
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, features, 1);
 
-        verify(controller).bind(eq(features), any(SparseIntArray.class));
+        verify(controller).bind(features);
         verify(controller, never()).unbind();
         assertEquals(TEST_CARRIER_DEFAULT_NAME, controller.getComponentName());
     }
@@ -578,57 +587,12 @@
         // We will not bind with FEATURE_EMERGENCY_MMTEL
         features.remove(new ImsFeatureConfiguration.FeatureSlotPair(0,
                 ImsFeature.FEATURE_EMERGENCY_MMTEL));
-        verify(controller).bind(eq(features), any(SparseIntArray.class));
+        verify(controller).bind(features);
         verify(controller, never()).unbind();
         assertEquals(TEST_CARRIER_DEFAULT_NAME, controller.getComponentName());
     }
 
     /**
-     * Ensure enabling and disabling IMS only happens one time per controller.
-     */
-    @Test
-    @SmallTest
-    public void testEnableDisableImsDedupe() {
-        setupResolver(1 /*numSlots*/, TEST_DEVICE_DEFAULT_NAME.getPackageName(),
-                TEST_DEVICE2_DEFAULT_NAME.getPackageName());
-        List<ResolveInfo> info = new ArrayList<>();
-        Set<String> featuresController1 = new HashSet<>();
-        featuresController1.add(ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE);
-        featuresController1.add(ImsResolver.METADATA_MMTEL_FEATURE);
-        Set<String> featuresController2 = new HashSet<>();
-        featuresController2.add(ImsResolver.METADATA_RCS_FEATURE);
-        info.add(getResolveInfo(TEST_DEVICE_DEFAULT_NAME, featuresController1, true));
-        info.add(getResolveInfo(TEST_DEVICE2_DEFAULT_NAME, featuresController2, true));
-        setupPackageQuery(info);
-        ImsServiceController deviceController1 = mock(ImsServiceController.class);
-        ImsServiceController deviceController2 = mock(ImsServiceController.class);
-        setImsServiceControllerFactory(deviceController1, deviceController2, null, null);
-        // Bind using default features
-        startBindNoCarrierConfig(1);
-        HashSet<ImsFeatureConfiguration.FeatureSlotPair> featureSet1 =
-                convertToHashSet(featuresController1, 0);
-        HashSet<ImsFeatureConfiguration.FeatureSlotPair> featureSet2 =
-                convertToHashSet(featuresController2, 0);
-        verify(deviceController1).bind(eq(featureSet1), any(SparseIntArray.class));
-        verify(deviceController2).bind(eq(featureSet2), any(SparseIntArray.class));
-        // simulate ImsServiceController binding and setup
-        mTestImsResolver.imsServiceFeatureCreated(0, ImsFeature.FEATURE_EMERGENCY_MMTEL,
-                deviceController1);
-        mTestImsResolver.imsServiceFeatureCreated(0, ImsFeature.FEATURE_MMTEL, deviceController1);
-        mTestImsResolver.imsServiceFeatureCreated(0, ImsFeature.FEATURE_RCS, deviceController2);
-
-        mTestImsResolver.enableIms(0 /*slotId*/);
-        // Verify enableIms is only called once per controller.
-        verify(deviceController1).enableIms(eq(0), eq(0));
-        verify(deviceController2).enableIms(eq(0), eq(0));
-
-        mTestImsResolver.disableIms(0 /*slotId*/);
-        // Verify disableIms is only called once per controller.
-        verify(deviceController1).disableIms(eq(0), eq(0));
-        verify(deviceController2).disableIms(eq(0), eq(0));
-    }
-
-    /**
      * Creates a carrier ImsService that does not report FEATURE_EMERGENCY_MMTEL and then update the
      * ImsService to define it. Ensure that the controller sets this capability once enabled.
      */
@@ -647,7 +611,7 @@
         // Bind without emergency calling
         startBindCarrierConfigAlreadySet();
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, features, 1);
-        verify(controller).bind(eq(features), any(SparseIntArray.class));
+        verify(controller).bind(features);
         verify(controller, never()).unbind();
         assertEquals(TEST_CARRIER_DEFAULT_NAME, controller.getComponentName());
 
@@ -661,8 +625,7 @@
 
         //Verify new feature is added to the carrier override.
         // add all features for slot 0
-        verify(controller, atLeastOnce()).changeImsServiceFeatures(eq(newFeatures),
-                any(SparseIntArray.class));
+        verify(controller, atLeastOnce()).changeImsServiceFeatures(newFeatures);
     }
 
     /**
@@ -683,7 +646,7 @@
 
         processAllMessages();
         verify(mMockQueryManager, never()).startQuery(any(), any());
-        verify(controller, never()).bind(any(), any(SparseIntArray.class));
+        verify(controller, never()).bind(any());
         verify(controller, never()).unbind();
     }
 
@@ -713,17 +676,7 @@
         // There is no carrier override set, so make sure that the ImsServiceController binds
         // to all SIMs.
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> featureSet = convertToHashSet(features, 0);
-        ArgumentCaptor<SparseIntArray> arrayCaptor =
-                        ArgumentCaptor.forClass(SparseIntArray.class);
-        verify(controller).bind(eq(featureSet), arrayCaptor.capture());
-        SparseIntArray slotIdToSubIdMap = arrayCaptor.getValue();
-        SparseIntArray compareMap = new SparseIntArray();
-        compareMap.put(0, 0);
-        //ensure that slotIdToSubIdMap was delivered properly.
-        for (int i = 0; i < slotIdToSubIdMap.size(); i++) {
-            assertEquals(slotIdToSubIdMap.get(i), compareMap.get(i));
-        }
-
+        verify(controller).bind(featureSet);
         verify(controller, never()).unbind();
         verify(mMockQueryManager, never()).startQuery(any(), any());
         assertEquals(TEST_DEVICE_DEFAULT_NAME, controller.getComponentName());
@@ -757,18 +710,7 @@
         // to all SIMs.
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> featureSet = convertToHashSet(features, 0);
         featureSet.addAll(convertToHashSet(features, 1));
-        ArgumentCaptor<SparseIntArray> arrayCaptor =
-                        ArgumentCaptor.forClass(SparseIntArray.class);
-        verify(controller).bind(eq(featureSet), arrayCaptor.capture());
-        SparseIntArray slotIdToSubIdMap = arrayCaptor.getValue();
-        assertEquals(slotIdToSubIdMap.size(), 2);
-        SparseIntArray compareMap = new SparseIntArray();
-        compareMap.put(0, 0);
-        compareMap.put(1, -1);
-        //ensure that slotIdToSubIdMap was delivered properly.
-        for (int i = 0; i < slotIdToSubIdMap.size(); i++) {
-            assertEquals(slotIdToSubIdMap.get(i), compareMap.get(i));
-        }
+        verify(controller).bind(featureSet);
         verify(controller, never()).unbind();
         verify(mMockQueryManager, never()).startQuery(any(), any());
         assertEquals(TEST_DEVICE_DEFAULT_NAME, controller.getComponentName());
@@ -777,15 +719,8 @@
         // as well
         PhoneConfigurationManager.notifyMultiSimConfigChange(1);
         processAllMessages();
-        compareMap.delete(1);
         featureSet = convertToHashSet(features, 0);
-        verify(controller).changeImsServiceFeatures(eq(featureSet), arrayCaptor.capture());
-        slotIdToSubIdMap = arrayCaptor.getValue();
-        assertEquals(slotIdToSubIdMap.size(), compareMap.size());
-        //ensure that slotIdToSubIdMap was delivered properly.
-        for (int i = 0; i < slotIdToSubIdMap.size(); i++) {
-            assertEquals(slotIdToSubIdMap.get(i), compareMap.get(i));
-        }
+        verify(controller).changeImsServiceFeatures(featureSet);
         verify(controller, never()).unbind();
     }
 
@@ -816,18 +751,7 @@
         // There is no carrier override set, so make sure that the ImsServiceController binds
         // to all SIMs.
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> featureSet = convertToHashSet(features, 0);
-
-        ArgumentCaptor<SparseIntArray> arrayCaptor =
-                        ArgumentCaptor.forClass(SparseIntArray.class);
-        verify(controller).bind(eq(featureSet), arrayCaptor.capture());
-        SparseIntArray slotIdToSubIdMap = arrayCaptor.getValue();
-        assertEquals(slotIdToSubIdMap.size(), 1);
-        SparseIntArray compareMap = new SparseIntArray();
-        compareMap.put(0, 0);
-        //ensure that slotIdToSubIdMap was delivered properly.
-        for (int i = 0; i < slotIdToSubIdMap.size(); i++) {
-            assertEquals(slotIdToSubIdMap.get(i), compareMap.get(i));
-        }
+        verify(controller).bind(featureSet);
         verify(controller, never()).unbind();
         verify(mMockQueryManager, never()).startQuery(any(), any());
         assertEquals(TEST_DEVICE_DEFAULT_NAME, controller.getComponentName());
@@ -837,15 +761,8 @@
         PhoneConfigurationManager.notifyMultiSimConfigChange(2);
         // Carrier config changed should happen for slot 1 (independent of carrier ImsService)
         sendCarrierConfigChanged(1, 1);
-        compareMap.put(1, 1);
         featureSet.addAll(convertToHashSet(features, 1));
-        verify(controller).changeImsServiceFeatures(eq(featureSet), arrayCaptor.capture());
-        slotIdToSubIdMap = arrayCaptor.getValue();
-        assertEquals(slotIdToSubIdMap.size(), compareMap.size());
-        //ensure that slotIdToSubIdMap was delivered properly.
-        for (int i = 0; i < slotIdToSubIdMap.size(); i++) {
-            assertEquals(slotIdToSubIdMap.get(i), compareMap.get(i));
-        }
+        verify(controller).changeImsServiceFeatures(featureSet);
         verify(controller, never()).unbind();
     }
 
@@ -900,8 +817,8 @@
         mDynamicQueryListener.onComplete(TEST_DEVICE2_DEFAULT_NAME, deviceFeatures2);
         processAllMessages();
 
-        verify(deviceController, times(2)).bind(eq(deviceFeatures1), any(SparseIntArray.class));
-        verify(deviceController2, times(1)).bind(eq(deviceFeatures2), any(SparseIntArray.class));
+        verify(deviceController, times(2)).bind(eq(deviceFeatures1));
+        verify(deviceController2, times(1)).bind(eq(deviceFeatures2));
     }
 
     /**
@@ -938,7 +855,7 @@
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 1);
 
         // Verify that all features that have been defined for the carrier override are bound
-        verify(carrierController).bind(eq(carrierFeatures), any(SparseIntArray.class));
+        verify(carrierController).bind(carrierFeatures);
         verify(carrierController, never()).unbind();
         assertEquals(TEST_CARRIER_DEFAULT_NAME, carrierController.getComponentName());
         // Verify that all features that are not defined in the carrier override are bound in the
@@ -946,7 +863,7 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> deviceFeatureSet =
                 convertToHashSet(deviceFeatures, 0);
         deviceFeatureSet.removeAll(carrierFeatures);
-        verify(deviceController).bind(eq(deviceFeatureSet), any(SparseIntArray.class));
+        verify(deviceController).bind(deviceFeatureSet);
         verify(deviceController, never()).unbind();
         assertEquals(TEST_DEVICE_DEFAULT_NAME, deviceController.getComponentName());
 
@@ -957,13 +874,11 @@
         // Assume that there is a CarrierConfig change that kicks off query to carrier service.
         sendCarrierConfigChanged(1, 1);
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 2);
-        verify(carrierController).changeImsServiceFeatures(eq(carrierFeatures),
-                        any(SparseIntArray.class));
+        verify(carrierController).changeImsServiceFeatures(carrierFeatures);
         deviceFeatureSet = convertToHashSet(deviceFeatures, 0);
         deviceFeatureSet.addAll(convertToHashSet(deviceFeatures, 1));
         deviceFeatureSet.removeAll(carrierFeatures);
-        verify(deviceController).changeImsServiceFeatures(eq(deviceFeatureSet),
-                        any(SparseIntArray.class));
+        verify(deviceController).changeImsServiceFeatures(deviceFeatureSet);
         verify(deviceController, never()).unbind();
     }
 
@@ -1002,7 +917,7 @@
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 1);
 
         // Verify that all features that have been defined for the carrier override are bound
-        verify(carrierController).bind(eq(carrierFeatures), any(SparseIntArray.class));
+        verify(carrierController).bind(carrierFeatures);
         verify(carrierController, never()).unbind();
         assertEquals(TEST_CARRIER_DEFAULT_NAME, carrierController.getComponentName());
         // Verify that all features that are not defined in the carrier override are bound in the
@@ -1011,7 +926,7 @@
                 convertToHashSet(deviceFeatures, 0);
         deviceFeatureSet.addAll(convertToHashSet(deviceFeatures, 1));
         deviceFeatureSet.removeAll(carrierFeatures);
-        verify(deviceController).bind(eq(deviceFeatureSet), any(SparseIntArray.class));
+        verify(deviceController).bind(deviceFeatureSet);
         verify(deviceController, never()).unbind();
         assertEquals(TEST_DEVICE_DEFAULT_NAME, deviceController.getComponentName());
 
@@ -1021,12 +936,10 @@
         processAllMessages();
         carrierFeatures = new HashSet<>();
         carrierFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(0, ImsFeature.FEATURE_RCS));
-        verify(carrierController).changeImsServiceFeatures(eq(carrierFeatures),
-                any(SparseIntArray.class));
+        verify(carrierController).changeImsServiceFeatures(carrierFeatures);
         deviceFeatureSet = convertToHashSet(deviceFeatures, 0);
         deviceFeatureSet.removeAll(carrierFeatures);
-        verify(deviceController).changeImsServiceFeatures(eq(deviceFeatureSet),
-                any(SparseIntArray.class));
+        verify(deviceController).changeImsServiceFeatures(deviceFeatureSet);
         verify(deviceController, never()).unbind();
     }
 
@@ -1049,16 +962,14 @@
         setupPackageQuery(info);
         ImsServiceController controller = setupController();
 
+
         startBindNoCarrierConfig(1);
         processAllMessages();
 
-        // If MMTEL_FEATURE is not set, EMERGENCY_MMTEL_FEATURE should not be in feature set.
-        features.clear();
-        features.add(ImsResolver.METADATA_RCS_FEATURE);
-        HashSet<ImsFeatureConfiguration.FeatureSlotPair> featureSet = convertToHashSet(features, 0);
         // There is no carrier override set, so make sure that the ImsServiceController binds
         // to all SIMs.
-        verify(controller).bind(eq(featureSet), any(SparseIntArray.class));
+        HashSet<ImsFeatureConfiguration.FeatureSlotPair> featureSet = convertToHashSet(features, 0);
+        verify(controller).bind(featureSet);
         verify(controller, never()).unbind();
         verify(mMockQueryManager, never()).startQuery(any(), any());
         assertEquals(TEST_DEVICE_DEFAULT_NAME, controller.getComponentName());
@@ -1096,7 +1007,7 @@
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 1);
 
         // Verify that all features that have been defined for the carrier override are bound
-        verify(carrierController).bind(eq(carrierFeatures), any(SparseIntArray.class));
+        verify(carrierController).bind(carrierFeatures);
         verify(carrierController, never()).unbind();
         assertEquals(TEST_CARRIER_DEFAULT_NAME, carrierController.getComponentName());
         // Verify that all features that are not defined in the carrier override are bound in the
@@ -1104,7 +1015,7 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> deviceFeatureSet =
                 convertToHashSet(deviceFeatures, 0);
         deviceFeatureSet.removeAll(carrierFeatures);
-        verify(deviceController).bind(eq(deviceFeatureSet), any(SparseIntArray.class));
+        verify(deviceController).bind(deviceFeatureSet);
         verify(deviceController, never()).unbind();
         assertEquals(TEST_DEVICE_DEFAULT_NAME, deviceController.getComponentName());
     }
@@ -1151,7 +1062,7 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> featureSet =
                 convertToHashSet(features, 0);
         featureSet.addAll(convertToHashSet(features, 1));
-        verify(controller).bind(eq(featureSet), any(SparseIntArray.class));
+        verify(controller).bind(featureSet);
 
         // add RCS to features list
         Set<String> newFeatures = new HashSet<>(features);
@@ -1165,7 +1076,7 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> newFeatureSet =
                 convertToHashSet(newFeatures, 0);
         newFeatureSet.addAll(convertToHashSet(newFeatures, 1));
-        verify(controller).changeImsServiceFeatures(eq(newFeatureSet), any(SparseIntArray.class));
+        verify(controller).changeImsServiceFeatures(newFeatureSet);
     }
 
     /**
@@ -1196,8 +1107,8 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> featureSet2 =
                 convertToHashSet(featuresController2, 0);
         featureSet2.addAll(convertToHashSet(featuresController2, 1));
-        verify(deviceController1).bind(eq(featureSet1), any(SparseIntArray.class));
-        verify(deviceController2).bind(eq(featureSet2), any(SparseIntArray.class));
+        verify(deviceController1).bind(featureSet1);
+        verify(deviceController2).bind(featureSet2);
 
         // add RCS to features list for device 1
         Set<String> newFeatures1 = new HashSet<>(featuresController1);
@@ -1209,10 +1120,8 @@
 
         // verify the devices have not changed features (because their configurations are still
         // the same)
-        verify(deviceController1, times(2)).changeImsServiceFeatures(eq(featureSet1),
-                any(SparseIntArray.class));
-        verify(deviceController2, times(2)).changeImsServiceFeatures(eq(featureSet2),
-                any(SparseIntArray.class));
+        verify(deviceController1, times(2)).changeImsServiceFeatures(featureSet1);
+        verify(deviceController2, times(2)).changeImsServiceFeatures(featureSet2);
     }
 
     /**
@@ -1235,7 +1144,7 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> featureSet =
                 convertToHashSet(features, 0);
         featureSet.addAll(convertToHashSet(features, 1));
-        verify(controller).bind(eq(featureSet), any(SparseIntArray.class));
+        verify(controller).bind(featureSet);
 
         // add RCS to features list
         Set<String> newFeatures = new HashSet<>(features);
@@ -1248,8 +1157,7 @@
         // Verify new feature is not added to the device default, since it is not configured.
         // This happens twice because two CarrierConfigChanged events occur, causing a
         // changeImsServiceFeatures after bind() and then another after packageChanged.
-        verify(controller, times(2)).changeImsServiceFeatures(eq(featureSet),
-                any(SparseIntArray.class));
+        verify(controller, times(2)).changeImsServiceFeatures(featureSet);
     }
 
     /**
@@ -1284,7 +1192,7 @@
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 1);
 
         // Verify that all features that have been defined for the carrier override are bound
-        verify(carrierController).bind(eq(carrierFeatures), any(SparseIntArray.class));
+        verify(carrierController).bind(carrierFeatures);
         verify(carrierController, never()).unbind();
         assertEquals(TEST_CARRIER_DEFAULT_NAME, carrierController.getComponentName());
         // Verify that all features that are not defined in the carrier override are bound in the
@@ -1293,7 +1201,7 @@
                 convertToHashSet(deviceFeatures, 1);
         deviceFeatureSet.addAll(convertToHashSet(deviceFeatures, 0));
         deviceFeatureSet.removeAll(carrierFeatures);
-        verify(deviceController).bind(eq(deviceFeatureSet), any(SparseIntArray.class));
+        verify(deviceController).bind(deviceFeatureSet);
         verify(deviceController, never()).unbind();
         assertEquals(TEST_DEVICE_DEFAULT_NAME, deviceController.getComponentName());
 
@@ -1314,12 +1222,10 @@
         newDeviceFeatureSet.addAll(convertToHashSet(newDeviceFeatures, 0));
         // remove carrier overrides for slot 0
         newDeviceFeatureSet.removeAll(carrierFeatures);
-        verify(deviceController).changeImsServiceFeatures(eq(newDeviceFeatureSet),
-                any(SparseIntArray.class));
+        verify(deviceController).changeImsServiceFeatures(newDeviceFeatureSet);
         // features should be the same as before, ImsServiceController will disregard change if it
         // is the same feature set anyway.
-        verify(carrierController).changeImsServiceFeatures(eq(carrierFeatures),
-                any(SparseIntArray.class));
+        verify(carrierController).changeImsServiceFeatures(carrierFeatures);
     }
 
     /**
@@ -1358,7 +1264,7 @@
         startBindCarrierConfigAlreadySet();
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 1);
         // Verify that all features that have been defined for the carrier override are bound
-        verify(carrierController).bind(eq(carrierFeatures), any(SparseIntArray.class));
+        verify(carrierController).bind(carrierFeatures);
         verify(carrierController, never()).unbind();
         assertEquals(TEST_CARRIER_DEFAULT_NAME, carrierController.getComponentName());
         // Verify that all features that are not defined in the carrier override are bound in the
@@ -1366,13 +1272,13 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> deviceFeatureSet1 =
                 convertToHashSet(deviceFeatures1, 1);
         deviceFeatureSet1.removeAll(carrierFeatures);
-        verify(deviceController1).bind(eq(deviceFeatureSet1), any(SparseIntArray.class));
+        verify(deviceController1).bind(deviceFeatureSet1);
         verify(deviceController1, never()).unbind();
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> deviceFeatureSet2 =
                 convertToHashSet(deviceFeatures2, 0);
         deviceFeatureSet2.addAll(convertToHashSet(deviceFeatures2, 1));
         deviceFeatureSet2.removeAll(carrierFeatures);
-        verify(deviceController2).bind(eq(deviceFeatureSet2), any(SparseIntArray.class));
+        verify(deviceController2).bind(deviceFeatureSet2);
         verify(deviceController2, never()).unbind();
         assertEquals(TEST_DEVICE_DEFAULT_NAME, deviceController1.getComponentName());
         assertEquals(TEST_DEVICE2_DEFAULT_NAME, deviceController2.getComponentName());
@@ -1385,14 +1291,11 @@
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 2);
 
         //Verify new feature is added to the carrier override.
-        verify(carrierController).changeImsServiceFeatures(eq(carrierFeatures),
-                any(SparseIntArray.class));
+        verify(carrierController).changeImsServiceFeatures(carrierFeatures);
         deviceFeatureSet1.removeAll(carrierFeatures);
-        verify(deviceController1, times(2)).changeImsServiceFeatures(eq(deviceFeatureSet1),
-                any(SparseIntArray.class));
+        verify(deviceController1, times(2)).changeImsServiceFeatures(deviceFeatureSet1);
         deviceFeatureSet2.removeAll(carrierFeatures);
-        verify(deviceController2).changeImsServiceFeatures(eq(deviceFeatureSet2),
-                any(SparseIntArray.class));
+        verify(deviceController2).changeImsServiceFeatures(deviceFeatureSet2);
     }
 
     /**
@@ -1425,7 +1328,7 @@
         startBindCarrierConfigAlreadySet();
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 1);
         // Verify that all features that have been defined for the carrier override are bound
-        verify(carrierController).bind(eq(carrierFeatures), any(SparseIntArray.class));
+        verify(carrierController).bind(carrierFeatures);
         verify(carrierController, never()).unbind();
         assertEquals(TEST_CARRIER_DEFAULT_NAME, carrierController.getComponentName());
         // Verify that all features that are not defined in the carrier override are bound in the
@@ -1434,7 +1337,7 @@
                 convertToHashSet(deviceFeatures, 1);
         deviceFeatureSet.addAll(convertToHashSet(deviceFeatures, 0));
         deviceFeatureSet.removeAll(carrierFeatures);
-        verify(deviceController).bind(eq(deviceFeatureSet), any(SparseIntArray.class));
+        verify(deviceController).bind(deviceFeatureSet);
         verify(deviceController, never()).unbind();
         assertEquals(TEST_DEVICE_DEFAULT_NAME, deviceController.getComponentName());
 
@@ -1447,8 +1350,7 @@
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 2);
 
         //Verify new feature is added to the carrier override.
-        verify(carrierController).changeImsServiceFeatures(eq(carrierFeatures),
-                any(SparseIntArray.class));
+        verify(carrierController).changeImsServiceFeatures(carrierFeatures);
         Set<String> newDeviceFeatures = new HashSet<>();
         newDeviceFeatures.add(ImsResolver.METADATA_MMTEL_FEATURE);
         newDeviceFeatures.add(ImsResolver.METADATA_RCS_FEATURE);
@@ -1456,8 +1358,7 @@
                 convertToHashSet(newDeviceFeatures, 1);
         newDeviceFeatureSet.addAll(convertToHashSet(newDeviceFeatures, 0));
         newDeviceFeatureSet.removeAll(carrierFeatures);
-        verify(deviceController).changeImsServiceFeatures(eq(newDeviceFeatureSet),
-                any(SparseIntArray.class));
+        verify(deviceController).changeImsServiceFeatures(newDeviceFeatureSet);
     }
 
     /**
@@ -1493,14 +1394,13 @@
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 1);
 
         // Verify that all features that have been defined for the carrier override are bound
-        verify(carrierController).bind(eq(carrierFeatures), any(SparseIntArray.class));
+        verify(carrierController).bind(carrierFeatures);
         // device features change
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> deviceFeatureSet =
                 convertToHashSet(deviceFeatures, 1);
         deviceFeatureSet.addAll(convertToHashSet(deviceFeatures, 0));
         deviceFeatureSet.removeAll(carrierFeatures);
-        verify(deviceController).changeImsServiceFeatures(eq(deviceFeatureSet),
-                any(SparseIntArray.class));
+        verify(deviceController).changeImsServiceFeatures(deviceFeatureSet);
     }
 
     /**
@@ -1545,8 +1445,7 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> deviceFeatureSet =
                 convertToHashSet(deviceFeatures, 1);
         deviceFeatureSet.addAll(convertToHashSet(deviceFeatures, 0));
-        verify(deviceController).changeImsServiceFeatures(eq(deviceFeatureSet),
-                any(SparseIntArray.class));
+        verify(deviceController).changeImsServiceFeatures(deviceFeatureSet);
     }
 
     /**
@@ -1589,8 +1488,7 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> deviceFeatureSet =
                 convertToHashSet(deviceFeatures, 1);
         deviceFeatureSet.addAll(convertToHashSet(deviceFeatures, 0));
-        verify(deviceController).changeImsServiceFeatures(eq(deviceFeatureSet),
-                any(SparseIntArray.class));
+        verify(deviceController).changeImsServiceFeatures(deviceFeatureSet);
     }
 
     /**
@@ -1640,7 +1538,7 @@
         assertNotNull(mTestImsResolver.getImsServiceInfoFromCache(
                 TEST_CARRIER_DEFAULT_NAME.getPackageName()));
         // Verify that carrier 2 is bound
-        verify(carrierController2).bind(eq(carrierFeatures2), any(SparseIntArray.class));
+        verify(carrierController2).bind(carrierFeatures2);
         assertNotNull(mTestImsResolver.getImsServiceInfoFromCache(
                 TEST_CARRIER_2_DEFAULT_NAME.getPackageName()));
         // device features change to accommodate for the features carrier 2 lacks
@@ -1648,8 +1546,7 @@
                 convertToHashSet(deviceFeatures, 1);
         deviceFeatureSet.addAll(convertToHashSet(deviceFeatures, 0));
         deviceFeatureSet.removeAll(carrierFeatures2);
-        verify(deviceController).changeImsServiceFeatures(eq(deviceFeatureSet),
-                any(SparseIntArray.class));
+        verify(deviceController).changeImsServiceFeatures(deviceFeatureSet);
     }
 
     /**
@@ -1688,14 +1585,13 @@
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 1);
 
         // Verify that all features that have been defined for the carrier override are bound
-        verify(carrierController).bind(eq(carrierFeatures), any(SparseIntArray.class));
+        verify(carrierController).bind(carrierFeatures);
         // device features change
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> deviceFeatureSet =
                 convertToHashSet(deviceFeatures, 1);
         deviceFeatureSet.addAll(convertToHashSet(deviceFeatures, 0));
         deviceFeatureSet.removeAll(carrierFeatures);
-        verify(deviceController).changeImsServiceFeatures(eq(deviceFeatureSet),
-                any(SparseIntArray.class));
+        verify(deviceController).changeImsServiceFeatures(deviceFeatureSet);
     }
 
     /**
@@ -1729,13 +1625,13 @@
         setupDynamicQueryFeaturesFailure(TEST_CARRIER_DEFAULT_NAME, 1);
 
         // Verify that a bind never occurs for the carrier controller.
-        verify(carrierController, never()).bind(any(), any(SparseIntArray.class));
+        verify(carrierController, never()).bind(any());
         verify(carrierController, never()).unbind();
         // Verify that all features are used to bind to the device ImsService since the carrier
         // ImsService failed to bind properly.
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> deviceFeatureSet =
                 convertToHashSet(deviceFeatures, 0);
-        verify(deviceController).bind(eq(deviceFeatureSet), any(SparseIntArray.class));
+        verify(deviceController).bind(deviceFeatureSet);
         verify(deviceController, never()).unbind();
         assertEquals(TEST_DEVICE_DEFAULT_NAME, deviceController.getComponentName());
     }
@@ -1770,14 +1666,14 @@
         setupDynamicQueryFeatures(TEST_CARRIER_DEFAULT_NAME, carrierFeatures, 1);
 
         // Verify that a bind never occurs for the carrier controller.
-        verify(carrierController).bind(eq(carrierFeatures), any(SparseIntArray.class));
+        verify(carrierController).bind(carrierFeatures);
         verify(carrierController, never()).unbind();
         // Verify that all features that are not defined in the carrier override are bound in the
         // device controller (including emergency voice for slot 0)
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> deviceFeatureSet =
                 convertToHashSet(deviceFeatures, 0);
         deviceFeatureSet.removeAll(carrierFeatures);
-        verify(deviceController).bind(eq(deviceFeatureSet), any(SparseIntArray.class));
+        verify(deviceController).bind(deviceFeatureSet);
         verify(deviceController, never()).unbind();
         assertEquals(TEST_DEVICE_DEFAULT_NAME, deviceController.getComponentName());
 
@@ -1788,8 +1684,7 @@
         // taken by the carrier app.
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> originalDeviceFeatureSet =
                 convertToHashSet(deviceFeatures, 0);
-        verify(deviceController).changeImsServiceFeatures(eq(originalDeviceFeatureSet),
-                any(SparseIntArray.class));
+        verify(deviceController).changeImsServiceFeatures(originalDeviceFeatureSet);
     }
 
     /**
@@ -1821,9 +1716,9 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> featureResultSet =
                 convertToHashSet(featureResult, 0);
         featureResultSet.addAll(convertToHashSet(featureResult, 1));
-        verify(deviceController1).bind(eq(featureResultSet), any(SparseIntArray.class));
+        verify(deviceController1).bind(featureResultSet);
         verify(deviceController1, never()).unbind();
-        verify(deviceController2, never()).bind(any(), any(SparseIntArray.class));
+        verify(deviceController2, never()).bind(any());
         verify(deviceController2, never()).unbind();
         verify(mMockQueryManager, never()).startQuery(any(), any());
         assertEquals(TEST_DEVICE_DEFAULT_NAME, deviceController1.getComponentName());
@@ -1858,9 +1753,9 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> featureResultSet =
                 convertToHashSet(featureResult, 0);
         featureResultSet.addAll(convertToHashSet(featureResult, 1));
-        verify(deviceController1).bind(eq(featureResultSet), any(SparseIntArray.class));
+        verify(deviceController1).bind(featureResultSet);
         verify(deviceController1, never()).unbind();
-        verify(deviceController2, never()).bind(any(), any(SparseIntArray.class));
+        verify(deviceController2, never()).bind(any());
         verify(deviceController2, never()).unbind();
         verify(mMockQueryManager, never()).startQuery(any(), any());
         assertEquals(TEST_DEVICE_DEFAULT_NAME, deviceController1.getComponentName());
@@ -1900,9 +1795,9 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> featureSet2 =
                 convertToHashSet(features2, 0);
         featureSet2.addAll(convertToHashSet(features2, 1));
-        verify(deviceController1).bind(eq(featureSet1), any(SparseIntArray.class));
+        verify(deviceController1).bind(featureSet1);
         verify(deviceController1, never()).unbind();
-        verify(deviceController2).bind(eq(featureSet2), any(SparseIntArray.class));
+        verify(deviceController2).bind(featureSet2);
         verify(deviceController2, never()).unbind();
         verify(mMockQueryManager, never()).startQuery(any(), any());
         assertEquals(TEST_DEVICE_DEFAULT_NAME, deviceController1.getComponentName());
@@ -1935,9 +1830,9 @@
         startBindNoCarrierConfig(1);
         processAllMessages();
 
-        verify(deviceController1, never()).bind(any(), any(SparseIntArray.class));
+        verify(deviceController1, never()).bind(any());
         verify(deviceController1, never()).unbind();
-        verify(deviceController2, never()).bind(any(), any(SparseIntArray.class));
+        verify(deviceController2, never()).bind(any());
         verify(deviceController2, never()).unbind();
         verify(mMockQueryManager, never()).startQuery(any(), any());
     }
@@ -1968,7 +1863,13 @@
         }
 
         mTestImsResolver = new ImsResolver(mMockContext, deviceMmTelPkgName, deviceRcsPkgName,
-                numSlots, mMockRepo, Looper.myLooper());
+                numSlots, mMockRepo);
+        try {
+            mLooper = new TestableLooper(mTestImsResolver.getHandler().getLooper());
+            monitorTestableLooper(mLooper);
+        } catch (Exception e) {
+            fail("Unable to create looper from handler.");
+        }
 
         mTestImsResolver.setSubscriptionManagerProxy(mTestSubscriptionManagerProxy);
         mTestImsResolver.setTelephonyManagerProxy(mTestTelephonyManagerProxy);
@@ -2233,6 +2134,8 @@
     private HashSet<ImsFeatureConfiguration.FeatureSlotPair> convertToHashSet(
             Set<String> features, int slotId) {
         return features.stream()
+                // We do not count this as a valid feature set member.
+                .filter(f -> !ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE.equals(f))
                 .map(f -> new ImsFeatureConfiguration.FeatureSlotPair(slotId,
                         metadataStringToFeature(f)))
                 .collect(Collectors.toCollection(HashSet::new));
@@ -2245,8 +2148,6 @@
 
     private int metadataStringToFeature(String f) {
         switch (f) {
-            case ImsResolver.METADATA_EMERGENCY_MMTEL_FEATURE:
-                return ImsFeature.FEATURE_EMERGENCY_MMTEL;
             case ImsResolver.METADATA_MMTEL_FEATURE:
                 return ImsFeature.FEATURE_MMTEL;
             case ImsResolver.METADATA_RCS_FEATURE:
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerCompatTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerCompatTest.java
deleted file mode 100644
index b80c6b0..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerCompatTest.java
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.ims;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertTrue;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.ServiceConnection;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.Looper;
-import android.os.RemoteException;
-import android.telephony.ims.feature.ImsFeature;
-import android.telephony.ims.stub.ImsFeatureConfiguration;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.SparseIntArray;
-
-import androidx.test.runner.AndroidJUnit4;
-
-import com.android.ims.ImsFeatureBinderRepository;
-import com.android.ims.ImsFeatureContainer;
-import com.android.ims.internal.IImsConfig;
-import com.android.ims.internal.IImsMMTelFeature;
-import com.android.ims.internal.IImsServiceController;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-
-import java.util.HashSet;
-
-@RunWith(AndroidJUnit4.class)
-public class ImsServiceControllerCompatTest extends ImsTestBase {
-
-    private static final int SLOT_0 = 0;
-    private static final int SUB_1 = 1;
-
-    private static final ImsServiceController.RebindRetry REBIND_RETRY =
-            new ImsServiceController.RebindRetry() {
-                @Override
-                public long getStartDelay() {
-                    return 50;
-                }
-
-                @Override
-                public long getMaximumDelay() {
-                    return 1000;
-                }
-            };
-
-    // Mocked classes
-    MmTelInterfaceAdapter mMockMmTelInterfaceAdapter;
-    IImsMMTelFeature mMockRemoteMMTelFeature;
-    IBinder mMockMMTelBinder;
-    IImsServiceController mMockServiceControllerBinder;
-    ImsServiceController.ImsServiceControllerCallbacks mMockCallbacks;
-    IImsConfig mMockImsConfig;
-    Context mMockContext;
-
-    private final ComponentName mTestComponentName = new ComponentName("TestPkg",
-            "ImsServiceControllerTest");
-    private final Handler mHandler = new Handler(Looper.getMainLooper());
-    private ImsServiceController mTestImsServiceController;
-    private ImsFeatureBinderRepository mRepo;
-    private MmTelFeatureCompatAdapter mMmTelCompatAdapterSpy;
-
-    @Before
-    @Override
-    public void setUp() throws Exception {
-        super.setUp();
-        mMockMmTelInterfaceAdapter = mock(MmTelInterfaceAdapter.class);
-        mMockRemoteMMTelFeature = mock(IImsMMTelFeature.class);
-        mMockMMTelBinder = mock(IBinder.class);
-        mMockServiceControllerBinder = mock(IImsServiceController.class);
-        mMockCallbacks = mock(ImsServiceController.ImsServiceControllerCallbacks.class);
-        mMockImsConfig = mock(IImsConfig.class);
-        mMockContext = mock(Context.class);
-        mRepo = new ImsFeatureBinderRepository();
-        // Can't mock MmTelFeatureCompatAdapter due to final getBinder() method.
-        mMmTelCompatAdapterSpy = spy(new MmTelFeatureCompatAdapter(mMockContext, SLOT_0,
-                mMockMmTelInterfaceAdapter));
-        mTestImsServiceController = new ImsServiceControllerCompat(mMockContext, mTestComponentName,
-                mMockCallbacks, mHandler, REBIND_RETRY, mRepo,
-                (a, b, c) -> mMmTelCompatAdapterSpy);
-        when(mMockContext.bindService(any(), any(), anyInt())).thenReturn(true);
-        when(mMockServiceControllerBinder.createMMTelFeature(anyInt()))
-                .thenReturn(mMockRemoteMMTelFeature);
-        when(mMockRemoteMMTelFeature.getConfigInterface()).thenReturn(mMockImsConfig);
-        when(mMockRemoteMMTelFeature.asBinder()).thenReturn(mMockMMTelBinder);
-    }
-
-    @After
-    @Override
-    public void tearDown() throws Exception {
-        mTestImsServiceController.stopBackoffTimerForTesting();
-        mTestImsServiceController = null;
-        // Make sure the handler is empty before finishing the test.
-        waitForHandlerAction(mHandler, 1000);
-        mTestImsServiceController = null;
-        mRepo = null;
-        mMmTelCompatAdapterSpy = null;
-        super.tearDown();
-    }
-
-    /**
-     * Tests that the MmTelFeatureCompatAdapter is cleaned up properly and ImsServiceController
-     * callbacks are properly called when an ImsService is bound and then crashes.
-     */
-    @SmallTest
-    @Test
-    public void testBindServiceAndCrashCleanUp() throws RemoteException {
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_1);
-        ServiceConnection conn = bindAndConnectService(slotIdToSubIdMap);
-        // add the MMTelFeature
-        verify(mMockServiceControllerBinder).createMMTelFeature(SLOT_0);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        validateMmTelFeatureContainerExists(SLOT_0);
-        // Remove the feature
-        conn.onBindingDied(mTestComponentName);
-        verify(mMmTelCompatAdapterSpy).onFeatureRemoved();
-        verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL));
-        validateMmTelFeatureContainerDoesntExist(SLOT_0);
-    }
-
-    private void validateMmTelFeatureContainerExists(int slotId) {
-        ImsFeatureContainer fc =
-                mRepo.getIfExists(slotId, ImsFeature.FEATURE_MMTEL).orElse(null);
-        assertNotNull("MMTEL FeatureContainer should not be null", fc);
-        assertEquals("ImsServiceController did not report MmTelFeature to service repo correctly",
-                mMmTelCompatAdapterSpy.getBinder(), fc.imsFeature);
-        assertEquals(0, (android.telephony.ims.ImsService.CAPABILITY_EMERGENCY_OVER_MMTEL
-                & fc.getCapabilities()));
-    }
-
-    private void validateMmTelFeatureContainerDoesntExist(int slotId) {
-        ImsFeatureContainer fc =
-                mRepo.getIfExists(slotId, ImsFeature.FEATURE_MMTEL).orElse(null);
-        assertNull("FeatureContainer should be null", fc);
-    }
-
-    private ServiceConnection bindAndConnectService(SparseIntArray slotIdToSubIdMap) {
-        HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>();
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
-        ServiceConnection connection = bindService(testFeatures, slotIdToSubIdMap);
-        IImsServiceController.Stub controllerStub = mock(IImsServiceController.Stub.class);
-        when(controllerStub.queryLocalInterface(any())).thenReturn(mMockServiceControllerBinder);
-        connection.onServiceConnected(mTestComponentName, controllerStub);
-        return connection;
-    }
-
-    private ServiceConnection bindService(
-            HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures,
-            SparseIntArray slotIdToSubIdMap) {
-        ArgumentCaptor<ServiceConnection> serviceCaptor =
-                ArgumentCaptor.forClass(ServiceConnection.class);
-        assertTrue(mTestImsServiceController.bind(testFeatures, slotIdToSubIdMap));
-        verify(mMockContext).bindService(any(), serviceCaptor.capture(), anyInt());
-        return serviceCaptor.getValue();
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java
index 083fac9..0d72364 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsServiceControllerTest.java
@@ -39,7 +39,6 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.RemoteException;
-import android.telephony.SubscriptionManager;
 import android.telephony.ims.ImsService;
 import android.telephony.ims.aidl.IImsConfig;
 import android.telephony.ims.aidl.IImsMmTelFeature;
@@ -49,7 +48,6 @@
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.stub.ImsFeatureConfiguration;
 import android.test.suitebuilder.annotation.SmallTest;
-import android.util.SparseIntArray;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -64,6 +62,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.HashSet;
 
@@ -75,10 +74,6 @@
 
     private static final int SLOT_0 = 0;
     private static final int SLOT_1 = 1;
-    private static final int SUB_2 = 2;
-    private static final int SUB_3 = 3;
-    private static final int SUB_4 = 4;
-    private static final int SUB_5 = 5;
 
     private static final ImsServiceController.RebindRetry REBIND_RETRY =
             new ImsServiceController.RebindRetry() {
@@ -97,7 +92,7 @@
         public ImsFeatureContainer container;
 
         @Override
-        public void imsFeatureCreated(ImsFeatureContainer c, int subId) {
+        public void imsFeatureCreated(ImsFeatureContainer c) {
             container = c;
         }
 
@@ -107,7 +102,7 @@
         }
 
         @Override
-        public void imsStatusChanged(int stat, int subId) {
+        public void imsStatusChanged(int stat) {
             container.setState(stat);
         }
 
@@ -117,17 +112,16 @@
         }
     }
 
-    // Mocked classes
-    IImsMmTelFeature mMockMmTelFeature;
-    IBinder mMockMmTelBinder;
-    IImsRcsFeature mMockRcsFeature;
-    IBinder mMockRcsBinder;
-    IImsConfig mMockImsConfig;
-    IImsRegistration mMockRcsRegistration;
-    IImsServiceController mMockServiceControllerBinder;
-    ImsServiceController.ImsServiceControllerCallbacks mMockCallbacks;
-    Context mMockContext;
+    @Mock IImsMmTelFeature mMockMmTelFeature;
+    @Mock IBinder mMockMmTelBinder;
+    @Mock IImsRcsFeature mMockRcsFeature;
+    @Mock IBinder mMockRcsBinder;
+    @Mock IImsConfig mMockImsConfig;
+    @Mock IImsRegistration mMockRcsRegistration;
 
+    @Mock IImsServiceController mMockServiceControllerBinder;
+    @Mock ImsServiceController.ImsServiceControllerCallbacks mMockCallbacks;
+    @Mock Context mMockContext;
     private final ComponentName mTestComponentName = new ComponentName("TestPkg",
             "ImsServiceControllerTest");
     private final Handler mHandler = new Handler(Looper.getMainLooper());
@@ -138,29 +132,17 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        mMockMmTelFeature = mock(IImsMmTelFeature.class);
-        mMockMmTelBinder = mock(IBinder.class);
-        mMockRcsFeature = mock(IImsRcsFeature.class);
-        mMockRcsBinder = mock(IBinder.class);
-        mMockImsConfig = mock(IImsConfig.class);
-        mMockRcsRegistration = mock(IImsRegistration.class);
-        mMockServiceControllerBinder = mock(IImsServiceController.class);
-        mMockCallbacks = mock(ImsServiceController.ImsServiceControllerCallbacks.class);
-        mMockContext = mock(Context.class);
-
         mRepo = new ImsFeatureBinderRepository();
         mTestImsServiceController = new ImsServiceController(mMockContext, mTestComponentName,
                 mMockCallbacks, mHandler, REBIND_RETRY, mRepo);
         when(mMockContext.bindService(any(), any(), anyInt())).thenReturn(true);
-        when(mMockServiceControllerBinder.createMmTelFeature(anyInt(), anyInt()))
+        when(mMockServiceControllerBinder.createMmTelFeature(anyInt()))
                 .thenReturn(mMockMmTelFeature);
-        when(mMockServiceControllerBinder.createRcsFeature(anyInt(), anyInt()))
+        when(mMockServiceControllerBinder.createRcsFeature(anyInt()))
                 .thenReturn(mMockRcsFeature);
-        when(mMockServiceControllerBinder.createEmergencyOnlyMmTelFeature(anyInt()))
-                .thenReturn(mMockMmTelFeature);
-        when(mMockServiceControllerBinder.getConfig(anyInt(), anyInt()))
+        when(mMockServiceControllerBinder.getConfig(anyInt()))
                 .thenReturn(mMockImsConfig);
-        when(mMockServiceControllerBinder.getRegistration(anyInt(), anyInt()))
+        when(mMockServiceControllerBinder.getRegistration(anyInt()))
                 .thenReturn(mMockRcsRegistration);
         when(mMockMmTelFeature.asBinder()).thenReturn(mMockMmTelBinder);
         when(mMockRcsFeature.asBinder()).thenReturn(mMockRcsBinder);
@@ -174,8 +156,6 @@
         mTestImsServiceController = null;
         // Make sure the handler is empty before finishing the test.
         waitForHandlerAction(mHandler, 1000);
-        mTestImsServiceController = null;
-        mRepo = null;
         super.tearDown();
     }
 
@@ -193,9 +173,7 @@
         ArgumentCaptor<Intent> intentCaptor =
                 ArgumentCaptor.forClass(Intent.class);
 
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        assertTrue(mTestImsServiceController.bind(testFeatures, slotIdToSubIdMap.clone()));
+        assertTrue(mTestImsServiceController.bind(testFeatures));
 
         int expectedFlags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE
                 | Context.BIND_IMPORTANT;
@@ -214,12 +192,10 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>();
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_MMTEL));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        bindAndConnectService(testFeatures);
 
         // already bound, should return false
-        assertFalse(mTestImsServiceController.bind(testFeatures, slotIdToSubIdMap.clone()));
+        assertFalse(mTestImsServiceController.bind(testFeatures));
 
         verify(mMockContext, times(1)).bindService(any(), any(), anyInt());
     }
@@ -237,14 +213,12 @@
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
 
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        bindAndConnectService(testFeatures);
 
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
+        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0, SUB_2);
+        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_RCS), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
@@ -256,132 +230,6 @@
     }
 
     /**
-     * Ensures ImsServiceController removes/adds changes to features that result in the same
-     * feature set with IMS feature when sub ID changed.
-     */
-    @SmallTest
-    @Test
-    public void testCallChangeWithNoNewFeaturesWithSubIdChanged()
-                        throws RemoteException {
-        HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>();
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
-                ImsFeature.FEATURE_RCS));
-
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
-
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0, SUB_2);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_RCS), any());
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_RCS),
-                eq(mTestImsServiceController));
-        validateMmTelFeatureContainerExists(SLOT_0);
-        validateRcsFeatureContainerExists(SLOT_0);
-
-        slotIdToSubIdMap.put(SLOT_0, SUB_3);
-        // ensure remove and add unchanged features that have a slot ID associated with the new
-        // subscription ID.
-        mTestImsServiceController.changeImsServiceFeatures(testFeatures,
-                slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), eq(true));
-        verify(mMockServiceControllerBinder).removeFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_RCS), eq(true));
-        verify(mMockServiceControllerBinder).removeFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_RCS), any());
-        verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_0), eq(ImsFeature.FEATURE_RCS),
-                eq(mTestImsServiceController));
-
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_3);
-        verify(mMockServiceControllerBinder, times(2)).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0, SUB_3);
-        verify(mMockServiceControllerBinder, times(2)).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_RCS), any());
-        verify(mMockCallbacks, times(2)).imsServiceFeatureCreated(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), eq(mTestImsServiceController));
-        verify(mMockCallbacks, times(2)).imsServiceFeatureCreated(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_RCS), eq(mTestImsServiceController));
-        validateMmTelFeatureContainerExists(SLOT_0);
-        validateRcsFeatureContainerExists(SLOT_0);
-    }
-
-    /**
-     * Ensures ImsServiceController removes/adds changes to features that result in the same
-     * feature set with IMS feature when sub ID changed.
-     */
-    @SmallTest
-    @Test
-    public void testCallChangeWithNoNewFeaturesWithAllSubIdChanged()
-                        throws RemoteException {
-        HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>();
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_1,
-                ImsFeature.FEATURE_MMTEL));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        slotIdToSubIdMap.put(SLOT_1, SUB_3);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_1, SUB_3);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_1), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        validateMmTelFeatureContainerExists(SLOT_0);
-        validateMmTelFeatureContainerExists(SLOT_1);
-
-        slotIdToSubIdMap.put(SLOT_0, SUB_4);
-        slotIdToSubIdMap.put(SLOT_1, SUB_5);
-        // ensure remove and add unchanged features that have a slot ID associated with the new
-        // subscription ID.
-        mTestImsServiceController.changeImsServiceFeatures(testFeatures,
-                slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), eq(true));
-        verify(mMockServiceControllerBinder).removeFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), eq(true));
-        verify(mMockServiceControllerBinder).removeFeatureStatusCallback(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_1), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_4);
-        verify(mMockServiceControllerBinder, times(2)).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks, times(2)).imsServiceFeatureCreated(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), eq(mTestImsServiceController));
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_1, SUB_5);
-        verify(mMockServiceControllerBinder, times(2)).addFeatureStatusCallback(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks, times(2)).imsServiceFeatureCreated(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), eq(mTestImsServiceController));
-        validateMmTelFeatureContainerExists(SLOT_0);
-        validateMmTelFeatureContainerExists(SLOT_1);
-    }
-
-    /**
      * Tests ImsServiceController keeps SIP delegate creation flags if MMTEL and RCS are supported.
      */
     @SmallTest
@@ -395,14 +243,12 @@
         when(mMockServiceControllerBinder.getImsServiceCapabilities()).thenReturn(
                 ImsService.CAPABILITY_SIP_DELEGATE_CREATION);
 
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        bindAndConnectService(testFeatures);
 
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
+        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0, SUB_2);
+        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_RCS), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
@@ -427,11 +273,9 @@
         when(mMockServiceControllerBinder.getImsServiceCapabilities()).thenReturn(
                 ImsService.CAPABILITY_SIP_DELEGATE_CREATION);
 
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        bindAndConnectService(testFeatures);
 
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
+        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
@@ -453,39 +297,9 @@
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_MMTEL));
 
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        bindAndConnectService(testFeatures);
 
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_EMERGENCY_MMTEL), eq(mTestImsServiceController));
-        // Make sure this callback happens, which will notify the framework of emergency calling
-        // availability.
-        validateMmTelFeatureContainerExistsWithEmergency(SLOT_0);
-    }
-
-    /**
-     * Tests proper API is called to create MMTEL for Emergency when sub ID is invalid
-     */
-    @SmallTest
-    @Test
-    public void testBindEmergencyMmTelWithInvalidSubId() throws RemoteException {
-        HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>();
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
-                ImsFeature.FEATURE_EMERGENCY_MMTEL));
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
-
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SubscriptionManager.INVALID_SUBSCRIPTION_ID);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
-
-        verify(mMockServiceControllerBinder).createEmergencyOnlyMmTelFeature(SLOT_0);
+        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
@@ -511,12 +325,10 @@
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
 
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        bindAndConnectService(testFeatures);
 
         // Verify no MMTEL or EMERGENCY_MMTEL features are created
-        verify(mMockServiceControllerBinder, never()).createMmTelFeature(SLOT_0, SUB_2);
+        verify(mMockServiceControllerBinder, never()).createMmTelFeature(SLOT_0);
         verify(mMockServiceControllerBinder, never()).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks, never()).imsServiceFeatureCreated(eq(SLOT_0),
@@ -525,7 +337,7 @@
                 eq(ImsFeature.FEATURE_EMERGENCY_MMTEL), eq(mTestImsServiceController));
         validateMmTelFeatureContainerDoesntExist(SLOT_0);
         // verify RCS feature is created
-        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0, SUB_2);
+        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_RCS), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_RCS),
@@ -546,9 +358,7 @@
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_MMTEL));
 
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        bindAndConnectService(testFeatures);
 
         validateMmTelFeatureContainerExistsWithEmergency(SLOT_0);
         validateMmTelFeatureExistsInCallback(SLOT_0, ImsService.CAPABILITY_EMERGENCY_OVER_MMTEL);
@@ -566,9 +376,7 @@
                 ImsFeature.FEATURE_MMTEL));
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        ServiceConnection conn = bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        ServiceConnection conn = bindAndConnectService(testFeatures);
 
         conn.onServiceDisconnected(mTestComponentName);
 
@@ -592,9 +400,7 @@
                 ImsFeature.FEATURE_MMTEL));
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        ServiceConnection conn = bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        ServiceConnection conn = bindAndConnectService(testFeatures);
 
         conn.onServiceDisconnected(mTestComponentName);
 
@@ -629,11 +435,9 @@
         TestCallback cb = new TestCallback();
         mRepo.registerForConnectionUpdates(SLOT_0, ImsFeature.FEATURE_MMTEL, cb, Runnable::run);
 
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        bindAndConnectService(testFeatures);
 
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
+        verify(mMockServiceControllerBinder).createMmTelFeature(eq(SLOT_0));
         ArgumentCaptor<IImsFeatureStatusCallback> captor =
                 ArgumentCaptor.forClass(IImsFeatureStatusCallback.class);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
@@ -660,19 +464,17 @@
                 ImsFeature.FEATURE_MMTEL));
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        ServiceConnection conn = bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        ServiceConnection conn = bindAndConnectService(testFeatures);
 
         mTestImsServiceController.unbind();
 
         verify(mMockContext).unbindService(eq(conn));
         verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), eq(false));
+                eq(ImsFeature.FEATURE_MMTEL));
         verify(mMockServiceControllerBinder).removeFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_RCS), eq(false));
+                eq(ImsFeature.FEATURE_RCS));
         verify(mMockServiceControllerBinder).removeFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_RCS), any());
         verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
@@ -694,9 +496,7 @@
                 ImsFeature.FEATURE_MMTEL));
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        ServiceConnection conn = bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        ServiceConnection conn = bindAndConnectService(testFeatures);
 
         conn.onBindingDied(null /*null*/);
 
@@ -721,9 +521,7 @@
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
 
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndNullServiceError(testFeatures, slotIdToSubIdMap.clone());
+        bindAndNullServiceError(testFeatures);
 
         verify(mMockCallbacks, never()).imsServiceFeatureCreated(anyInt(), anyInt(),
                 eq(mTestImsServiceController));
@@ -738,17 +536,15 @@
     @SmallTest
     @Test
     public void testBindServiceAndImsFeatureReturnedNull() throws RemoteException {
-        when(mMockServiceControllerBinder.createRcsFeature(anyInt(), anyInt()))
+        when(mMockServiceControllerBinder.createRcsFeature(anyInt()))
                 .thenReturn(null);
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>();
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
 
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        bindAndConnectService(testFeatures);
 
-        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0, SUB_2);
+        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0);
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_RCS),
                 eq(mTestImsServiceController));
         validateRcsFeatureContainerDoesntExist(SLOT_0);
@@ -763,11 +559,8 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>();
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_MMTEL));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        slotIdToSubIdMap.put(SLOT_1, SUB_3);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
+        bindAndConnectService(testFeatures);
+        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
@@ -778,48 +571,9 @@
         testFeaturesWithAddition.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_1,
                 ImsFeature.FEATURE_MMTEL));
 
-        mTestImsServiceController.changeImsServiceFeatures(testFeaturesWithAddition,
-                slotIdToSubIdMap.clone());
+        mTestImsServiceController.changeImsServiceFeatures(testFeaturesWithAddition);
 
-        verify(mMockServiceControllerBinder, never()).removeImsFeature(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), eq(true));
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_1, SUB_3);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_1), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        validateMmTelFeatureContainerExists(SLOT_0);
-        validateMmTelFeatureContainerExists(SLOT_1);
-    }
-
-    /**
-     * Ensures IMS features are correctly changed when configuration change from one to two SIMs.
-     */
-    @SmallTest
-    @Test
-    public void testBindService_oneSimToMsim() throws RemoteException {
-        HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>();
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        // Create a new list with an additional item
-        HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeaturesWithAddition = new HashSet<>(
-                testFeatures);
-        testFeaturesWithAddition.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_1,
-                ImsFeature.FEATURE_MMTEL));
-        slotIdToSubIdMap.put(SLOT_1, SUB_3);
-        mTestImsServiceController.changeImsServiceFeatures(testFeaturesWithAddition,
-                slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder, never()).removeImsFeature(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), eq(true));
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_1, SUB_3);
+        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_1);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_1),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_1), eq(ImsFeature.FEATURE_MMTEL),
@@ -839,10 +593,8 @@
                 ImsFeature.FEATURE_MMTEL));
         TestCallback cb = new TestCallback();
         mRepo.registerForConnectionUpdates(SLOT_0, ImsFeature.FEATURE_MMTEL, cb, Runnable::run);
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
+        bindAndConnectService(testFeatures);
+        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
@@ -858,8 +610,7 @@
         testFeaturesWithAddition.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_EMERGENCY_MMTEL));
 
-        mTestImsServiceController.changeImsServiceFeatures(testFeaturesWithAddition,
-                slotIdToSubIdMap.clone());
+        mTestImsServiceController.changeImsServiceFeatures(testFeaturesWithAddition);
 
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_EMERGENCY_MMTEL),
@@ -871,8 +622,7 @@
                 | cb.container.getCapabilities()) > 0);
 
         // Remove Emergency calling
-        mTestImsServiceController.changeImsServiceFeatures(testFeatures,
-                slotIdToSubIdMap.clone());
+        mTestImsServiceController.changeImsServiceFeatures(testFeatures);
 
         verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_EMERGENCY_MMTEL),
@@ -893,10 +643,8 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>();
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0, SUB_2);
+        bindAndConnectService(testFeatures);
+        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_RCS), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_RCS),
@@ -908,11 +656,9 @@
         testFeaturesWithAddition.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_1,
                 ImsFeature.FEATURE_EMERGENCY_MMTEL));
 
-        slotIdToSubIdMap.put(SLOT_1, SUB_3);
-        mTestImsServiceController.changeImsServiceFeatures(testFeaturesWithAddition,
-                slotIdToSubIdMap.clone());
+        mTestImsServiceController.changeImsServiceFeatures(testFeaturesWithAddition);
 
-        verify(mMockServiceControllerBinder, never()).createMmTelFeature(SLOT_1, SUB_3);
+        verify(mMockServiceControllerBinder, never()).createMmTelFeature(SLOT_1);
         verify(mMockServiceControllerBinder, never()).addFeatureStatusCallback(eq(SLOT_1),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks, never()).imsServiceFeatureCreated(eq(SLOT_1),
@@ -931,10 +677,8 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>();
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_MMTEL));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
+        bindAndConnectService(testFeatures);
+        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
@@ -942,13 +686,12 @@
         validateMmTelFeatureContainerExists(SLOT_0);
 
         // Call change with the same features and make sure it is disregarded
-        mTestImsServiceController.changeImsServiceFeatures(testFeatures, slotIdToSubIdMap.clone());
+        mTestImsServiceController.changeImsServiceFeatures(testFeatures);
 
-        verify(mMockServiceControllerBinder, times(1)).createMmTelFeature(SLOT_0, SUB_2);
+        verify(mMockServiceControllerBinder, times(1)).createMmTelFeature(SLOT_0);
         verify(mMockServiceControllerBinder, times(1)).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockServiceControllerBinder, never()).removeImsFeature(anyInt(), anyInt(),
-                eq(true));
+        verify(mMockServiceControllerBinder, never()).removeImsFeature(anyInt(), anyInt());
 
 
         verify(mMockServiceControllerBinder, never()).removeFeatureStatusCallback(anyInt(),
@@ -960,54 +703,6 @@
     }
 
     /**
-     * Ensures IMS features are correctly changed when configuration change from two SIMs to one.
-     */
-    @SmallTest
-    @Test
-    public void testBindService_MsimToOneSim() throws RemoteException {
-        HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>();
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_1,
-                ImsFeature.FEATURE_MMTEL));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        slotIdToSubIdMap.put(SLOT_1, SUB_3);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_1, SUB_3);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_1), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        validateMmTelFeatureContainerExists(SLOT_0);
-        validateMmTelFeatureContainerExists(SLOT_1);
-        // Create a new list with one less item
-        HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeaturesWithSubtraction =
-                new HashSet<>(testFeatures);
-        testFeaturesWithSubtraction.remove(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_1,
-                ImsFeature.FEATURE_MMTEL));
-
-        slotIdToSubIdMap.delete(SLOT_1);
-        mTestImsServiceController.changeImsServiceFeatures(testFeaturesWithSubtraction,
-                slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder, never()).removeImsFeature(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), eq(false));
-        verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), eq(false));
-        verify(mMockServiceControllerBinder).removeFeatureStatusCallback(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_1), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        validateMmTelFeatureContainerExists(SLOT_0);
-        validateMmTelFeatureContainerDoesntExist(SLOT_1);
-    }
-
-    /**
      * Ensures ImsService and ImsResolver are notified when a feature is added and then removed.
      */
     @SmallTest
@@ -1018,16 +713,13 @@
                 ImsFeature.FEATURE_MMTEL));
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_1,
                 ImsFeature.FEATURE_MMTEL));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        slotIdToSubIdMap.put(SLOT_1, SUB_3);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
+        bindAndConnectService(testFeatures);
+        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
                 eq(mTestImsServiceController));
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_1, SUB_3);
+        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_1);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_1),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_1), eq(ImsFeature.FEATURE_MMTEL),
@@ -1040,11 +732,10 @@
         testFeaturesWithSubtraction.remove(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_1,
                 ImsFeature.FEATURE_MMTEL));
 
-        mTestImsServiceController.changeImsServiceFeatures(testFeaturesWithSubtraction,
-                slotIdToSubIdMap.clone());
+        mTestImsServiceController.changeImsServiceFeatures(testFeaturesWithSubtraction);
 
         verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), eq(false));
+                eq(ImsFeature.FEATURE_MMTEL));
         verify(mMockServiceControllerBinder).removeFeatureStatusCallback(eq(SLOT_1),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_1), eq(ImsFeature.FEATURE_MMTEL),
@@ -1054,97 +745,6 @@
     }
 
     /**
-     * Ensures removed feature is actually removed and remove/add unchanged features that have a
-     * slot ID associated with new subscription ID.
-     */
-    @SmallTest
-    @Test
-    public void testBindServiceAndRemoveFeatureWithSubIdChanged() throws RemoteException {
-        HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>();
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
-                ImsFeature.FEATURE_MMTEL));
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_1,
-                ImsFeature.FEATURE_MMTEL));
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
-                ImsFeature.FEATURE_RCS));
-        testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_1,
-                ImsFeature.FEATURE_RCS));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        slotIdToSubIdMap.put(SLOT_1, SUB_3);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0, SUB_2);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_RCS), any());
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_RCS),
-                eq(mTestImsServiceController));
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_1, SUB_3);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_1), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_1, SUB_3);
-        verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_RCS), any());
-        verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_1), eq(ImsFeature.FEATURE_RCS),
-                eq(mTestImsServiceController));
-        validateMmTelFeatureContainerExists(SLOT_0);
-        validateMmTelFeatureContainerExists(SLOT_1);
-        validateRcsFeatureContainerExists(SLOT_0);
-        validateRcsFeatureContainerExists(SLOT_1);
-
-        // Create a new list with one less item
-        HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeaturesWithSubtraction =
-                new HashSet<>(testFeatures);
-        testFeaturesWithSubtraction.remove(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_1,
-                ImsFeature.FEATURE_MMTEL));
-        slotIdToSubIdMap.put(SLOT_0, SUB_4);
-        mTestImsServiceController.changeImsServiceFeatures(testFeaturesWithSubtraction,
-                slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), eq(false));
-        verify(mMockServiceControllerBinder).removeFeatureStatusCallback(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_1), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        validateMmTelFeatureContainerExists(SLOT_0);
-        validateMmTelFeatureContainerDoesntExist(SLOT_1);
-        // ensure remove and add unchanged features that have a slot ID associated with the new
-        // subscription ID.
-        verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), eq(true));
-        verify(mMockServiceControllerBinder).removeFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
-                eq(mTestImsServiceController));
-        verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_RCS), eq(true));
-        verify(mMockServiceControllerBinder).removeFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_RCS), any());
-        verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_0), eq(ImsFeature.FEATURE_RCS),
-                eq(mTestImsServiceController));
-
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_4);
-        verify(mMockServiceControllerBinder, times(2)).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), any());
-        verify(mMockCallbacks, times(2)).imsServiceFeatureCreated(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), eq(mTestImsServiceController));
-        verify(mMockServiceControllerBinder).createRcsFeature(SLOT_0, SUB_4);
-        verify(mMockServiceControllerBinder, times(2)).addFeatureStatusCallback(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_RCS), any());
-        verify(mMockCallbacks, times(2)).imsServiceFeatureCreated(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_RCS), eq(mTestImsServiceController));
-        validateMmTelFeatureContainerExists(SLOT_0);
-        validateRcsFeatureContainerExists(SLOT_0);
-        validateRcsFeatureContainerExists(SLOT_1);
-    }
-
-    /**
      * Ensures ImsService and ImsResolver are notified when all features are removed.
      */
     @SmallTest
@@ -1155,16 +755,13 @@
                 ImsFeature.FEATURE_MMTEL));
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_1,
                 ImsFeature.FEATURE_MMTEL));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        slotIdToSubIdMap.put(SLOT_1, SUB_3);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0, SUB_2);
+        bindAndConnectService(testFeatures);
+        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_0);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
                 eq(mTestImsServiceController));
-        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_1, SUB_3);
+        verify(mMockServiceControllerBinder).createMmTelFeature(SLOT_1);
         verify(mMockServiceControllerBinder).addFeatureStatusCallback(eq(SLOT_1),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks).imsServiceFeatureCreated(eq(SLOT_1), eq(ImsFeature.FEATURE_MMTEL),
@@ -1173,17 +770,16 @@
         validateMmTelFeatureContainerExists(SLOT_1);
 
         // Create a new empty list
-        mTestImsServiceController.changeImsServiceFeatures(new HashSet<>(),
-                slotIdToSubIdMap.clone());
+        mTestImsServiceController.changeImsServiceFeatures(new HashSet<>());
 
         verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_0),
-                eq(ImsFeature.FEATURE_MMTEL), eq(false));
+                eq(ImsFeature.FEATURE_MMTEL));
         verify(mMockServiceControllerBinder).removeFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_0), eq(ImsFeature.FEATURE_MMTEL),
                 eq(mTestImsServiceController));
         verify(mMockServiceControllerBinder).removeImsFeature(eq(SLOT_1),
-                eq(ImsFeature.FEATURE_MMTEL), eq(false));
+                eq(ImsFeature.FEATURE_MMTEL));
         verify(mMockServiceControllerBinder).removeFeatureStatusCallback(eq(SLOT_1),
                 eq(ImsFeature.FEATURE_MMTEL), any());
         verify(mMockCallbacks).imsServiceFeatureRemoved(eq(SLOT_1), eq(ImsFeature.FEATURE_MMTEL),
@@ -1201,9 +797,7 @@
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures = new HashSet<>();
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_MMTEL));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        bindAndConnectService(testFeatures);
         mTestImsServiceController.unbind();
         // Create a new list with an additional item
         HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeaturesWithAddition = new HashSet<>(
@@ -1212,10 +806,9 @@
         testFeaturesWithAddition.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
 
-        mTestImsServiceController.changeImsServiceFeatures(testFeaturesWithAddition,
-                slotIdToSubIdMap.clone());
+        mTestImsServiceController.changeImsServiceFeatures(testFeaturesWithAddition);
 
-        verify(mMockServiceControllerBinder, never()).createRcsFeature(SLOT_0, SUB_2);
+        verify(mMockServiceControllerBinder, never()).createRcsFeature(eq(SLOT_0));
         verify(mMockServiceControllerBinder, never()).removeFeatureStatusCallback(eq(SLOT_0),
                 eq(ImsFeature.FEATURE_RCS), any());
         verify(mMockCallbacks, never()).imsServiceFeatureCreated(eq(SLOT_0),
@@ -1236,9 +829,7 @@
                 ImsFeature.FEATURE_MMTEL));
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        ServiceConnection conn = bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        ServiceConnection conn = bindAndConnectService(testFeatures);
 
         conn.onBindingDied(null /*null*/);
 
@@ -1260,9 +851,7 @@
                 ImsFeature.FEATURE_MMTEL));
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        ServiceConnection conn = bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        ServiceConnection conn = bindAndConnectService(testFeatures);
 
         conn.onBindingDied(null);
         // null binding should be ignored in this case.
@@ -1285,9 +874,7 @@
                 ImsFeature.FEATURE_MMTEL));
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        ServiceConnection conn = bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        ServiceConnection conn = bindAndConnectService(testFeatures);
 
         conn.onBindingDied(null /*null*/);
 
@@ -1306,9 +893,7 @@
                 ImsFeature.FEATURE_MMTEL));
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        ServiceConnection conn = bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        ServiceConnection conn = bindAndConnectService(testFeatures);
 
         conn.onBindingDied(null /*null*/);
         mTestImsServiceController.unbind();
@@ -1332,11 +917,9 @@
                 ImsFeature.FEATURE_MMTEL));
         testFeatures.add(new ImsFeatureConfiguration.FeatureSlotPair(SLOT_0,
                 ImsFeature.FEATURE_RCS));
-        SparseIntArray slotIdToSubIdMap = new SparseIntArray();
-        slotIdToSubIdMap.put(SLOT_0, SUB_2);
-        ServiceConnection conn = bindAndConnectService(testFeatures, slotIdToSubIdMap.clone());
+        ServiceConnection conn = bindAndConnectService(testFeatures);
         conn.onBindingDied(null /*null*/);
-        mTestImsServiceController.bind(testFeatures, slotIdToSubIdMap.clone());
+        mTestImsServiceController.bind(testFeatures);
 
         long delay = mTestImsServiceController.getRebindDelay();
         waitForHandlerActionDelayed(mHandler, delay, 2 * delay);
@@ -1406,16 +989,14 @@
     }
 
     private void bindAndNullServiceError(
-            HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures,
-            SparseIntArray slotIdToSubIdMap) {
-        ServiceConnection connection = bindService(testFeatures, slotIdToSubIdMap);
+            HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures) {
+        ServiceConnection connection = bindService(testFeatures);
         connection.onNullBinding(mTestComponentName);
     }
 
     private ServiceConnection bindAndConnectService(
-            HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures,
-            SparseIntArray slotIdToSubIdMap) {
-        ServiceConnection connection = bindService(testFeatures, slotIdToSubIdMap);
+            HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures) {
+        ServiceConnection connection = bindService(testFeatures);
         IImsServiceController.Stub controllerStub = mock(IImsServiceController.Stub.class);
         when(controllerStub.queryLocalInterface(any())).thenReturn(mMockServiceControllerBinder);
         connection.onServiceConnected(mTestComponentName, controllerStub);
@@ -1423,11 +1004,10 @@
     }
 
     private ServiceConnection bindService(
-            HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures,
-            SparseIntArray slotIdToSubIdMap) {
+            HashSet<ImsFeatureConfiguration.FeatureSlotPair> testFeatures) {
         ArgumentCaptor<ServiceConnection> serviceCaptor =
                 ArgumentCaptor.forClass(ServiceConnection.class);
-        assertTrue(mTestImsServiceController.bind(testFeatures, slotIdToSubIdMap));
+        assertTrue(mTestImsServiceController.bind(testFeatures));
         verify(mMockContext).bindService(any(), serviceCaptor.capture(), anyInt());
         return serviceCaptor.getValue();
     }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsTestBase.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsTestBase.java
index 63fcf10..086390a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsTestBase.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsTestBase.java
@@ -25,8 +25,6 @@
 
 import androidx.test.InstrumentationRegistry;
 
-import com.android.internal.telephony.TelephonyTest;
-
 import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
@@ -44,7 +42,6 @@
     protected TestableLooper mTestableLooper;
 
     public void setUp() throws Exception {
-        TelephonyTest.enableStrictMode();
         mContext = InstrumentationRegistry.getTargetContext();
         MockitoAnnotations.initMocks(this);
         // Set up the looper if it does not exist on the test thread.
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsVideoProviderWrapperTest.java b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsVideoProviderWrapperTest.java
index 99d1ce4..beeeefa 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ims/ImsVideoProviderWrapperTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ims/ImsVideoProviderWrapperTest.java
@@ -17,7 +17,6 @@
 package com.android.internal.telephony.ims;
 
 import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.telecom.VideoProfile;
@@ -30,10 +29,11 @@
 
 import junit.framework.TestCase;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 /**
  * Tests for the {@link com.android.ims.internal.VideoPauseTracker} class.
@@ -41,26 +41,19 @@
 @RunWith(AndroidJUnit4.class)
 public class ImsVideoProviderWrapperTest extends TestCase {
     private ImsVideoCallProviderWrapper mImsVideoCallProviderWrapper;
-
-    // Mocked classes
+    @Mock
     VideoPauseTracker mVideoPauseTracker;
 
     @Before
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        mVideoPauseTracker = mock(VideoPauseTracker.class);
+        MockitoAnnotations.initMocks(this);
         mImsVideoCallProviderWrapper = new ImsVideoCallProviderWrapper(null, mVideoPauseTracker);
         when(mVideoPauseTracker.shouldPauseVideoFor(anyInt())).thenReturn(true);
         when(mVideoPauseTracker.shouldResumeVideoFor(anyInt())).thenReturn(true);
     }
 
-    @After
-    @Override
-    public void tearDown() throws Exception {
-        mImsVideoCallProviderWrapper = null;
-    }
-
     @SmallTest
     @Test
     public void testIsPause() {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallTest.java
index d665264..306a503 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsCallTest.java
@@ -22,8 +22,6 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
@@ -44,27 +42,20 @@
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 
-import java.util.concurrent.Executor;
-
 public class ImsCallTest extends TelephonyTest {
 
     private Bundle mBundle;
     private ImsCallProfile mTestCallProfile;
 
-    private final Executor mExecutor = Runnable::run;
-
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
         mTestCallProfile = new ImsCallProfile();
         mBundle = mTestCallProfile.mCallExtras;
-        doReturn(mExecutor).when(mContext).getMainExecutor();
     }
 
     @After
     public void tearDown() throws Exception {
-        mBundle = null;
-        mTestCallProfile = null;
         super.tearDown();
     }
 
@@ -79,7 +70,7 @@
 
         ArgumentCaptor<ImsCallSession.Listener> listenerCaptor =
                 ArgumentCaptor.forClass(ImsCallSession.Listener.class);
-        verify(mockSession).setListener(listenerCaptor.capture(), any());
+        verify(mockSession).setListener(listenerCaptor.capture());
         ImsCallSession.Listener listener = listenerCaptor.getValue();
         assertNotNull(listener);
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsExternalCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsExternalCallTrackerTest.java
index 475ebea..7c9f01a 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsExternalCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsExternalCallTrackerTest.java
@@ -18,7 +18,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import android.net.Uri;
@@ -30,11 +29,12 @@
 import com.android.internal.telephony.Call;
 import com.android.internal.telephony.Connection;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -47,25 +47,18 @@
     private static final int CALL_ID = 1;
 
     ImsExternalCallTracker mTracker;
-
-    // Mocked classes
+    @Mock
     ImsPhone mImsPhone;
+    @Mock
     ImsPullCall mImsPullCall;
+    @Mock
     ImsExternalCallTracker.ImsCallNotify mCallNotifier;
 
     @Before
     public void setUp() throws Exception {
-        mImsPhone = mock(ImsPhone.class);
-        mImsPullCall = mock(ImsPullCall.class);
-        mCallNotifier = mock(ImsExternalCallTracker.ImsCallNotify.class);
+        MockitoAnnotations.initMocks(this);
 
-        mTracker = new ImsExternalCallTracker(mImsPhone, mImsPullCall, mCallNotifier,
-            Runnable::run);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mTracker = null;
+        mTracker = new ImsExternalCallTracker(mImsPhone, mImsPullCall, mCallNotifier);
     }
 
     @FlakyTest
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java
index c2db93f..68ba403 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTest.java
@@ -21,7 +21,6 @@
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -41,10 +40,12 @@
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
+import org.mockito.Mock;
 
 public class ImsPhoneCallTest extends TelephonyTest {
-    // Mocked classes
+    @Mock
     ImsPhoneConnection mConnection1;
+    @Mock
     ImsPhoneConnection mConnection2;
 
     ImsStreamMediaProfile mMediaProfile;
@@ -54,8 +55,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mConnection1 = mock(ImsPhoneConnection.class);
-        mConnection2 = mock(ImsPhoneConnection.class);
         replaceInstance(ImsPhoneCallTracker.class, "mPhone", mImsCT, mImsPhone);
 
         mImsCallUT = new ImsPhoneCall(mImsCT, ImsPhoneCall.CONTEXT_FOREGROUND);
@@ -66,7 +65,6 @@
     @After
     public void tearDown() throws Exception {
         mImsCallUT = null;
-        mMediaProfile = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
index 95eedc2..d1826d5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneCallTrackerTest.java
@@ -28,7 +28,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.anyString;
@@ -51,9 +50,7 @@
 import static org.mockito.Mockito.when;
 
 import android.annotation.Nullable;
-import android.content.BroadcastReceiver;
 import android.content.Context;
-import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.pm.PackageManager;
 import android.net.NetworkStats;
@@ -67,7 +64,6 @@
 import android.telephony.CarrierConfigManager;
 import android.telephony.DisconnectCause;
 import android.telephony.PhoneNumberUtils;
-import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsCallSession;
@@ -79,7 +75,6 @@
 import android.telephony.ims.feature.ImsFeature;
 import android.telephony.ims.feature.MmTelFeature;
 import android.telephony.ims.stub.ImsRegistrationImplBase;
-import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -96,7 +91,6 @@
 import com.android.internal.telephony.CallStateException;
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.Connection;
-import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.PhoneConstants;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.d2d.RtpTransport;
@@ -109,11 +103,12 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 import java.util.Set;
-import java.util.concurrent.Executor;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -125,61 +120,75 @@
     private ImsCall.Listener mImsCallListener;
     private ImsCall mImsCall;
     private ImsCall mSecondImsCall;
-    private BroadcastReceiver mBroadcastReceiver;
     private Bundle mBundle = new Bundle();
-    private static final int SUB_0 = 0;
     @Nullable private VtDataUsageProvider mVtDataUsageProvider;
-
-    // Mocked classes
-    private ArgumentCaptor<Set<RtpHeaderExtensionType>> mRtpHeaderExtensionTypeCaptor;
-    private FeatureConnector<ImsManager> mMockConnector;
+    @Mock
     private ImsCallSession mImsCallSession;
+    @Mock
     private SharedPreferences mSharedPreferences;
+    @Mock
     private ImsPhoneConnection.Listener mImsPhoneConnectionListener;
+    @Mock
     private ImsConfig mImsConfig;
+    @Mock
     private ImsPhoneConnection mImsPhoneConnection;
+    @Mock
     private INetworkStatsProviderCallback mVtDataUsageProviderCb;
+    @Mock
     private ImsPhoneCallTracker.ConnectorFactory mConnectorFactory;
-
-    private final Executor mExecutor = Runnable::run;
+    @Mock
+    private FeatureConnector<ImsManager> mMockConnector;
+    @Captor
+    private ArgumentCaptor<Set<RtpHeaderExtensionType>> mRtpHeaderExtensionTypeCaptor;
 
     private void imsCallMocking(final ImsCall imsCall) throws Exception {
 
-        doAnswer((Answer<Void>) invocation -> {
-            // trigger the listener on accept call
-            if (mImsCallListener != null) {
-                mImsCallListener.onCallStarted(imsCall);
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // trigger the listener on accept call
+                if (mImsCallListener != null) {
+                    mImsCallListener.onCallStarted(imsCall);
+                }
+                return null;
             }
-            return null;
         }).when(imsCall).accept(anyInt());
 
-        doAnswer((Answer<Void>) invocation -> {
-            // trigger the listener on reject call
-            int reasonCode = (int) invocation.getArguments()[0];
-            if (mImsCallListener != null) {
-                mImsCallListener.onCallStartFailed(imsCall, new ImsReasonInfo(reasonCode, -1));
-                mImsCallListener.onCallTerminated(imsCall, new ImsReasonInfo(reasonCode, -1));
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // trigger the listener on reject call
+                int reasonCode = (int) invocation.getArguments()[0];
+                if (mImsCallListener != null) {
+                    mImsCallListener.onCallStartFailed(imsCall, new ImsReasonInfo(reasonCode, -1));
+                    mImsCallListener.onCallTerminated(imsCall, new ImsReasonInfo(reasonCode, -1));
+                }
+                return null;
             }
-            return null;
         }).when(imsCall).reject(anyInt());
 
-        doAnswer((Answer<Void>) invocation -> {
-            // trigger the listener on reject call
-            int reasonCode = (int) invocation.getArguments()[0];
-            if (mImsCallListener != null) {
-                mImsCallListener.onCallTerminated(imsCall, new ImsReasonInfo(reasonCode, -1));
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                // trigger the listener on reject call
+                int reasonCode = (int) invocation.getArguments()[0];
+                if (mImsCallListener != null) {
+                    mImsCallListener.onCallTerminated(imsCall, new ImsReasonInfo(reasonCode, -1));
+                }
+                return null;
             }
-            return null;
         }).when(imsCall).terminate(anyInt());
 
-        doAnswer((Answer<Void>) invocation -> {
-            if (mImsCallListener != null) {
-                mImsCallListener.onCallHeld(imsCall);
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                if (mImsCallListener != null) {
+                    mImsCallListener.onCallHeld(imsCall);
+                }
+                return null;
             }
-            return null;
         }).when(imsCall).hold();
 
-        doReturn(mExecutor).when(mContext).getMainExecutor();
         imsCall.attachSession(mImsCallSession);
         doReturn("1").when(mImsCallSession).getCallId();
         doReturn(mImsCallProfile).when(mImsCallSession).getCallProfile();
@@ -187,14 +196,7 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mRtpHeaderExtensionTypeCaptor = ArgumentCaptor.forClass(Set.class);
-        mMockConnector = mock(FeatureConnector.class);
-        mImsCallSession = mock(ImsCallSession.class);
-        mSharedPreferences = mock(SharedPreferences.class);
-        mImsConfig = mock(ImsConfig.class);
-        mVtDataUsageProviderCb = mock(INetworkStatsProviderCallback.class);
-        mConnectorFactory = mock(ImsPhoneCallTracker.ConnectorFactory.class);
+        super.setUp(this.getClass().getSimpleName());
         mImsCallProfile.mCallExtras = mBundle;
         mImsCall = spy(new ImsCall(mContext, mImsCallProfile));
         mSecondImsCall = spy(new ImsCall(mContext, mImsCallProfile));
@@ -211,19 +213,26 @@
             return null;
         }).when(mImsManager).open(any(), any(), any());
 
-        doAnswer((Answer<ImsCall>) invocation -> {
-            mImsCallListener =
-                    (ImsCall.Listener) invocation.getArguments()[1];
-            mImsCall.setListener(mImsCallListener);
-            return mImsCall;
+        doAnswer(new Answer<ImsCall>() {
+            @Override
+            public ImsCall answer(InvocationOnMock invocation) throws Throwable {
+                mImsCallListener =
+                        (ImsCall.Listener) invocation.getArguments()[1];
+                mImsCall.setListener(mImsCallListener);
+                return mImsCall;
+            }
         }).when(mImsManager).takeCall(any(), any());
 
-        doAnswer((Answer<ImsCall>) invocation -> {
-            mImsCallListener =
-                    (ImsCall.Listener) invocation.getArguments()[2];
-            mSecondImsCall.setListener(mImsCallListener);
-            return mSecondImsCall;
-        }).when(mImsManager).makeCall(eq(mImsCallProfile), any(), any());
+        doAnswer(new Answer<ImsCall>() {
+            @Override
+            public ImsCall answer(InvocationOnMock invocation) throws Throwable {
+                mImsCallListener =
+                        (ImsCall.Listener) invocation.getArguments()[2];
+                mSecondImsCall.setListener(mImsCallListener);
+                return mSecondImsCall;
+            }
+        }).when(mImsManager).makeCall(eq(mImsCallProfile), (String[]) any(),
+                (ImsCall.Listener) any());
 
         doAnswer(invocation -> {
             mCapabilityCallback = (ImsMmTelManager.CapabilityCallback) invocation.getArguments()[0];
@@ -241,6 +250,19 @@
         }).when(mConnectorFactory).create(any(), anyInt(), anyString(), any(), any());
 
         mCTUT = new ImsPhoneCallTracker(mImsPhone, mConnectorFactory, Runnable::run);
+        mCTUT.addReasonCodeRemapping(null, "Wifi signal lost.", ImsReasonInfo.CODE_WIFI_LOST);
+        mCTUT.addReasonCodeRemapping(501, "Call answered elsewhere.",
+                ImsReasonInfo.CODE_ANSWERED_ELSEWHERE);
+        mCTUT.addReasonCodeRemapping(510, "Call answered elsewhere.",
+                ImsReasonInfo.CODE_ANSWERED_ELSEWHERE);
+        mCTUT.addReasonCodeRemapping(ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, "",
+                ImsReasonInfo.CODE_SIP_FORBIDDEN);
+        mCTUT.addReasonCodeRemapping(ImsReasonInfo.CODE_SIP_SERVICE_UNAVAILABLE,
+                "emergency calls over wifi not allowed in this location",
+                ImsReasonInfo.CODE_EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE);
+        mCTUT.addReasonCodeRemapping(ImsReasonInfo.CODE_SIP_FORBIDDEN,
+                "service not allowed in this location",
+                ImsReasonInfo.CODE_WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION);
         mCTUT.setDataEnabled(true);
 
         final ArgumentCaptor<VtDataUsageProvider> vtDataUsageProviderCaptor =
@@ -250,31 +272,17 @@
         mVtDataUsageProvider = vtDataUsageProviderCaptor.getValue();
         assertNotNull(mVtDataUsageProvider);
         mVtDataUsageProvider.setProviderCallbackBinder(mVtDataUsageProviderCb);
-        final ArgumentCaptor<BroadcastReceiver> receiverCaptor =
-                ArgumentCaptor.forClass(BroadcastReceiver.class);
-        verify(mContext).registerReceiver(receiverCaptor.capture(), any());
-        mBroadcastReceiver = receiverCaptor.getValue();
-        assertNotNull(mBroadcastReceiver);
 
         logd("ImsPhoneCallTracker initiated");
         processAllMessages();
 
         verify(mMockConnector).connect();
-        mConnectorListener.connectionReady(mImsManager, SUB_0);
+        mConnectorListener.connectionReady(mImsManager);
     }
 
     @After
     public void tearDown() throws Exception {
         mCTUT = null;
-        mMmTelListener = null;
-        mConnectorListener = null;
-        mCapabilityCallback = null;
-        mImsCallListener = null;
-        mImsCall = null;
-        mSecondImsCall = null;
-        mBroadcastReceiver = null;
-        mBundle = null;
-        mVtDataUsageProvider = null;
         super.tearDown();
     }
 
@@ -346,169 +354,7 @@
 
     @Test
     @SmallTest
-    public void testCarrierConfigLoadSubscription() throws Exception {
-        // Start with there being no subId loaded, so SubscriptionController#isActiveSubId is false
-        // as part of setup, connectionReady is called, which ends up calling
-        // updateCarrierConfiguration. Since the carrier config is not report carrier identified
-        // config, we should not see updateImsServiceConfig called yet.
-        verify(mImsManager, never()).updateImsServiceConfig();
-        // Send disconnected indication
-        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
-
-        // Receive a subscription loaded and IMS connection ready indication.
-        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
-        mContextFixture.getCarrierConfigBundle().putBoolean(
-                CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
-        sendCarrierConfigChanged();
-        // CarrierConfigLoader has signalled that the carrier config has been applied for a specific
-        // subscription. This will trigger unavailable -> ready indications.
-        mConnectorListener.connectionReady(mImsManager, SUB_0);
-        processAllMessages();
-        verify(mImsManager).updateImsServiceConfig();
-    }
-
-    @Test
-    @SmallTest
-    public void testCarrierConfigSentLocked() throws Exception {
-        // move to ImsService unavailable state.
-        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
-        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
-        mContextFixture.getCarrierConfigBundle().putBoolean(
-                CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
-
-        sendCarrierConfigChanged();
-        // No ImsService connected, so this will cache the config.
-        verify(mImsManager, never()).updateImsServiceConfig();
-
-        // Connect to ImsService, but sim is locked, so ensure we do not send configs yet
-        doReturn(mIccCard).when(mPhone).getIccCard();
-        doReturn(IccCardConstants.State.PIN_REQUIRED).when(mIccCard).getState();
-        mConnectorListener.connectionReady(mImsManager, SUB_0);
-        processAllMessages();
-        verify(mImsManager, never()).updateImsServiceConfig();
-
-        // Now move to ready and simulate carrier config change in response to SIM state change.
-        doReturn(IccCardConstants.State.READY).when(mIccCard).getState();
-        sendCarrierConfigChanged();
-        verify(mImsManager).updateImsServiceConfig();
-    }
-
-    @Test
-    @SmallTest
-    public void testCarrierConfigSentAfterReady() throws Exception {
-        verify(mImsManager, never()).updateImsServiceConfig();
-
-        // Receive a subscription loaded and IMS connection ready indication.
-        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
-        mContextFixture.getCarrierConfigBundle().putBoolean(
-                CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
-        // CarrierConfigLoader has signalled that the carrier config has been applied for a specific
-        // subscription. This will trigger unavailable -> ready indications.
-        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
-        mConnectorListener.connectionReady(mImsManager, SUB_0);
-        processAllMessages();
-        // Did not receive carrier config changed yet
-        verify(mImsManager, never()).updateImsServiceConfig();
-        sendCarrierConfigChanged();
-        processAllMessages();
-        verify(mImsManager).updateImsServiceConfig();
-    }
-
-    @Test
-    @SmallTest
-    public void testCarrierConfigSentBeforeReady() throws Exception {
-        // move to ImsService unavailable state.
-        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
-        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
-        mContextFixture.getCarrierConfigBundle().putBoolean(
-                CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
-
-        sendCarrierConfigChanged();
-        // No ImsService connected, so this will cache the config.
-        verify(mImsManager, never()).updateImsServiceConfig();
-
-        // Connect to ImsService and ensure that the pending carrier config change is processed
-        // properly.
-        mConnectorListener.connectionReady(mImsManager, SUB_0);
-        processAllMessages();
-        verify(mImsManager).updateImsServiceConfig();
-    }
-
-    @Test
-    @SmallTest
-    public void testCarrierConfigSentAfterReadyAndCrash() throws Exception {
-        verify(mImsManager, never()).updateImsServiceConfig();
-
-        // Receive a subscription loaded and IMS connection ready indication.
-        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
-        mContextFixture.getCarrierConfigBundle().putBoolean(
-                CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
-        // CarrierConfigLoader has signalled that the carrier config has been applied for a specific
-        // subscription. This will trigger unavailable -> ready indications.
-        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
-        mConnectorListener.connectionReady(mImsManager, SUB_0);
-        processAllMessages();
-        // Did not receive carrier config changed yet
-        verify(mImsManager, never()).updateImsServiceConfig();
-        sendCarrierConfigChanged();
-        processAllMessages();
-        // ImsService crashes and reconnects
-        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
-        mConnectorListener.connectionReady(mImsManager, SUB_0);
-        processAllMessages();
-        verify(mImsManager, times(2)).updateImsServiceConfig();
-    }
-
-    @Test
-    @SmallTest
-    public void testCarrierConfigSentBeforeReadyAndCrash() throws Exception {
-        // move to ImsService unavailable state.
-        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
-        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
-        mContextFixture.getCarrierConfigBundle().putBoolean(
-                CarrierConfigManager.KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
-
-        sendCarrierConfigChanged();
-        // No ImsService connected, so this will cache the config.
-        verify(mImsManager, never()).updateImsServiceConfig();
-
-        // Connect to ImsService and then simulate a crash recovery. We should make sure that the
-        // configs are sent again after recovery.
-        mConnectorListener.connectionReady(mImsManager, SUB_0);
-        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
-        mConnectorListener.connectionReady(mImsManager, SUB_0);
-        processAllMessages();
-        verify(mImsManager, times(2)).updateImsServiceConfig();
-    }
-
-    @Test
-    @SmallTest
     public void testImsMTCall() {
-        ImsPhoneConnection connection = setupRingingConnection();
-        assertEquals(android.telecom.Connection.VERIFICATION_STATUS_PASSED,
-                connection.getNumberVerificationStatus());
-    }
-
-    @Test
-    @SmallTest
-    public void testImsMTCallMissed() {
-        ImsPhoneConnection connection = setupRingingConnection();
-        mImsCallListener.onCallTerminated(connection.getImsCall(),
-                new ImsReasonInfo(ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, 0));
-        assertEquals(DisconnectCause.INCOMING_MISSED, connection.getDisconnectCause());
-    }
-
-    @Test
-    @SmallTest
-    public void testImsMTCallRejected() {
-        ImsPhoneConnection connection = setupRingingConnection();
-        connection.onHangupLocal();
-        mImsCallListener.onCallTerminated(connection.getImsCall(),
-                new ImsReasonInfo(ImsReasonInfo.CODE_SIP_REQUEST_TIMEOUT, 0));
-        assertEquals(DisconnectCause.INCOMING_REJECTED, connection.getDisconnectCause());
-    }
-
-    private ImsPhoneConnection setupRingingConnection() {
         mImsCallProfile.setCallerNumberVerificationStatus(
                 ImsCallProfile.VERIFICATION_STATUS_PASSED);
         assertEquals(PhoneConstants.State.IDLE, mCTUT.getState());
@@ -525,7 +371,6 @@
         connection.addListener(mImsPhoneConnectionListener);
         assertEquals(android.telecom.Connection.VERIFICATION_STATUS_PASSED,
                 connection.getNumberVerificationStatus());
-        return connection;
     }
 
     @Test
@@ -550,10 +395,6 @@
     @Test
     @SmallTest
     public void testImsCepOnPeer() throws Exception {
-        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
-        bundle.putBoolean(
-                CarrierConfigManager.KEY_SUPPORT_IMS_CONFERENCE_EVENT_PACKAGE_ON_PEER_BOOL, true);
-        mCTUT.updateCarrierConfigCache(bundle);
         testImsMTCallAccept();
         doReturn(false).when(mImsCall).isConferenceHost();
         doReturn(true).when(mImsCall).isMultiparty();
@@ -913,8 +754,6 @@
     @Test
     @SmallTest
     public void testReasonCodeRemap() {
-        loadReasonCodeRemap();
-
         assertEquals(ImsReasonInfo.CODE_WIFI_LOST, mCTUT.maybeRemapReasonCode(
                 new ImsReasonInfo(1, 1, "Wifi signal lost.")));
         assertEquals(ImsReasonInfo.CODE_WIFI_LOST, mCTUT.maybeRemapReasonCode(
@@ -931,87 +770,6 @@
                 "Call answered elsewhere.")));
     }
 
-    private void clearCarrierConfig() {
-        PersistableBundle bundle = new PersistableBundle();
-        mCTUT.updateCarrierConfigCache(bundle);
-    }
-
-    private void loadReasonCodeRemap() {
-        mCTUT.addReasonCodeRemapping(null, "Wifi signal lost.", ImsReasonInfo.CODE_WIFI_LOST);
-        mCTUT.addReasonCodeRemapping(501, "Call answered elsewhere.",
-                ImsReasonInfo.CODE_ANSWERED_ELSEWHERE);
-        mCTUT.addReasonCodeRemapping(510, "Call answered elsewhere.",
-                ImsReasonInfo.CODE_ANSWERED_ELSEWHERE);
-        mCTUT.addReasonCodeRemapping(ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, "",
-                ImsReasonInfo.CODE_SIP_FORBIDDEN);
-        mCTUT.addReasonCodeRemapping(ImsReasonInfo.CODE_SIP_SERVICE_UNAVAILABLE,
-                "emergency calls over wifi not allowed in this location",
-                ImsReasonInfo.CODE_EMERGENCY_CALL_OVER_WFC_NOT_AVAILABLE);
-        mCTUT.addReasonCodeRemapping(ImsReasonInfo.CODE_SIP_FORBIDDEN,
-                "service not allowed in this location",
-                ImsReasonInfo.CODE_WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION);
-    }
-
-    private void loadReasonCodeRemapCarrierConfig() {
-        PersistableBundle bundle = new PersistableBundle();
-        String[] mappings = new String[] {
-                // These shall be equivalent to the remappings added in setUp():
-                "*|Wifi signal lost.|1407",
-                "501|Call answered elsewhere.|1014",
-                "510|Call answered elsewhere.|1014",
-                "510||332",
-                "352|emergency calls over wifi not allowed in this location|1622",
-                "332|service not allowed in this location|1623",
-                };
-        bundle.putStringArray(CarrierConfigManager.KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY,
-                mappings);
-        mCTUT.updateCarrierConfigCache(bundle);
-    }
-
-    @Test
-    @SmallTest
-    public void testReasonCodeRemapCarrierConfig() {
-        clearCarrierConfig();
-        // The map shall become empty now
-
-        assertEquals(510, // ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE
-                mCTUT.maybeRemapReasonCode(new ImsReasonInfo(510, 1, "Call answered elsewhere.")));
-
-        loadReasonCodeRemapCarrierConfig();
-        testReasonCodeRemap();
-        testNumericOnlyRemap();
-        testRemapEmergencyCallsOverWfc();
-        testRemapWfcNotAvailable();
-    }
-
-    private void loadReasonCodeRemapCarrierConfigWithWildcardMessage() {
-        PersistableBundle bundle = new PersistableBundle();
-        String[] mappings = new String[]{
-                "1014|call completed elsewhere|1014",
-                "1014|*|510",
-                };
-        bundle.putStringArray(CarrierConfigManager.KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY,
-                mappings);
-        mCTUT.updateCarrierConfigCache(bundle);
-    }
-
-    @Test
-    @SmallTest
-    public void testReasonCodeRemapCarrierConfigWithWildcardMessage() {
-        clearCarrierConfig();
-        // The map shall become empty now
-
-        loadReasonCodeRemapCarrierConfigWithWildcardMessage();
-        assertEquals(ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, mCTUT.maybeRemapReasonCode(
-                new ImsReasonInfo(1014, 200, "Call Rejected By User"))); // 1014 -> 510
-        assertEquals(ImsReasonInfo.CODE_ANSWERED_ELSEWHERE, mCTUT.maybeRemapReasonCode(
-                new ImsReasonInfo(1014, 200, "Call completed elsewhere"))); // 1014 -> 1014
-
-        // Simulate that after SIM swap the new carrier config doesn't have the mapping for 1014
-        loadReasonCodeRemapCarrierConfig();
-        assertEquals(ImsReasonInfo.CODE_ANSWERED_ELSEWHERE, mCTUT.maybeRemapReasonCode(
-                new ImsReasonInfo(1014, 200, "Call Rejected By User"))); // 1014 -> 1014
-    }
 
     @Test
     @SmallTest
@@ -1030,7 +788,7 @@
         processAllMessages();
 
         // Simulate ImsManager getting reconnected.
-        mConnectorListener.connectionReady(mImsManager, SUB_0);
+        mConnectorListener.connectionReady(mImsManager);
         verify(mImsManager, never()).makeCall(nullable(ImsCallProfile.class),
                 eq(new String[]{"+17005554141"}), nullable(ImsCall.Listener.class));
         // Make sure that open is called in ImsPhoneCallTracker when it was first connected and
@@ -1094,216 +852,6 @@
         Assert.assertEquals("*55", connection.getAddress());
     }
 
-
-    /**
-     * Tests carrier requirement to re-map certain dialstrings based on the phones service state.
-     * Dial strings in a particular roaming state (ex. ROAMING_TYPE_INTERNATIONAL) can be mapped
-     * to the number.  Ideally, dialstrings in different roaming states will be mapped to
-     * different remappings.
-     *
-     * ex.
-     *
-     * dialstring --> remapping
-     *
-     * 611 --> 123 , *611 --> 123   when  ServiceState.ROAMING_TYPE_DOMESTIC
-     *
-     * 611 --> 456 , *611 --> 456   when  ServiceState.ROAMING_TYPE_INTERNATIONAL
-     */
-    @Test
-    @MediumTest
-    public void testRewriteOutgoingNumberBasedOnRoamingState() {
-        // mock carrier [dialstring]:[remapping]
-        final String dialString = "611";
-        final String dialStringStar = "*611";
-        final String remapping1 = "1111111111";
-        final String remapping2 = "2222222222";
-
-        // Create the re-mappings by getting the mock carrier bundle and inserting string arrays
-        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
-        // insert domestic roaming bundle
-        bundle.putStringArray(CarrierConfigManager
-                        .KEY_DIAL_STRING_REPLACE_STRING_ARRAY,
-                new String[]{(dialString + ":" + remapping1),
-                        (dialStringStar + ":" + remapping1)});
-        // insert international roaming bundle
-        bundle.putStringArray(CarrierConfigManager
-                        .KEY_INTERNATIONAL_ROAMING_DIAL_STRING_REPLACE_STRING_ARRAY,
-                new String[]{(dialString + ":" + remapping2),
-                        (dialStringStar + ":" + remapping2)});
-
-        try {
-            doAnswer(new Answer<ImsCall>() {
-                @Override
-                public ImsCall answer(InvocationOnMock invocation) throws Throwable {
-                    mImsCallListener =
-                            (ImsCall.Listener) invocation.getArguments()[2];
-                    ImsCall imsCall = spy(new ImsCall(mContext, mImsCallProfile));
-                    imsCall.setListener(mImsCallListener);
-                    imsCallMocking(imsCall);
-                    return imsCall;
-                }
-            }).when(mImsManager).makeCall(eq(mImsCallProfile), (String[]) any(),
-                    (ImsCall.Listener) any());
-        } catch (ImsException ie) {
-        }
-
-        // set mock call for helper function CallTracker#shouldPerformInternationalNumberRemapping
-        doReturn(ServiceState.ROAMING_TYPE_INTERNATIONAL)
-                .when(mServiceState).getVoiceRoamingType();
-
-        // perform a call while service is state in roaming international
-        ImsPhoneConnection connection = null;
-        try {
-            connection = (ImsPhoneConnection) mCTUT.dial(dialString,
-                    ImsCallProfile.CALL_TYPE_VOICE, null);
-        } catch (Exception ex) {
-            ex.printStackTrace();
-            Assert.fail("unexpected exception thrown" + ex.getMessage());
-        }
-        if (connection == null) {
-            Assert.fail("connection is null");
-        }
-
-        Assert.assertEquals(dialString, connection.getAddress());
-        Assert.assertEquals(remapping2, connection.getConvertedNumber());
-
-        mCTUT.hangupAllOrphanedConnections(DisconnectCause.NORMAL);
-
-        // perform a 2nd call while service state is in roaming international
-        ImsPhoneConnection connection2 = null;
-        try {
-            connection2 = (ImsPhoneConnection) mCTUT.dial(dialStringStar,
-                    ImsCallProfile.CALL_TYPE_VOICE, null);
-        } catch (Exception ex) {
-            ex.printStackTrace();
-            Assert.fail("unexpected exception thrown" + ex.getMessage());
-        }
-        if (connection2 == null) {
-            Assert.fail("connection is null");
-        }
-
-        Assert.assertEquals(dialStringStar, connection2.getAddress());
-        Assert.assertEquals(remapping2, connection2.getConvertedNumber());
-
-        mCTUT.hangupAllOrphanedConnections(DisconnectCause.NORMAL);
-
-
-        // CHANGE THE SERVICE STATE: international --> domestic
-        doReturn(ServiceState.ROAMING_TYPE_DOMESTIC)
-                .when(mServiceState).getVoiceRoamingType();
-
-        // perform 3rd call while service state is in roaming DOMESTIC
-        ImsPhoneConnection connection3 = null;
-        try {
-            connection3 = (ImsPhoneConnection) mCTUT.dial(dialString,
-                    ImsCallProfile.CALL_TYPE_VOICE, null);
-        } catch (Exception ex) {
-            ex.printStackTrace();
-            Assert.fail("unexpected exception thrown" + ex.getMessage());
-        }
-        if (connection3 == null) {
-            Assert.fail("connection is null");
-        }
-
-        Assert.assertEquals(dialString, connection3.getAddress());
-        Assert.assertEquals(remapping1, connection3.getConvertedNumber());
-
-
-        mCTUT.hangupAllOrphanedConnections(DisconnectCause.NORMAL);
-
-        // perform 4th call while service state is in roaming DOMESTIC
-        ImsPhoneConnection connection4 = null;
-        try {
-            connection4 = (ImsPhoneConnection) mCTUT.dial(dialStringStar,
-                    ImsCallProfile.CALL_TYPE_VOICE, null);
-        } catch (Exception ex) {
-            ex.printStackTrace();
-            Assert.fail("unexpected exception thrown" + ex.getMessage());
-        }
-        if (connection4 == null) {
-            Assert.fail("connection is null");
-        }
-
-        Assert.assertEquals(dialStringStar, connection4.getAddress());
-        Assert.assertEquals(remapping1, connection4.getConvertedNumber());
-
-        mCTUT.hangupAllOrphanedConnections(DisconnectCause.NORMAL);
-    }
-
-
-    /**
-     * Tests the edge case where the phone is in ServiceState.ROAMING_TYPE_INTERNATIONAL but the
-     * Carrier never set the bundle for this ServiceState.  Always default to
-     * CarrierConfigManager.KEY_DIAL_STRING_REPLACE_STRING_ARRAY.
-     */
-    @Test
-    @SmallTest
-    public void testRewriteOutgoingNumberInternationalButBundleNotSet() {
-        // mock carrier [dialstring]:[remapping]
-        final String dialString = "611";
-        final String dialStringStar = "*611";
-        final String remapping1 = "1111111111";
-
-        // Create the re-mappings by getting the mock carrier bundle and inserting string arrays
-        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
-        // insert domestic roaming bundle
-        bundle.putStringArray(CarrierConfigManager
-                        .KEY_DIAL_STRING_REPLACE_STRING_ARRAY,
-                new String[]{(dialString + ":" + remapping1),
-                        (dialStringStar + ":" + remapping1)});
-
-        try {
-            doAnswer(new Answer<ImsCall>() {
-                @Override
-                public ImsCall answer(InvocationOnMock invocation) throws Throwable {
-                    mImsCallListener =
-                            (ImsCall.Listener) invocation.getArguments()[2];
-                    ImsCall imsCall = spy(new ImsCall(mContext, mImsCallProfile));
-                    imsCall.setListener(mImsCallListener);
-                    imsCallMocking(imsCall);
-                    return imsCall;
-                }
-            }).when(mImsManager).makeCall(eq(mImsCallProfile), (String[]) any(),
-                    (ImsCall.Listener) any());
-        } catch (ImsException ie) {
-        }
-
-        doReturn(ServiceState.ROAMING_TYPE_INTERNATIONAL)
-                .when(mServiceState).getVoiceRoamingType();
-
-        Assert.assertNotNull(mImsPhone);
-        Assert.assertNotNull(mImsPhone.getDefaultPhone());
-
-        ImsPhoneConnection connection = null;
-        try {
-            connection = (ImsPhoneConnection) mCTUT.dial(dialString,
-                    ImsCallProfile.CALL_TYPE_VOICE, null);
-        } catch (Exception ex) {
-            ex.printStackTrace();
-            Assert.fail("unexpected exception thrown" + ex.getMessage());
-        }
-        if (connection == null) {
-            Assert.fail("connection is null");
-        }
-
-        // helper function CallTracker#shouldPerformInternationalNumberRemapping early exists since
-        // the KEY_INTERNATIONAL_ROAMING_DIAL_STRING_REPLACE_STRING_ARRAY bundle is null. Therefore,
-        // we should never check the service state and default to
-        // KEY_INTERNATIONAL_ROAMING_DIAL_STRING_REPLACE_STRING_ARRAY bundle
-        verify(mServiceState, times(0)).getVoiceRoamingType();
-
-        Assert.assertEquals(mImsPhone.getDefaultPhone().getServiceState().getVoiceRoamingType(),
-                ServiceState.ROAMING_TYPE_INTERNATIONAL);
-
-        Assert.assertNull(bundle.getStringArray(CarrierConfigManager
-                .KEY_INTERNATIONAL_ROAMING_DIAL_STRING_REPLACE_STRING_ARRAY));
-
-        Assert.assertEquals(dialString, connection.getAddress());
-        Assert.assertEquals(remapping1, connection.getConvertedNumber());
-
-        mCTUT.hangupAllOrphanedConnections(DisconnectCause.NORMAL);
-    }
-
     /**
      * Test notification of handover from LTE to WIFI and WIFI to LTE and ensure that the expected
      * connection events are sent.
@@ -1522,10 +1070,6 @@
     @Test
     @SmallTest
     public void testCantMakeCallTooMany() {
-        PersistableBundle bundle = mContextFixture.getCarrierConfigBundle();
-        bundle.putBoolean(CarrierConfigManager.KEY_ALLOW_HOLD_VIDEO_CALL_BOOL, true);
-        mCTUT.updateCarrierConfigCache(bundle);
-
         // Place a call.
         placeCallAndMakeActive();
 
@@ -1563,8 +1107,6 @@
     @Test
     @SmallTest
     public void testNumericOnlyRemap() {
-        loadReasonCodeRemap();
-
         assertEquals(ImsReasonInfo.CODE_SIP_FORBIDDEN, mCTUT.maybeRemapReasonCode(
                 new ImsReasonInfo(ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, 0)));
         assertEquals(ImsReasonInfo.CODE_SIP_FORBIDDEN, mCTUT.maybeRemapReasonCode(
@@ -1574,8 +1116,6 @@
     @Test
     @SmallTest
     public void testRemapEmergencyCallsOverWfc() {
-        loadReasonCodeRemap();
-
         assertEquals(ImsReasonInfo.CODE_SIP_SERVICE_UNAVAILABLE,
                 mCTUT.maybeRemapReasonCode(
                         new ImsReasonInfo(ImsReasonInfo.CODE_SIP_SERVICE_UNAVAILABLE, 0)));
@@ -1592,8 +1132,6 @@
     @Test
     @SmallTest
     public void testRemapWfcNotAvailable() {
-        loadReasonCodeRemap();
-
         assertEquals(ImsReasonInfo.CODE_SIP_FORBIDDEN,
                 mCTUT.maybeRemapReasonCode(
                         new ImsReasonInfo(ImsReasonInfo.CODE_SIP_FORBIDDEN, 0)));
@@ -1773,20 +1311,20 @@
     @Test
     @SmallTest
     public void testConfigureRtpHeaderExtensionTypes() throws Exception {
-        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
-        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
+
         mContextFixture.getCarrierConfigBundle().putBoolean(
                 CarrierConfigManager.KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL,
                 true);
         mContextFixture.getCarrierConfigBundle().putBoolean(
                 CarrierConfigManager.KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL,
                 true);
-        sendCarrierConfigChanged();
+        // Hacky but ImsPhoneCallTracker caches carrier config, so necessary.
+        mCTUT.updateCarrierConfigCache(mContextFixture.getCarrierConfigBundle());
 
         ImsPhoneCallTracker.Config config = new ImsPhoneCallTracker.Config();
         config.isD2DCommunicationSupported = true;
         mCTUT.setConfig(config);
-        mConnectorListener.connectionReady(mImsManager, SUB_0);
+        mConnectorListener.connectionReady(mImsManager);
 
         // Expect to get offered header extensions since d2d is supported.
         verify(mImsManager).setOfferedRtpHeaderExtensionTypes(
@@ -1804,20 +1342,20 @@
     @Test
     @SmallTest
     public void testRtpButNoSdp() throws Exception {
-        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
-        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
+
         mContextFixture.getCarrierConfigBundle().putBoolean(
                 CarrierConfigManager.KEY_SUPPORTS_DEVICE_TO_DEVICE_COMMUNICATION_USING_RTP_BOOL,
                 true);
         mContextFixture.getCarrierConfigBundle().putBoolean(
                 CarrierConfigManager.KEY_SUPPORTS_SDP_NEGOTIATION_OF_D2D_RTP_HEADER_EXTENSIONS_BOOL,
                 false);
-        sendCarrierConfigChanged();
+        // Hacky but ImsPhoneCallTracker caches carrier config, so necessary.
+        mCTUT.updateCarrierConfigCache(mContextFixture.getCarrierConfigBundle());
 
         ImsPhoneCallTracker.Config config = new ImsPhoneCallTracker.Config();
         config.isD2DCommunicationSupported = true;
         mCTUT.setConfig(config);
-        mConnectorListener.connectionReady(mImsManager, SUB_0);
+        mConnectorListener.connectionReady(mImsManager);
 
         // Expect to get offered header extensions since d2d is supported.
         verify(mImsManager).setOfferedRtpHeaderExtensionTypes(
@@ -1834,40 +1372,15 @@
     @Test
     @SmallTest
     public void testDontConfigureRtpHeaderExtensionTypes() throws Exception {
-        mConnectorListener.connectionUnavailable(FeatureConnector.UNAVAILABLE_REASON_DISCONNECTED);
-        doReturn(true).when(mSubscriptionController).isActiveSubId(anyInt());
-        sendCarrierConfigChanged();
         ImsPhoneCallTracker.Config config = new ImsPhoneCallTracker.Config();
         config.isD2DCommunicationSupported = false;
         mCTUT.setConfig(config);
-        mConnectorListener.connectionReady(mImsManager, SUB_0);
+        mConnectorListener.connectionReady(mImsManager);
 
         // Expect no offered header extensions since d2d is not supported.
         verify(mImsManager, never()).setOfferedRtpHeaderExtensionTypes(any());
     }
 
-    @Test
-    @SmallTest
-    public void testCleanupAndRemoveConnection() throws Exception {
-        ImsPhoneConnection conn = placeCall();
-        assertEquals(1, mCTUT.getConnections().size());
-        assertNotNull(mCTUT.getPendingMO());
-        assertEquals(Call.State.DIALING, mCTUT.mForegroundCall.getState());
-
-        mCTUT.cleanupAndRemoveConnection(conn);
-        assertEquals(0, mCTUT.getConnections().size());
-        assertNull(mCTUT.getPendingMO());
-        assertEquals(Call.State.IDLE, mCTUT.mForegroundCall.getState());
-    }
-
-    private void sendCarrierConfigChanged() {
-        Intent intent = new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
-        intent.putExtra(CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX, mPhone.getSubId());
-        intent.putExtra(CarrierConfigManager.EXTRA_SLOT_INDEX, mPhone.getPhoneId());
-        mBroadcastReceiver.onReceive(mContext, intent);
-        processAllMessages();
-    }
-
     private void assertVtDataUsageUpdated(int expectedToken, long rxBytes, long txBytes)
             throws RemoteException {
         final ArgumentCaptor<NetworkStats> ifaceStatsCaptor = ArgumentCaptor.forClass(
@@ -1895,16 +1408,6 @@
     }
 
     private ImsPhoneConnection placeCallAndMakeActive() {
-        ImsPhoneConnection connection = placeCall();
-        ImsCall imsCall = connection.getImsCall();
-        imsCall.getImsCallSessionListenerProxy().callSessionProgressing(imsCall.getSession(),
-                new ImsStreamMediaProfile());
-        imsCall.getImsCallSessionListenerProxy().callSessionStarted(imsCall.getSession(),
-                new ImsCallProfile());
-        return connection;
-    }
-
-    private ImsPhoneConnection placeCall() {
         try {
             doAnswer(new Answer<ImsCall>() {
                 @Override
@@ -1916,7 +1419,6 @@
                     imsCallMocking(imsCall);
                     return imsCall;
                 }
-
             }).when(mImsManager).makeCall(eq(mImsCallProfile), (String[]) any(),
                     (ImsCall.Listener) any());
         } catch (ImsException ie) {
@@ -1933,6 +1435,11 @@
         if (connection == null) {
             Assert.fail("connection is null");
         }
+        ImsCall imsCall = connection.getImsCall();
+        imsCall.getImsCallSessionListenerProxy().callSessionProgressing(imsCall.getSession(),
+                new ImsStreamMediaProfile());
+        imsCall.getImsCallSessionListenerProxy().callSessionStarted(imsCall.getSession(),
+                new ImsCallProfile());
         return connection;
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java
index 9779cfa..5e98e50 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneConnectionTest.java
@@ -66,11 +66,12 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
+import java.lang.reflect.Field;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
@@ -81,18 +82,16 @@
 
     private ImsPhoneConnection mConnectionUT;
     private Bundle mBundle = new Bundle();
-
-    // Mocked classes
+    @Mock
     private ImsPhoneCall mForeGroundCall;
+    @Mock
     private ImsPhoneCall mBackGroundCall;
+    @Mock
     private ImsPhoneCall mRingGroundCall;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mForeGroundCall = mock(ImsPhoneCall.class);
-        mBackGroundCall = mock(ImsPhoneCall.class);
-        mRingGroundCall = mock(ImsPhoneCall.class);
         replaceInstance(Handler.class, "mLooper", mImsCT, Looper.myLooper());
         replaceInstance(ImsPhoneCallTracker.class, "mForegroundCall", mImsCT, mForeGroundCall);
         replaceInstance(ImsPhoneCallTracker.class, "mBackgroundCall", mImsCT, mBackGroundCall);
@@ -105,8 +104,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mBundle = null;
-        mConnectionUT = null;
         super.tearDown();
     }
 
@@ -278,7 +275,13 @@
         // process post dial string during update
         assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
         assertEquals(Connection.PostDialState.STARTED, mConnectionUT.getPostDialState());
-        moveTimeForward(ImsPhoneConnection.PAUSE_DELAY_MILLIS);
+        try {
+            Field field = ImsPhoneConnection.class.getDeclaredField("PAUSE_DELAY_MILLIS");
+            field.setAccessible(true);
+            moveTimeForward((Integer) field.get(null));
+        } catch (Exception ex) {
+            Assert.fail("unexpected exception thrown" + ex.getMessage());
+        }
         processAllMessages();
         assertEquals(Connection.PostDialState.COMPLETE, mConnectionUT.getPostDialState());
     }
@@ -430,14 +433,15 @@
     @SmallTest
     public void testSetRedirectingAddress() {
         mConnectionUT = new ImsPhoneConnection(mImsPhone, mImsCall, mImsCT, mForeGroundCall, false);
-        String[] forwardedNumber = new String[]{"11111", "22222", "33333"};
-        ArrayList<String> forwardedNumberList =
-                new ArrayList<String>(Arrays.asList(forwardedNumber));
+        ArrayList<String> forwardedNumber = new ArrayList<String>();
+        forwardedNumber.add("11111");
+        forwardedNumber.add("22222");
+        forwardedNumber.add("33333");
 
         assertEquals(mConnectionUT.getForwardedNumber(), null);
-        mBundle.putStringArray(ImsCallProfile.EXTRA_FORWARDED_NUMBER, forwardedNumber);
+        mBundle.putStringArrayList(ImsCallProfile.EXTRA_FORWARDED_NUMBER, forwardedNumber);
         assertTrue(mConnectionUT.update(mImsCall, Call.State.ACTIVE));
-        assertEquals(forwardedNumberList, mConnectionUT.getForwardedNumber());
+        assertEquals(forwardedNumber, mConnectionUT.getForwardedNumber());
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneFactoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneFactoryTest.java
index a657ba2..5514853 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneFactoryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneFactoryTest.java
@@ -19,7 +19,6 @@
 import static org.junit.Assert.assertNotNull;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -32,17 +31,23 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 
 import java.util.concurrent.Executor;
 
 public class ImsPhoneFactoryTest extends TelephonyTest {
-    // Mocked classes
-    private PhoneNotifier mPhoneNotifier;
 
+    @Mock
+    private PhoneNotifier mPhoneNotifer;
     private ImsPhone mImsPhoneUT;
     private ImsPhoneFactoryHandler mImsPhoneFactoryHandler;
 
-    private final Executor mExecutor = Runnable::run;
+    private Executor mExecutor = new Executor() {
+        @Override
+        public void execute(Runnable r) {
+            r.run();
+        }
+    };
 
     private class ImsPhoneFactoryHandler extends HandlerThread {
 
@@ -51,18 +56,17 @@
         }
         @Override
         public void onLooperPrepared() {
-            mImsPhoneUT = ImsPhoneFactory.makePhone(mContext, mPhoneNotifier, mPhone);
+            mImsPhoneUT = ImsPhoneFactory.makePhone(mContext, mPhoneNotifer, mPhone);
             setReady(true);
         }
     }
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mPhoneNotifier = mock(PhoneNotifier.class);
+        super.setUp(this.getClass().getSimpleName());
         doReturn(mExecutor).when(mContext).getMainExecutor();
 
-        mImsPhoneFactoryHandler = new ImsPhoneFactoryHandler(getClass().getSimpleName());
+        mImsPhoneFactoryHandler = new ImsPhoneFactoryHandler(this.getClass().getSimpleName());
         mImsPhoneFactoryHandler.start();
 
         waitUntilReady();
@@ -72,8 +76,6 @@
     public void tearDown() throws Exception {
         mImsPhoneFactoryHandler.quit();
         mImsPhoneFactoryHandler.join();
-        mImsPhoneFactoryHandler = null;
-        mImsPhoneUT = null;
         super.tearDown();
     }
 
@@ -83,6 +85,6 @@
         assertEquals(mPhone, mImsPhoneUT.getDefaultPhone());
 
         mImsPhoneUT.notifyDataActivity();
-        verify(mPhoneNotifier, times(1)).notifyDataActivity(eq(mImsPhoneUT));
+        verify(mPhoneNotifer, times(1)).notifyDataActivity(eq(mImsPhoneUT));
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneMmiCodeTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneMmiCodeTest.java
index 23b6bb9..aee46b7 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneMmiCodeTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneMmiCodeTest.java
@@ -21,7 +21,6 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 
 import android.os.PersistableBundle;
 import android.telephony.CarrierConfigManager;
@@ -35,6 +34,8 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 import java.util.concurrent.Executor;
 
@@ -49,16 +50,19 @@
     private static final String TEST_DIAL_STRING_NON_EMERGENCY_NUMBER = "11976";
     private ImsPhoneMmiCode mImsPhoneMmiCode;
     private ImsPhone mImsPhoneUT;
+    @Mock private ServiceState mServiceState;
 
-    // Mocked classes
-    private ServiceState mServiceState;
-
-    private final Executor mExecutor = Runnable::run;
+    private Executor mExecutor = new Executor() {
+        @Override
+        public void execute(Runnable r) {
+            r.run();
+        }
+    };
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mServiceState = mock(ServiceState.class);
+        MockitoAnnotations.initMocks(this);
         doReturn(mExecutor).when(mContext).getMainExecutor();
         doReturn(mPhone).when(mPhone).getDefaultPhone();
         doReturn(mServiceState).when(mPhone).getServiceState();
@@ -70,8 +74,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mImsPhoneMmiCode = null;
-        mImsPhoneUT = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
index 17a63dd..be037d9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsPhoneTest.java
@@ -16,8 +16,6 @@
 
 package com.android.internal.telephony.imsphone;
 
-import static android.Manifest.permission.MODIFY_PHONE_STATE;
-import static android.provider.Telephony.SimInfo.COLUMN_PHONE_NUMBER_SOURCE_IMS;
 import static android.telephony.CarrierConfigManager.USSD_OVER_CS_ONLY;
 import static android.telephony.CarrierConfigManager.USSD_OVER_CS_PREFERRED;
 import static android.telephony.CarrierConfigManager.USSD_OVER_IMS_ONLY;
@@ -42,7 +40,6 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
@@ -52,7 +49,6 @@
 import android.content.BroadcastReceiver;
 import android.content.Intent;
 import android.content.res.Resources;
-import android.net.Uri;
 import android.os.AsyncResult;
 import android.os.Bundle;
 import android.os.Handler;
@@ -61,7 +57,6 @@
 import android.sysprop.TelephonyProperties;
 import android.telephony.CarrierConfigManager;
 import android.telephony.ServiceState;
-import android.telephony.SubscriptionInfo;
 import android.telephony.TelephonyManager;
 import android.telephony.ims.ImsCallProfile;
 import android.telephony.ims.ImsReasonInfo;
@@ -93,6 +88,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.List;
 import java.util.concurrent.Executor;
@@ -103,15 +99,25 @@
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class ImsPhoneTest extends TelephonyTest {
-    // Mocked classes
+    @Mock
     private ImsPhoneCall mForegroundCall;
+    @Mock
     private ImsPhoneCall mBackgroundCall;
+    @Mock
     private ImsPhoneCall mRingingCall;
+    @Mock
     private Handler mTestHandler;
+    @Mock
     Connection mConnection;
+    @Mock
     ImsUtInterface mImsUtInterface;
 
-    private final Executor mExecutor = Runnable::run;
+    private Executor mExecutor = new Executor() {
+        @Override
+        public void execute(Runnable r) {
+            r.run();
+        }
+    };
 
     private ImsPhone mImsPhoneUT;
     private PersistableBundle mBundle;
@@ -127,12 +133,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mForegroundCall = mock(ImsPhoneCall.class);
-        mBackgroundCall = mock(ImsPhoneCall.class);
-        mRingingCall = mock(ImsPhoneCall.class);
-        mTestHandler = mock(Handler.class);
-        mConnection = mock(Connection.class);
-        mImsUtInterface = mock(ImsUtInterface.class);
 
         mImsCT.mForegroundCall = mForegroundCall;
         mImsCT.mBackgroundCall = mBackgroundCall;
@@ -175,7 +175,6 @@
     @After
     public void tearDown() throws Exception {
         mImsPhoneUT = null;
-        mBundle = null;
         super.tearDown();
     }
 
@@ -734,7 +733,7 @@
     @Test
     @SmallTest
     public void testRoamingToAirplanModeIwlanInService() throws Exception {
-        doReturn(true).when(mAccessNetworksManager).isInLegacyMode();
+        doReturn(true).when(mTransportManager).isInLegacyMode();
         doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
         doReturn(true).when(mPhone).isRadioOn();
 
@@ -762,7 +761,7 @@
     @Test
     @SmallTest
     public void testRoamingToOutOfService() throws Exception {
-        doReturn(true).when(mAccessNetworksManager).isInLegacyMode();
+        doReturn(true).when(mTransportManager).isInLegacyMode();
         doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
         doReturn(true).when(mPhone).isRadioOn();
 
@@ -788,7 +787,7 @@
     @Test
     @SmallTest
     public void testRoamingChangeForLteInLegacyMode() throws Exception {
-        doReturn(true).when(mAccessNetworksManager).isInLegacyMode();
+        doReturn(true).when(mTransportManager).isInLegacyMode();
         doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
         doReturn(true).when(mPhone).isRadioOn();
 
@@ -813,7 +812,7 @@
     @Test
     @SmallTest
     public void testDataOnlyRoamingCellToIWlanInLegacyMode() throws Exception {
-        doReturn(true).when(mAccessNetworksManager).isInLegacyMode();
+        doReturn(true).when(mTransportManager).isInLegacyMode();
         doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
         doReturn(true).when(mPhone).isRadioOn();
 
@@ -839,7 +838,7 @@
     @Test
     @SmallTest
     public void testCellVoiceDataChangeToWlanInLegacyMode() throws Exception {
-        doReturn(true).when(mAccessNetworksManager).isInLegacyMode();
+        doReturn(true).when(mTransportManager).isInLegacyMode();
         doReturn(PhoneConstants.State.IDLE).when(mImsCT).getState();
         doReturn(true).when(mPhone).isRadioOn();
 
@@ -977,97 +976,6 @@
         mImsPhoneUT.handleMessage(m);
     }
 
-    @Test
-    @SmallTest
-    public void testSetPhoneNumberForSourceIms() {
-        // In reality the method under test runs in phone process so has MODIFY_PHONE_STATE
-        mContextFixture.addCallingOrSelfPermission(MODIFY_PHONE_STATE);
-        int subId = 1;
-        doReturn(subId).when(mPhone).getSubId();
-        SubscriptionInfo subInfo = mock(SubscriptionInfo.class);
-        doReturn("gb").when(subInfo).getCountryIso();
-        doReturn(subInfo).when(mSubscriptionController).getSubscriptionInfo(subId);
-
-        // 1. Two valid phone number; 1st is set.
-        Uri[] associatedUris = new Uri[] {
-            Uri.parse("sip:+447539447777@ims.x.com"),
-            Uri.parse("tel:+447539446666")
-        };
-        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
-
-        verify(mSubscriptionController).setSubscriptionProperty(
-                subId, COLUMN_PHONE_NUMBER_SOURCE_IMS, "+447539447777");
-
-        // 2. 1st invalid and 2nd valid: 2nd is set.
-        associatedUris = new Uri[] {
-            Uri.parse("sip:447539447777@ims.x.com"),
-            Uri.parse("tel:+447539446666")
-        };
-        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
-
-        verify(mSubscriptionController).setSubscriptionProperty(
-                subId, COLUMN_PHONE_NUMBER_SOURCE_IMS, "+447539446666");
-
-        // 3. 1st sip-uri is not phone number and 2nd valid: 2nd is set.
-        associatedUris = new Uri[] {
-            Uri.parse("sip:john.doe@ims.x.com"),
-            Uri.parse("tel:+447539446677"),
-            Uri.parse("sip:+447539447766@ims.x.com")
-        };
-        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
-
-        verify(mSubscriptionController).setSubscriptionProperty(
-                subId, COLUMN_PHONE_NUMBER_SOURCE_IMS, "+447539446677");
-
-        // Clean up
-        mContextFixture.addCallingOrSelfPermission("");
-    }
-
-    @Test
-    @SmallTest
-    public void testSetPhoneNumberForSourceImsNegativeCases() {
-        // In reality the method under test runs in phone process so has MODIFY_PHONE_STATE
-        mContextFixture.addCallingOrSelfPermission(MODIFY_PHONE_STATE);
-        int subId = 1;
-        doReturn(subId).when(mPhone).getSubId();
-        SubscriptionInfo subInfo = mock(SubscriptionInfo.class);
-        doReturn("gb").when(subInfo).getCountryIso();
-        doReturn(subInfo).when(mSubscriptionController).getSubscriptionInfo(subId);
-
-        // 1. No valid phone number; do not set
-        Uri[] associatedUris = new Uri[] {
-            Uri.parse("sip:447539447777@ims.x.com"),
-            Uri.parse("tel:447539446666")
-        };
-        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
-
-        verify(mSubscriptionController, never()).setSubscriptionProperty(
-                anyInt(), any(), any());
-
-        // 2. no URI; do not set
-        associatedUris = new Uri[] {};
-        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
-
-        verify(mSubscriptionController, never()).setSubscriptionProperty(
-                anyInt(), any(), any());
-
-        // 3. null URI; do not set
-        associatedUris = new Uri[] { null };
-        mImsPhoneUT.setPhoneNumberForSourceIms(associatedUris);
-
-        verify(mSubscriptionController, never()).setSubscriptionProperty(
-                anyInt(), any(), any());
-
-        // 4. null pointer; do not set
-        mImsPhoneUT.setPhoneNumberForSourceIms(null);
-
-        verify(mSubscriptionController, never()).setSubscriptionProperty(
-                anyInt(), any(), any());
-
-        // Clean up
-        mContextFixture.addCallingOrSelfPermission("");
-    }
-
     private ServiceState getServiceStateDataAndVoice(int rat, int regState, boolean isRoaming) {
         ServiceState ss = new ServiceState();
         ss.setStateOutOfService();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRegistrationCallbackHelperTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRegistrationCallbackHelperTest.java
index cce0646..f2f69db 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRegistrationCallbackHelperTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRegistrationCallbackHelperTest.java
@@ -21,7 +21,6 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Matchers.anyInt;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import android.net.Uri;
@@ -37,25 +36,26 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 
 public class ImsRegistrationCallbackHelperTest extends TelephonyTest {
-    // Mocked classes
-    private ImsRegistrationUpdate mMockRegistrationUpdate;
 
+    @Mock
+    private ImsRegistrationUpdate mMockRegistrationUpdate;
     private ImsRegistrationCallbackHelper mRegistrationCallbackHelper;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mMockRegistrationUpdate = mock(ImsRegistrationUpdate.class);
+
         mRegistrationCallbackHelper = new ImsRegistrationCallbackHelper(mMockRegistrationUpdate,
                 Runnable::run);
     }
 
     @After
     public void tearDown() throws Exception {
-        mRegistrationCallbackHelper = null;
         super.tearDown();
+        mRegistrationCallbackHelper = null;
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java
index 6f8d899..00230c5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/imsphone/ImsRttTextHandlerTest.java
@@ -19,7 +19,6 @@
 import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
 
 import android.os.HandlerThread;
-import android.os.Message;
 import android.os.ParcelFileDescriptor;
 import android.telecom.Connection;
 
@@ -31,7 +30,6 @@
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.ComparisonFailure;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import java.io.IOException;
@@ -40,11 +38,9 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 
-@Ignore("b/221640979") // TODO: Enable the tests after fixing the resource leak.
 public class ImsRttTextHandlerTest extends TelephonyTest {
     private static final int TEST_TIMEOUT = 1000;
     private static final int READ_BUFFER_SIZE = 1000;
-    private static final String SHORT_TEXT = "Hello, World!";
     private static final String LONG_TEXT = "No Soldier shall, in time of peace be quartered in " +
             "any house, without the consent of the Owner, nor in time of war, but in a manner to " +
             "be prescribed by law.";
@@ -227,42 +223,6 @@
         Assert.assertEquals(LONG_TEXT, readAll(mPipeFromHandler));
     }
 
-    /**
-     * Test {@link ImsRttTextHandler#handleMessage(Message)} SEND_TO_INCALL case.  Specifically,
-     * test SEND_IN_CALL does not throw an exception when given a null msg.obj.
-     */
-    @Test
-    public void testHandleMessageCaseSendToInCallWithNullMsgObj() {
-        // Create a Message object
-        Message msg = new Message();
-        // Set the message what to SEND_TO_INCALL
-        msg.setWhat(mRttTextHandler.getSendToIncall());
-        // Set the message object to null
-        msg.obj = null;
-        // Call handleMessage with the null msg and ensure no Exception is thrown
-        mRttTextHandler.handleMessage(msg);
-    }
-
-    /**
-     * Test {@link ImsRttTextHandler#handleMessage(Message)} SEND_TO_INCALL case.  If
-     * mRttTextStream is null, then text should be written to mBufferedTextToIncall.
-     */
-    @Test
-    public void testHandleMessageWithRttTextStreamNull() {
-        // Ensure the buffer is empty
-        Assert.assertEquals("", mRttTextHandler.getBufferedTextToIncall().toString());
-        // Simulate the stream was never initialized or null
-        mRttTextHandler.setRttTextStream(null);
-        // Wait for change to take action
-        waitForHandlerAction(mRttTextHandler, TEST_TIMEOUT);
-        // Send text to In Call
-        mRttTextHandler.sendToInCall(SHORT_TEXT);
-        // Wait for change to take action
-        waitForHandlerAction(mRttTextHandler, TEST_TIMEOUT);
-        // Assert the text was written to the buffer
-        Assert.assertEquals(SHORT_TEXT, mRttTextHandler.getBufferedTextToIncall().toString());
-    }
-
     @After
     public void tearDown() throws Exception {
         mPipeFromHandler.close();
@@ -271,14 +231,6 @@
         waitForHandlerAction(mRttTextHandler, TEST_TIMEOUT);
         mHandlerThread.quit();
         mHandlerThread.join();
-
-        mRttTextStream = null;
-        mNetworkWriter = null;
-        mRttTextHandler = null;
-        mHandlerThread = null;
-        mPipeToHandler = null;
-        mPipeFromHandler = null;
-        mHandlerSideOfPipeToHandler = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/CallQualityMetricsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/CallQualityMetricsTest.java
index ae1c46d..e530425 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/CallQualityMetricsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/CallQualityMetricsTest.java
@@ -17,7 +17,6 @@
 package com.android.internal.telephony.metrics;
 
 import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 import android.telephony.CallQuality;
@@ -29,7 +28,6 @@
 import android.telephony.CellSignalStrengthWcdma;
 import android.telephony.SignalStrength;
 
-import com.android.internal.telephony.SignalStrengthController;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession.Event.CallQualitySummary;
 
@@ -38,27 +36,22 @@
 import org.junit.Test;
 
 public class CallQualityMetricsTest extends TelephonyTest {
-    // Mocked classes
-    SignalStrengthController mSsc;
 
     private CallQualityMetrics mCallQualityMetrics;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mSsc = mock(SignalStrengthController.class);
         mCallQualityMetrics = new CallQualityMetrics(mPhone);
 
         // the ImsPhone does not return a ServiceStateTracker, so CallQualityMetrics gets the
         // default phone from the ImsPhone and uses that to get the ServiceStateTracker, therefore
         // we need to mock the default phone as well.
         when(mPhone.getDefaultPhone()).thenReturn(mPhone);
-        when(mPhone.getSignalStrengthController()).thenReturn(mSsc);
     }
 
     @After
     public void tearDown() throws Exception {
-        mCallQualityMetrics = null;
         super.tearDown();
     }
 
@@ -271,7 +264,7 @@
                 new CellSignalStrengthTdscdma(),
                 lteSs1,
                 new CellSignalStrengthNr());
-        when(mSsc.getSignalStrength()).thenReturn(ss1);
+        when(mSST.getSignalStrength()).thenReturn(ss1);
         mCallQualityMetrics.saveCallQuality(cq1);
 
         // save good quality with low rssnr
@@ -287,7 +280,7 @@
                 new CellSignalStrengthTdscdma(),
                 lteSs2,
                 new CellSignalStrengthNr());
-        when(mSsc.getSignalStrength()).thenReturn(ss2);
+        when(mSST.getSignalStrength()).thenReturn(ss2);
         mCallQualityMetrics.saveCallQuality(cq1);
 
         CallQualitySummary dlSummary = mCallQualityMetrics.getCallQualitySummaryDl();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/ImsStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/ImsStatsTest.java
index 8b2fe92..c2b690f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/ImsStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/ImsStatsTest.java
@@ -25,14 +25,11 @@
 import static android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.CAPABILITY_TYPE_VOICE;
 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_IWLAN;
 import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_LTE;
-import static android.telephony.ims.stub.ImsRegistrationImplBase.REGISTRATION_TECH_NR;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -59,6 +56,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.Map;
 
@@ -74,12 +72,10 @@
                     | MmTelCapabilities.CAPABILITY_TYPE_SMS
                     | MmTelCapabilities.CAPABILITY_TYPE_UT;
 
-    // Mocked classes
-    private UiccSlot mPhysicalSlot0;
-    private UiccSlot mPhysicalSlot1;
-    private Phone mSecondPhone;
-    private ImsPhone mSecondImsPhone;
-    private ServiceStateStats mServiceStateStats;
+    @Mock private UiccSlot mPhysicalSlot0;
+    @Mock private UiccSlot mPhysicalSlot1;
+    @Mock private Phone mSecondPhone;
+    @Mock private ImsPhone mSecondImsPhone;
 
     private TestableImsStats mImsStats;
 
@@ -109,23 +105,18 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mPhysicalSlot0 = mock(UiccSlot.class);
-        mPhysicalSlot1 = mock(UiccSlot.class);
-        mSecondPhone = mock(Phone.class);
-        mSecondImsPhone = mock(ImsPhone.class);
-        mServiceStateStats = mock(ServiceStateStats.class);
 
         doReturn(CARRIER1_ID).when(mPhone).getCarrierId();
         doReturn(mImsPhone).when(mPhone).getImsPhone();
         doReturn(mSST).when(mImsPhone).getServiceStateTracker();
-        doReturn(mServiceStateStats).when(mSST).getServiceStateStats();
 
         // WWAN PS RAT is LTE
-        doReturn(new NetworkRegistrationInfo.Builder()
-                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
-                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                .build())
-                .when(mServiceState).getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN);
+        doReturn(
+                        new NetworkRegistrationInfo.Builder()
+                                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE)
+                                .build())
+                .when(mServiceState)
+                .getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN);
 
         // Single physical SIM
         doReturn(true).when(mPhysicalSlot0).isActive();
@@ -140,7 +131,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mImsStats = null;
         super.tearDown();
     }
 
@@ -348,86 +338,6 @@
         assertEquals(0L, stats.smsCapableMillis);
         assertEquals(0L, stats.smsAvailableMillis);
         verifyNoMoreInteractions(mPersistAtomsStorage);
-        // ServiceStateStats should be notified
-        verify(mServiceStateStats).onImsVoiceRegistrationChanged();
-    }
-
-    @Test
-    @SmallTest
-    public void onImsCapabilitiesChanged_differentTech() throws Exception {
-        mImsStats.onSetFeatureResponse(
-                CAPABILITY_TYPE_VOICE,
-                REGISTRATION_TECH_LTE,
-                ProvisioningManager.PROVISIONING_VALUE_ENABLED);
-        mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
-        mImsStats.onImsCapabilitiesChanged(
-                REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
-
-        verify(mServiceStateStats).onImsVoiceRegistrationChanged();
-
-        mImsStats.incTimeMillis(2000L);
-        mImsStats.onImsCapabilitiesChanged(
-                REGISTRATION_TECH_NR, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
-
-        // Atom with previous feature availability should be generated
-        ArgumentCaptor<ImsRegistrationStats> captor =
-                ArgumentCaptor.forClass(ImsRegistrationStats.class);
-        verify(mPersistAtomsStorage).addImsRegistrationStats(captor.capture());
-        ImsRegistrationStats stats = captor.getValue();
-        assertEquals(CARRIER1_ID, stats.carrierId);
-        assertEquals(0, stats.simSlotIndex);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, stats.rat);
-        assertEquals(2000L, stats.registeredMillis);
-        assertEquals(2000L, stats.voiceCapableMillis);
-        assertEquals(2000L, stats.voiceAvailableMillis);
-        assertEquals(0L, stats.videoCapableMillis);
-        assertEquals(0L, stats.videoAvailableMillis);
-        assertEquals(0L, stats.utCapableMillis);
-        assertEquals(0L, stats.utAvailableMillis);
-        assertEquals(0L, stats.smsCapableMillis);
-        assertEquals(0L, stats.smsAvailableMillis);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-        // ServiceStateStats should be notified
-        verify(mServiceStateStats, times(2)).onImsVoiceRegistrationChanged();
-    }
-
-    @Test
-    @SmallTest
-    public void onImsCapabilitiesChanged_differentTechNoVoice() throws Exception {
-        mImsStats.onSetFeatureResponse(
-                CAPABILITY_TYPE_SMS,
-                REGISTRATION_TECH_LTE,
-                ProvisioningManager.PROVISIONING_VALUE_ENABLED);
-        mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
-        mImsStats.onImsCapabilitiesChanged(
-                REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_SMS));
-
-        verify(mServiceStateStats, never()).onImsVoiceRegistrationChanged();
-
-        mImsStats.incTimeMillis(2000L);
-        mImsStats.onImsCapabilitiesChanged(
-                REGISTRATION_TECH_NR, new MmTelCapabilities(CAPABILITY_TYPE_SMS));
-
-        // Atom with previous feature availability should be generated
-        ArgumentCaptor<ImsRegistrationStats> captor =
-                ArgumentCaptor.forClass(ImsRegistrationStats.class);
-        verify(mPersistAtomsStorage).addImsRegistrationStats(captor.capture());
-        ImsRegistrationStats stats = captor.getValue();
-        assertEquals(CARRIER1_ID, stats.carrierId);
-        assertEquals(0, stats.simSlotIndex);
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, stats.rat);
-        assertEquals(2000L, stats.registeredMillis);
-        assertEquals(0L, stats.voiceCapableMillis);
-        assertEquals(0L, stats.voiceAvailableMillis);
-        assertEquals(0L, stats.videoCapableMillis);
-        assertEquals(0L, stats.videoAvailableMillis);
-        assertEquals(0L, stats.utCapableMillis);
-        assertEquals(0L, stats.utAvailableMillis);
-        assertEquals(2000L, stats.smsCapableMillis);
-        assertEquals(2000L, stats.smsAvailableMillis);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-        // ServiceStateStats should not be notified
-        verify(mServiceStateStats, never()).onImsVoiceRegistrationChanged();
     }
 
     @Test
@@ -812,61 +722,4 @@
         assertEquals("Timeout", termination.extraMessage);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
-
-    @Test
-    @SmallTest
-    public void getImsVoiceRadioTech_noRegistration() throws Exception {
-        // Do nothing
-
-        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, mImsStats.getImsVoiceRadioTech());
-    }
-
-    @Test
-    @SmallTest
-    public void getImsVoiceRadioTech_noVoiceRegistration() throws Exception {
-        mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
-        mImsStats.onImsCapabilitiesChanged(
-                REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_SMS));
-
-        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, mImsStats.getImsVoiceRadioTech());
-    }
-
-    @Test
-    @SmallTest
-    public void getImsVoiceRadioTech_cellularRegistration() throws Exception {
-        mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
-        mImsStats.onImsCapabilitiesChanged(
-                REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
-
-        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, mImsStats.getImsVoiceRadioTech());
-    }
-
-    @Test
-    @SmallTest
-    public void getImsVoiceRadioTech_wifiRegistration() throws Exception {
-        mImsStats.onImsRegistered(TRANSPORT_TYPE_WLAN);
-        mImsStats.onImsCapabilitiesChanged(
-                REGISTRATION_TECH_IWLAN, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
-
-        assertEquals(TelephonyManager.NETWORK_TYPE_IWLAN, mImsStats.getImsVoiceRadioTech());
-    }
-
-    @Test
-    @SmallTest
-    public void getImsVoiceRadioTech_unregistered() throws Exception {
-        mImsStats.onImsRegistered(TRANSPORT_TYPE_WWAN);
-        mImsStats.onImsCapabilitiesChanged(
-                REGISTRATION_TECH_LTE, new MmTelCapabilities(CAPABILITY_TYPE_VOICE));
-        mImsStats.onImsUnregistered(
-                new ImsReasonInfo(ImsReasonInfo.CODE_REGISTRATION_ERROR, 999, "Timeout"));
-        doReturn(
-                        new NetworkRegistrationInfo.Builder()
-                                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_UMTS)
-                                .build())
-                .when(mServiceState)
-                .getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN);
-
-
-        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, mImsStats.getImsVoiceRadioTech());
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/InProgressCallSessionTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/InProgressCallSessionTest.java
index 116293c..280ee2c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/InProgressCallSessionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/InProgressCallSessionTest.java
@@ -44,7 +44,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mCallSession = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/InProgressSmsSessionTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/InProgressSmsSessionTest.java
index a8ac50a..b2b9ca5 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/InProgressSmsSessionTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/InProgressSmsSessionTest.java
@@ -16,10 +16,6 @@
 
 package com.android.internal.telephony.metrics;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.telephony.TelephonyTest;
@@ -29,6 +25,10 @@
 import org.junit.Before;
 import org.junit.Test;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
 public class InProgressSmsSessionTest extends TelephonyTest {
 
     private InProgressSmsSession mSmsSession;
@@ -41,7 +41,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mSmsSession = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java
index a4e2574..cd15686 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/MetricsCollectorTest.java
@@ -28,7 +28,6 @@
 import static org.mockito.Mockito.anyLong;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -48,12 +47,12 @@
 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
 import com.android.internal.telephony.uicc.UiccCard;
 import com.android.internal.telephony.uicc.UiccController;
-import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UiccSlot;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -82,34 +81,26 @@
 
     // b/153195691: we cannot verify the contents of StatsEvent as its getters are marked with @hide
 
-    // Mocked classes
-    private Phone mSecondPhone;
-    private UiccSlot mPhysicalSlot;
-    private UiccSlot mEsimSlot;
-    private UiccCard mActiveCard;
-    private UiccPort mActivePort;
-    private ServiceStateStats mServiceStateStats;
+    @Mock private Phone mSecondPhone;
+    @Mock private UiccSlot mPhysicalSlot;
+    @Mock private UiccSlot mEsimSlot;
+    @Mock private UiccCard mActiveCard;
+
+    @Mock private ServiceStateStats mServiceStateStats;
 
     private MetricsCollector mMetricsCollector;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mSecondPhone = mock(Phone.class);
-        mPhysicalSlot = mock(UiccSlot.class);
-        mEsimSlot = mock(UiccSlot.class);
-        mActiveCard = mock(UiccCard.class);
-        mActivePort = mock(UiccPort.class);
-        mServiceStateStats = mock(ServiceStateStats.class);
-        mMetricsCollector =
-                new MetricsCollector(mContext, mPersistAtomsStorage);
+        mMetricsCollector = new MetricsCollector(mContext);
+        mMetricsCollector.setPersistAtomsStorage(mPersistAtomsStorage);
         doReturn(mSST).when(mSecondPhone).getServiceStateTracker();
         doReturn(mServiceStateStats).when(mSST).getServiceStateStats();
     }
 
     @After
     public void tearDown() throws Exception {
-        mMetricsCollector = null;
         super.tearDown();
     }
 
@@ -124,8 +115,7 @@
         doReturn(CardState.CARDSTATE_PRESENT).when(mEsimSlot).getCardState();
         doReturn(true).when(mEsimSlot).isEuicc();
         doReturn(mActiveCard).when(mEsimSlot).getUiccCard();
-        doReturn(4).when(mActivePort).getNumApplications();
-        doReturn(new UiccPort[] {mActivePort}).when(mActiveCard).getUiccPortList();
+        doReturn(4).when(mActiveCard).getNumApplications();
         doReturn(new UiccSlot[] {mPhysicalSlot, mEsimSlot}).when(mUiccController).getUiccSlots();
         doReturn(mPhysicalSlot).when(mUiccController).getUiccSlot(eq(0));
         doReturn(mEsimSlot).when(mUiccController).getUiccSlot(eq(1));
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/PerSimStatusTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/PerSimStatusTest.java
deleted file mode 100644
index 3d5cf481..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/PerSimStatusTest.java
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.metrics;
-
-import static android.telephony.SubscriptionManager.PHONE_NUMBER_SOURCE_CARRIER;
-import static android.telephony.SubscriptionManager.PHONE_NUMBER_SOURCE_IMS;
-import static android.telephony.SubscriptionManager.PHONE_NUMBER_SOURCE_UICC;
-
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_B;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_UNKNOWN;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__CELLULAR_PREFERRED;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__UNKNOWN;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__WIFI_ONLY;
-import static com.android.internal.telephony.TelephonyStatsLog.PER_SIM_STATUS__WFC_MODE__WIFI_PREFERRED;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-
-import android.telephony.SubscriptionInfo;
-import android.telephony.TelephonyManager;
-import android.telephony.ims.ImsManager;
-import android.telephony.ims.ImsMmTelManager;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import com.android.internal.telephony.IccCard;
-import com.android.internal.telephony.Phone;
-import com.android.internal.telephony.PhoneFactory;
-import com.android.internal.telephony.SubscriptionController;
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.uicc.UiccSlot;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class PerSimStatusTest extends TelephonyTest {
-    private static final int ENABLED_2G =
-            (int) TelephonyManager.NETWORK_TYPE_BITMASK_GSM
-                    | (int) TelephonyManager.NETWORK_TYPE_BITMASK_GPRS
-                    | (int) TelephonyManager.NETWORK_TYPE_BITMASK_EDGE
-                    | (int) TelephonyManager.NETWORK_TYPE_BITMASK_CDMA
-                    | (int) TelephonyManager.NETWORK_TYPE_BITMASK_1xRTT;
-
-    private Phone mSecondPhone;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mSecondPhone = mock(Phone.class);
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    @Test
-    @SmallTest
-    public void onPullAtom_perSimStatus() throws Exception {
-        // Make PhoneFactory.getPhones() return an array of two
-        replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone, mSecondPhone});
-        // phone 0 setup
-        doReturn(0).when(mPhone).getPhoneId();
-        doReturn(1).when(mPhone).getSubId();
-        doReturn(100).when(mPhone).getCarrierId();
-        doReturn("6506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
-        doReturn("")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
-        doReturn("+16506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_IMS, null, null);
-        SubscriptionInfo subscriptionInfo1 = mock(SubscriptionInfo.class);
-        doReturn("us").when(subscriptionInfo1).getCountryIso();
-        doReturn(subscriptionInfo1).when(mSubscriptionController).getSubscriptionInfo(1);
-        ImsManager imsManager = mContext.getSystemService(ImsManager.class);
-        ImsMmTelManager imsMmTelManager1 = mock(ImsMmTelManager.class);
-        doReturn(imsMmTelManager1).when(imsManager).getImsMmTelManager(1);
-        doReturn(true).when(imsMmTelManager1).isAdvancedCallingSettingEnabled();
-        doReturn(true).when(imsMmTelManager1).isVoWiFiSettingEnabled();
-        doReturn(ImsMmTelManager.WIFI_MODE_WIFI_ONLY).when(imsMmTelManager1).getVoWiFiModeSetting();
-        doReturn(ImsMmTelManager.WIFI_MODE_CELLULAR_PREFERRED)
-                .when(imsMmTelManager1)
-                .getVoWiFiRoamingModeSetting();
-        doReturn(false).when(imsMmTelManager1).isVtSettingEnabled();
-        doReturn(false).when(mPhone).getDataRoamingEnabled();
-        doReturn(1L)
-                .when(mPhone)
-                .getAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
-        doReturn(0L)
-                .when(mPhone)
-                .getAllowedNetworkTypes(
-                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G & ENABLED_2G);
-        IccCard iccCard1 = mock(IccCard.class);
-        doReturn(true).when(iccCard1).getIccLockEnabled();
-        doReturn(iccCard1).when(mPhone).getIccCard();
-        UiccSlot uiccSlot1 = mock(UiccSlot.class);
-        doReturn(UiccSlot.VOLTAGE_CLASS_A).when(uiccSlot1).getMinimumVoltageClass();
-        doReturn(uiccSlot1).when(mUiccController).getUiccSlotForPhone(0);
-        // phone 1 setup
-        doReturn(mContext).when(mSecondPhone).getContext();
-        doReturn(1).when(mSecondPhone).getPhoneId();
-        doReturn(2).when(mSecondPhone).getSubId();
-        doReturn(101).when(mSecondPhone).getCarrierId();
-        doReturn("0123")
-                .when(mSubscriptionController)
-                .getPhoneNumber(2, PHONE_NUMBER_SOURCE_UICC, null, null);
-        doReturn("16506950123")
-                .when(mSubscriptionController)
-                .getPhoneNumber(2, PHONE_NUMBER_SOURCE_CARRIER, null, null);
-        doReturn("+16506950123")
-                .when(mSubscriptionController)
-                .getPhoneNumber(2, PHONE_NUMBER_SOURCE_IMS, null, null);
-        SubscriptionInfo subscriptionInfo2 = mock(SubscriptionInfo.class);
-        doReturn("us").when(subscriptionInfo2).getCountryIso();
-        doReturn(subscriptionInfo2).when(mSubscriptionController).getSubscriptionInfo(2);
-        ImsMmTelManager imsMmTelManager2 = mock(ImsMmTelManager.class);
-        doReturn(imsMmTelManager2).when(imsManager).getImsMmTelManager(2);
-        doReturn(true).when(imsMmTelManager2).isAdvancedCallingSettingEnabled();
-        doReturn(false).when(imsMmTelManager2).isVoWiFiSettingEnabled();
-        doReturn(ImsMmTelManager.WIFI_MODE_WIFI_ONLY).when(imsMmTelManager2).getVoWiFiModeSetting();
-        doReturn(ImsMmTelManager.WIFI_MODE_WIFI_PREFERRED)
-                .when(imsMmTelManager2)
-                .getVoWiFiRoamingModeSetting();
-        doReturn(true).when(imsMmTelManager2).isVtSettingEnabled();
-        doReturn(false).when(mSecondPhone).getDataRoamingEnabled();
-        doReturn(1L)
-                .when(mSecondPhone)
-                .getAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
-        doReturn(1L)
-                .when(mSecondPhone)
-                .getAllowedNetworkTypes(
-                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G & ENABLED_2G);
-        IccCard iccCard2 = mock(IccCard.class);
-        doReturn(false).when(iccCard2).getIccLockEnabled();
-        doReturn(iccCard2).when(mSecondPhone).getIccCard();
-        UiccSlot uiccSlot2 = mock(UiccSlot.class);
-        doReturn(UiccSlot.VOLTAGE_CLASS_B).when(uiccSlot2).getMinimumVoltageClass();
-        doReturn(uiccSlot2).when(mUiccController).getUiccSlotForPhone(1);
-
-        PerSimStatus perSimStatus1 = PerSimStatus.getCurrentState(mPhone);
-        PerSimStatus perSimStatus2 = PerSimStatus.getCurrentState(mSecondPhone);
-
-        assertEquals(100, perSimStatus1.carrierId);
-        assertEquals(1, perSimStatus1.phoneNumberSourceUicc);
-        assertEquals(0, perSimStatus1.phoneNumberSourceCarrier);
-        assertEquals(1, perSimStatus1.phoneNumberSourceIms);
-        assertEquals(true, perSimStatus1.advancedCallingSettingEnabled);
-        assertEquals(true, perSimStatus1.voWiFiSettingEnabled);
-        assertEquals(PER_SIM_STATUS__WFC_MODE__WIFI_ONLY, perSimStatus1.voWiFiModeSetting);
-        assertEquals(
-                PER_SIM_STATUS__WFC_MODE__CELLULAR_PREFERRED,
-                perSimStatus1.voWiFiRoamingModeSetting);
-        assertEquals(false, perSimStatus1.vtSettingEnabled);
-        assertEquals(false, perSimStatus1.dataRoamingEnabled);
-        assertEquals(1L, perSimStatus1.preferredNetworkType);
-        assertEquals(true, perSimStatus1.disabled2g);
-        assertEquals(true, perSimStatus1.pin1Enabled);
-        assertEquals(
-                PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A,
-                perSimStatus1.minimumVoltageClass);
-        assertEquals(101, perSimStatus2.carrierId);
-        assertEquals(1, perSimStatus2.phoneNumberSourceUicc);
-        assertEquals(2, perSimStatus2.phoneNumberSourceCarrier);
-        assertEquals(2, perSimStatus2.phoneNumberSourceIms);
-        assertEquals(true, perSimStatus2.advancedCallingSettingEnabled);
-        assertEquals(false, perSimStatus2.voWiFiSettingEnabled);
-        assertEquals(PER_SIM_STATUS__WFC_MODE__WIFI_ONLY, perSimStatus2.voWiFiModeSetting);
-        assertEquals(
-                PER_SIM_STATUS__WFC_MODE__WIFI_PREFERRED, perSimStatus2.voWiFiRoamingModeSetting);
-        assertEquals(true, perSimStatus2.vtSettingEnabled);
-        assertEquals(false, perSimStatus2.dataRoamingEnabled);
-        assertEquals(1L, perSimStatus2.preferredNetworkType);
-        assertEquals(false, perSimStatus2.disabled2g);
-        assertEquals(false, perSimStatus2.pin1Enabled);
-        assertEquals(
-                PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_B,
-                perSimStatus2.minimumVoltageClass);
-    }
-
-    @Test
-    @SmallTest
-    public void onPullAtom_perSimStatus_noSubscriptionController() throws Exception {
-        replaceInstance(SubscriptionController.class, "sInstance", null, null);
-
-        PerSimStatus perSimStatus = PerSimStatus.getCurrentState(mPhone);
-
-        assertEquals(perSimStatus, null);
-    }
-
-    @Test
-    @SmallTest
-    public void onPullAtom_perSimStatus_noImsManager() throws Exception {
-        doReturn(0).when(mPhone).getPhoneId();
-        doReturn(1).when(mPhone).getSubId();
-        doReturn(100).when(mPhone).getCarrierId();
-        doReturn("6506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
-        doReturn("")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
-        doReturn("+16506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_IMS, null, null);
-        SubscriptionInfo subscriptionInfo = mock(SubscriptionInfo.class);
-        doReturn("us").when(subscriptionInfo).getCountryIso();
-        doReturn(subscriptionInfo).when(mSubscriptionController).getSubscriptionInfo(1);
-        doReturn(null).when(mContext).getSystemService(ImsManager.class);
-        doReturn(1L)
-                .when(mPhone)
-                .getAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
-        doReturn(0L)
-                .when(mPhone)
-                .getAllowedNetworkTypes(
-                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G & ENABLED_2G);
-        IccCard iccCard = mock(IccCard.class);
-        doReturn(true).when(iccCard).getIccLockEnabled();
-        doReturn(iccCard).when(mPhone).getIccCard();
-        UiccSlot uiccSlot1 = mock(UiccSlot.class);
-        doReturn(UiccSlot.VOLTAGE_CLASS_A).when(uiccSlot1).getMinimumVoltageClass();
-        doReturn(uiccSlot1).when(mUiccController).getUiccSlotForPhone(0);
-
-        PerSimStatus perSimStatus = PerSimStatus.getCurrentState(mPhone);
-
-        assertEquals(100, perSimStatus.carrierId);
-        assertEquals(1, perSimStatus.phoneNumberSourceUicc);
-        assertEquals(0, perSimStatus.phoneNumberSourceCarrier);
-        assertEquals(1, perSimStatus.phoneNumberSourceIms);
-        assertEquals(false, perSimStatus.advancedCallingSettingEnabled);
-        assertEquals(false, perSimStatus.voWiFiSettingEnabled);
-        assertEquals(PER_SIM_STATUS__WFC_MODE__UNKNOWN, perSimStatus.voWiFiModeSetting);
-        assertEquals(PER_SIM_STATUS__WFC_MODE__UNKNOWN, perSimStatus.voWiFiRoamingModeSetting);
-        assertEquals(false, perSimStatus.vtSettingEnabled);
-        assertEquals(false, perSimStatus.dataRoamingEnabled);
-        assertEquals(1L, perSimStatus.preferredNetworkType);
-        assertEquals(true, perSimStatus.disabled2g);
-        assertEquals(true, perSimStatus.pin1Enabled);
-        assertEquals(
-                PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A,
-                perSimStatus.minimumVoltageClass);
-    }
-
-    @Test
-    @SmallTest
-    public void onPullAtom_perSimStatus_noImsMmTelManager() throws Exception {
-        doReturn(0).when(mPhone).getPhoneId();
-        doReturn(1).when(mPhone).getSubId();
-        doReturn(100).when(mPhone).getCarrierId();
-        doReturn("6506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
-        doReturn("")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
-        doReturn("+16506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_IMS, null, null);
-        SubscriptionInfo subscriptionInfo = mock(SubscriptionInfo.class);
-        doReturn("us").when(subscriptionInfo).getCountryIso();
-        doReturn(subscriptionInfo).when(mSubscriptionController).getSubscriptionInfo(1);
-        ImsManager imsManager = mContext.getSystemService(ImsManager.class);
-        doThrow(new IllegalArgumentException()).when(imsManager).getImsMmTelManager(1);
-        doReturn(false).when(mPhone).getDataRoamingEnabled();
-        doReturn(1L)
-                .when(mPhone)
-                .getAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
-        doReturn(0L)
-                .when(mPhone)
-                .getAllowedNetworkTypes(
-                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G & ENABLED_2G);
-        IccCard iccCard = mock(IccCard.class);
-        doReturn(true).when(iccCard).getIccLockEnabled();
-        doReturn(iccCard).when(mPhone).getIccCard();
-        UiccSlot uiccSlot1 = mock(UiccSlot.class);
-        doReturn(UiccSlot.VOLTAGE_CLASS_A).when(uiccSlot1).getMinimumVoltageClass();
-        doReturn(uiccSlot1).when(mUiccController).getUiccSlotForPhone(0);
-
-        PerSimStatus perSimStatus = PerSimStatus.getCurrentState(mPhone);
-
-        assertEquals(100, perSimStatus.carrierId);
-        assertEquals(1, perSimStatus.phoneNumberSourceUicc);
-        assertEquals(0, perSimStatus.phoneNumberSourceCarrier);
-        assertEquals(1, perSimStatus.phoneNumberSourceIms);
-        assertEquals(false, perSimStatus.advancedCallingSettingEnabled);
-        assertEquals(false, perSimStatus.voWiFiSettingEnabled);
-        assertEquals(PER_SIM_STATUS__WFC_MODE__UNKNOWN, perSimStatus.voWiFiModeSetting);
-        assertEquals(PER_SIM_STATUS__WFC_MODE__UNKNOWN, perSimStatus.voWiFiRoamingModeSetting);
-        assertEquals(false, perSimStatus.vtSettingEnabled);
-        assertEquals(false, perSimStatus.dataRoamingEnabled);
-        assertEquals(1L, perSimStatus.preferredNetworkType);
-        assertEquals(true, perSimStatus.disabled2g);
-        assertEquals(true, perSimStatus.pin1Enabled);
-        assertEquals(
-                PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_A,
-                perSimStatus.minimumVoltageClass);
-    }
-
-    @Test
-    @SmallTest
-    public void onPullAtom_perSimStatus_noUiccSlot() throws Exception {
-        doReturn(0).when(mPhone).getPhoneId();
-        doReturn(1).when(mPhone).getSubId();
-        doReturn(100).when(mPhone).getCarrierId();
-        doReturn("6506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_UICC, null, null);
-        doReturn("")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_CARRIER, null, null);
-        doReturn("+16506953210")
-                .when(mSubscriptionController)
-                .getPhoneNumber(1, PHONE_NUMBER_SOURCE_IMS, null, null);
-        SubscriptionInfo subscriptionInfo = mock(SubscriptionInfo.class);
-        doReturn("us").when(subscriptionInfo).getCountryIso();
-        doReturn(subscriptionInfo).when(mSubscriptionController).getSubscriptionInfo(1);
-        doReturn(null).when(mContext).getSystemService(ImsManager.class);
-        doReturn(1L)
-                .when(mPhone)
-                .getAllowedNetworkTypes(TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_USER);
-        doReturn(0L)
-                .when(mPhone)
-                .getAllowedNetworkTypes(
-                        TelephonyManager.ALLOWED_NETWORK_TYPES_REASON_ENABLE_2G & ENABLED_2G);
-        IccCard iccCard = mock(IccCard.class);
-        doReturn(true).when(iccCard).getIccLockEnabled();
-        doReturn(iccCard).when(mPhone).getIccCard();
-        doReturn(null).when(mUiccController).getUiccSlotForPhone(0);
-
-        PerSimStatus perSimStatus = PerSimStatus.getCurrentState(mPhone);
-
-        assertEquals(100, perSimStatus.carrierId);
-        assertEquals(1, perSimStatus.phoneNumberSourceUicc);
-        assertEquals(0, perSimStatus.phoneNumberSourceCarrier);
-        assertEquals(1, perSimStatus.phoneNumberSourceIms);
-        assertEquals(false, perSimStatus.advancedCallingSettingEnabled);
-        assertEquals(false, perSimStatus.voWiFiSettingEnabled);
-        assertEquals(PER_SIM_STATUS__WFC_MODE__UNKNOWN, perSimStatus.voWiFiModeSetting);
-        assertEquals(PER_SIM_STATUS__WFC_MODE__UNKNOWN, perSimStatus.voWiFiRoamingModeSetting);
-        assertEquals(false, perSimStatus.vtSettingEnabled);
-        assertEquals(false, perSimStatus.dataRoamingEnabled);
-        assertEquals(1L, perSimStatus.preferredNetworkType);
-        assertEquals(true, perSimStatus.disabled2g);
-        assertEquals(true, perSimStatus.pin1Enabled);
-        assertEquals(
-                PER_SIM_STATUS__SIM_VOLTAGE_CLASS__VOLTAGE_CLASS_UNKNOWN,
-                perSimStatus.minimumVoltageClass);
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
index d2e30db..df158c1 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/PersistAtomsStorageTest.java
@@ -16,14 +16,6 @@
 
 package com.android.internal.telephony.metrics;
 
-import static android.text.format.DateUtils.DAY_IN_MILLIS;
-
-import static com.android.internal.telephony.TelephonyStatsLog.GBA_EVENT__FAILED_REASON__FEATURE_NOT_READY;
-import static com.android.internal.telephony.TelephonyStatsLog.GBA_EVENT__FAILED_REASON__UNKNOWN;
-import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR;
-import static com.android.internal.telephony.TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML;
-import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT;
-import static com.android.internal.telephony.TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
@@ -41,7 +33,6 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 
 import android.annotation.Nullable;
@@ -50,32 +41,15 @@
 import android.telephony.DisconnectCause;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
-import android.telephony.TelephonyProtoEnums;
 import android.telephony.ims.ImsReasonInfo;
-import android.telephony.ims.SipDelegateManager;
 import android.test.suitebuilder.annotation.SmallTest;
 
-import com.android.internal.telephony.TelephonyStatsLog;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.nano.PersistAtomsProto.CellularDataServiceSwitch;
 import com.android.internal.telephony.nano.PersistAtomsProto.CellularServiceState;
-import com.android.internal.telephony.nano.PersistAtomsProto.DataCallSession;
-import com.android.internal.telephony.nano.PersistAtomsProto.GbaEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerListenerEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationFeatureTagStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationServiceDescStats;
 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationStats;
 import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationTermination;
 import com.android.internal.telephony.nano.PersistAtomsProto.PersistAtoms;
-import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.RcsClientProvisioningStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipDelegateStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipMessageResponse;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportFeatureTagStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportSession;
-import com.android.internal.telephony.nano.PersistAtomsProto.UceEventStats;
 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallRatUsage;
 import com.android.internal.telephony.nano.PersistAtomsProto.VoiceCallSession;
 import com.android.internal.telephony.nano.TelephonyProto.TelephonyCallSession.Event.AudioCodec;
@@ -88,6 +62,7 @@
 import org.junit.rules.TemporaryFolder;
 import org.mockito.ArgumentCaptor;
 import org.mockito.InOrder;
+import org.mockito.Mock;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -104,13 +79,8 @@
     private static final int CARRIER1_ID = 1;
     private static final int CARRIER2_ID = 1187;
     private static final int CARRIER3_ID = 1435;
-    private static final int SLOT_ID1 = 1;
-    private static final int SLOT_ID2 = 2;
-    private static final int REGISTRATION1_TECH = 1;
-    private static final int REGISTRATION2_TECH = 2;
 
-    // Mocked classes
-    private FileOutputStream mTestFileOutputStream;
+    @Mock private FileOutputStream mTestFileOutputStream;
 
     @Rule public TemporaryFolder mFolder = new TemporaryFolder();
 
@@ -144,7 +114,6 @@
     private CellularServiceState mServiceState2Proto;
     private CellularServiceState mServiceState3Proto;
     private CellularServiceState mServiceState4Proto;
-    private CellularServiceState mServiceState5Proto;
 
     private CellularDataServiceSwitch[] mServiceSwitches;
     private CellularServiceState[] mServiceStates;
@@ -161,68 +130,6 @@
     private ImsRegistrationStats[] mImsRegistrationStats;
     private ImsRegistrationTermination[] mImsRegistrationTerminations;
 
-    // Data call sessions
-    private DataCallSession mDataCallSession0;
-    private DataCallSession mDataCallSession1;
-
-    // RCS registration feature tags for slot 0 and 1
-    private ImsRegistrationFeatureTagStats mImsRegistrationFeatureTagStats1Proto;
-    private ImsRegistrationFeatureTagStats mImsRegistrationFeatureTagStats2Proto;
-    private ImsRegistrationFeatureTagStats[] mImsRegistrationFeatureTagStatses;
-
-    // RCS provisioning client stats for slot 0 and 1
-    private RcsClientProvisioningStats mRcsClientProvisioningStats1Proto;
-    private RcsClientProvisioningStats mRcsClientProvisioningStats2Proto;
-    private RcsClientProvisioningStats[] mRcsClientProvisioningStatses;
-
-    // RCS provisioning ACS stats for slot 0 and 1
-    private RcsAcsProvisioningStats mRcsAcsProvisioningStats1Proto;
-    private RcsAcsProvisioningStats mRcsAcsProvisioningStats2Proto;
-    private RcsAcsProvisioningStats[] mRcsAcsProvisioningStatses;
-
-    private ImsRegistrationServiceDescStats mImsRegistrationServiceIm;
-    private ImsRegistrationServiceDescStats mImsRegistrationServiceFt;
-    private ImsRegistrationServiceDescStats[] mImsRegistrationServiceDescStats;
-
-    // IMS dedicated bearer listener event stats for slot 0 and 1
-    private ImsDedicatedBearerListenerEvent mImsDedicatedBearerListenerEvent1;
-    private ImsDedicatedBearerListenerEvent mImsDedicatedBearerListenerEvent2;
-    private ImsDedicatedBearerListenerEvent[] mImsDedicatedBearerListenerEvents;
-
-    // IMS dedicated bearer event stats for slot 0 and 1
-    private ImsDedicatedBearerEvent mImsDedicatedBearerEvent1;
-    private ImsDedicatedBearerEvent mImsDedicatedBearerEvent2;
-    private ImsDedicatedBearerEvent[] mImsDedicatedBearerEvents;
-
-    private UceEventStats mUceEventStats1;
-    private UceEventStats mUceEventStats2;
-    private UceEventStats[] mUceEventStatses;
-
-    private PresenceNotifyEvent mPresenceNotifyEvent1;
-    private PresenceNotifyEvent mPresenceNotifyEvent2;
-    private PresenceNotifyEvent[] mPresenceNotifyEvents;
-
-    private SipTransportFeatureTagStats mSipTransportFeatureTagStats1;
-    private SipTransportFeatureTagStats mSipTransportFeatureTagStats2;
-    private SipTransportFeatureTagStats[] mSipTransportFeatureTagStatsArray;
-
-    private SipDelegateStats mSipDelegateStats1;
-    private SipDelegateStats mSipDelegateStats2;
-    private SipDelegateStats mSipDelegateStats3;
-    private SipDelegateStats[] mSipDelegateStatsArray;
-
-    private GbaEvent mGbaEvent1;
-    private GbaEvent mGbaEvent2;
-    private GbaEvent[] mGbaEvent;
-
-    private SipMessageResponse mSipMessageResponse1;
-    private SipMessageResponse mSipMessageResponse2;
-    private SipMessageResponse[] mSipMessageResponse;
-
-    private SipTransportSession mSipTransportSession1;
-    private SipTransportSession mSipTransportSession2;
-    private SipTransportSession[] mSipTransportSession;
-
     private void makeTestData() {
         // MO call with SRVCC (LTE to UMTS)
         mCall1Proto = new VoiceCallSession();
@@ -311,7 +218,7 @@
         mCall3Proto.isEmergency = false;
         mCall3Proto.isRoaming = false;
 
-        // CS MO emergency call while camped on LTE
+        // CS MO call while camped on LTE
         mCall4Proto = new VoiceCallSession();
         mCall4Proto.bearerAtStart = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
         mCall4Proto.bearerAtEnd = VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
@@ -336,7 +243,7 @@
         mCall4Proto.srvccFailureCount = 0L;
         mCall4Proto.srvccCancellationCount = 0L;
         mCall4Proto.rttEnabled = false;
-        mCall4Proto.isEmergency = true;
+        mCall4Proto.isEmergency = false;
         mCall4Proto.isRoaming = true;
 
         mCarrier1LteUsageProto = new VoiceCallRatUsage();
@@ -409,7 +316,6 @@
         mServiceState1Proto.isMultiSim = true;
         mServiceState1Proto.carrierId = CARRIER1_ID;
         mServiceState1Proto.totalTimeMillis = 5000L;
-        mServiceState1Proto.isEmergencyOnly = false;
 
         // LTE with ENDC on slot 0
         mServiceState2Proto = new CellularServiceState();
@@ -422,7 +328,6 @@
         mServiceState2Proto.isMultiSim = true;
         mServiceState2Proto.carrierId = CARRIER1_ID;
         mServiceState2Proto.totalTimeMillis = 15000L;
-        mServiceState2Proto.isEmergencyOnly = false;
 
         // LTE with WFC and roaming on slot 1
         mServiceState3Proto = new CellularServiceState();
@@ -435,7 +340,6 @@
         mServiceState3Proto.isMultiSim = true;
         mServiceState3Proto.carrierId = CARRIER2_ID;
         mServiceState3Proto.totalTimeMillis = 10000L;
-        mServiceState3Proto.isEmergencyOnly = false;
 
         // UMTS with roaming on slot 1
         mServiceState4Proto = new CellularServiceState();
@@ -448,20 +352,6 @@
         mServiceState4Proto.isMultiSim = true;
         mServiceState4Proto.carrierId = CARRIER2_ID;
         mServiceState4Proto.totalTimeMillis = 10000L;
-        mServiceState4Proto.isEmergencyOnly = false;
-
-        // Limited service on slot 0
-        mServiceState5Proto = new CellularServiceState();
-        mServiceState5Proto.voiceRat = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-        mServiceState5Proto.dataRat = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-        mServiceState5Proto.voiceRoamingType = ServiceState.ROAMING_TYPE_NOT_ROAMING;
-        mServiceState5Proto.dataRoamingType = ServiceState.ROAMING_TYPE_NOT_ROAMING;
-        mServiceState5Proto.isEndc = false;
-        mServiceState5Proto.simSlotIndex = 0;
-        mServiceState5Proto.isMultiSim = true;
-        mServiceState5Proto.carrierId = CARRIER1_ID;
-        mServiceState5Proto.totalTimeMillis = 15000L;
-        mServiceState5Proto.isEmergencyOnly = true;
 
         mServiceSwitches =
                 new CellularDataServiceSwitch[] {mServiceSwitch1Proto, mServiceSwitch2Proto};
@@ -470,8 +360,7 @@
                     mServiceState1Proto,
                     mServiceState2Proto,
                     mServiceState3Proto,
-                    mServiceState4Proto,
-                    mServiceState5Proto
+                    mServiceState4Proto
                 };
 
         // IMS over LTE on slot 0, registered for 5 seconds
@@ -543,327 +432,6 @@
                 new ImsRegistrationTermination[] {
                     mImsRegistrationTerminationLte, mImsRegistrationTerminationWifi
                 };
-
-        mDataCallSession0 = new DataCallSession();
-        mDataCallSession0.dimension = 111;
-        mDataCallSession0.carrierId = CARRIER1_ID;
-        mDataCallSession0.oosAtEnd = false;
-        mDataCallSession0.ratSwitchCount = 3L;
-        mDataCallSession0.setupFailed = false;
-        mDataCallSession0.durationMinutes = 20;
-        mDataCallSession0.ongoing = true;
-
-        mDataCallSession1 = new DataCallSession();
-        mDataCallSession1.dimension = 222;
-        mDataCallSession1.carrierId = CARRIER2_ID;
-        mDataCallSession1.oosAtEnd = true;
-        mDataCallSession1.ratSwitchCount = 1L;
-        mDataCallSession1.setupFailed = false;
-        mDataCallSession1.durationMinutes = 5;
-        mDataCallSession1.ongoing = false;
-
-        // RCS registrtion feature tag slot 0
-        mImsRegistrationFeatureTagStats1Proto = new ImsRegistrationFeatureTagStats();
-        mImsRegistrationFeatureTagStats1Proto.carrierId = CARRIER1_ID;
-        mImsRegistrationFeatureTagStats1Proto.slotId = 0;
-        mImsRegistrationFeatureTagStats1Proto.featureTagName = 1;
-        mImsRegistrationFeatureTagStats1Proto.registrationTech = TelephonyManager.NETWORK_TYPE_LTE;
-        mImsRegistrationFeatureTagStats1Proto.registeredMillis = 3600L;
-
-        // RCS registrtion feature tag slot 1
-        mImsRegistrationFeatureTagStats2Proto = new ImsRegistrationFeatureTagStats();
-        mImsRegistrationFeatureTagStats2Proto.carrierId = CARRIER2_ID;
-        mImsRegistrationFeatureTagStats2Proto.slotId = 1;
-        mImsRegistrationFeatureTagStats2Proto.featureTagName = 0;
-        mImsRegistrationFeatureTagStats2Proto.registrationTech = TelephonyManager.NETWORK_TYPE_LTE;
-        mImsRegistrationFeatureTagStats2Proto.registeredMillis = 3600L;
-
-        mImsRegistrationFeatureTagStatses =
-                new ImsRegistrationFeatureTagStats[] {
-                        mImsRegistrationFeatureTagStats1Proto,
-                        mImsRegistrationFeatureTagStats2Proto
-                };
-
-        // RCS client provisioning stats slot 0
-        mRcsClientProvisioningStats1Proto = new RcsClientProvisioningStats();
-        mRcsClientProvisioningStats1Proto.carrierId = CARRIER1_ID;
-        mRcsClientProvisioningStats1Proto.slotId = 0;
-        mRcsClientProvisioningStats1Proto.event =
-                RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT;
-        mRcsClientProvisioningStats1Proto.count = 1;
-
-        // RCS client provisioning stats slot 1
-        mRcsClientProvisioningStats2Proto = new RcsClientProvisioningStats();
-        mRcsClientProvisioningStats2Proto.carrierId = CARRIER2_ID;
-        mRcsClientProvisioningStats2Proto.slotId = 1;
-        mRcsClientProvisioningStats2Proto.event =
-                RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION;
-        mRcsClientProvisioningStats2Proto.count = 1;
-
-        mRcsClientProvisioningStatses =
-                new RcsClientProvisioningStats[] {
-                        mRcsClientProvisioningStats1Proto,
-                        mRcsClientProvisioningStats2Proto
-                };
-
-        // RCS ACS provisioning stats : error response
-        mRcsAcsProvisioningStats1Proto = new RcsAcsProvisioningStats();
-        mRcsAcsProvisioningStats1Proto.carrierId = CARRIER1_ID;
-        mRcsAcsProvisioningStats1Proto.slotId = 0;
-        mRcsAcsProvisioningStats1Proto.responseCode = 401;
-        mRcsAcsProvisioningStats1Proto.responseType =
-                RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR;
-        mRcsAcsProvisioningStats1Proto.isSingleRegistrationEnabled = true;
-        mRcsAcsProvisioningStats1Proto.count = 1;
-        mRcsAcsProvisioningStats1Proto.stateTimerMillis = START_TIME_MILLIS;
-
-        // RCS ACS provisioning stats : xml
-        mRcsAcsProvisioningStats2Proto = new RcsAcsProvisioningStats();
-        mRcsAcsProvisioningStats2Proto.carrierId = CARRIER1_ID;
-        mRcsAcsProvisioningStats2Proto.slotId = 0;
-        mRcsAcsProvisioningStats2Proto.responseCode = 200;
-        mRcsAcsProvisioningStats2Proto.responseType =
-                RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML;
-        mRcsAcsProvisioningStats2Proto.isSingleRegistrationEnabled = true;
-        mRcsAcsProvisioningStats2Proto.count = 1;
-        mRcsAcsProvisioningStats2Proto.stateTimerMillis = START_TIME_MILLIS;
-
-        mRcsAcsProvisioningStatses =
-                new RcsAcsProvisioningStats[] {
-                        mRcsAcsProvisioningStats1Proto,
-                        mRcsAcsProvisioningStats2Proto
-                };
-
-        mImsRegistrationServiceIm = new ImsRegistrationServiceDescStats();
-        mImsRegistrationServiceIm.carrierId = CARRIER1_ID;
-        mImsRegistrationServiceIm.slotId = SLOT_ID1;
-        mImsRegistrationServiceIm.serviceIdName = 0;
-        mImsRegistrationServiceIm.serviceIdVersion = 1.0f;
-        mImsRegistrationServiceIm.registrationTech = REGISTRATION1_TECH;
-        mImsRegistrationServiceIm.publishedMillis = START_TIME_MILLIS;
-
-        mImsRegistrationServiceFt = new ImsRegistrationServiceDescStats();
-        mImsRegistrationServiceFt.carrierId = CARRIER2_ID;
-        mImsRegistrationServiceFt.slotId = SLOT_ID2;
-        mImsRegistrationServiceFt.serviceIdName = 1;
-        mImsRegistrationServiceFt.serviceIdVersion = 2.0f;
-        mImsRegistrationServiceFt.registrationTech = REGISTRATION2_TECH;
-        mImsRegistrationServiceIm.publishedMillis = START_TIME_MILLIS;
-
-        mImsRegistrationServiceDescStats =
-            new ImsRegistrationServiceDescStats[] {
-                mImsRegistrationServiceIm, mImsRegistrationServiceFt
-            };
-
-
-        mImsDedicatedBearerListenerEvent1 = new ImsDedicatedBearerListenerEvent();
-        mImsDedicatedBearerListenerEvent1.carrierId = CARRIER1_ID;
-        mImsDedicatedBearerListenerEvent1.slotId = SLOT_ID1;
-        mImsDedicatedBearerListenerEvent1.ratAtEnd = TelephonyManager.NETWORK_TYPE_LTE;
-        mImsDedicatedBearerListenerEvent1.qci = 5;
-        mImsDedicatedBearerListenerEvent1.dedicatedBearerEstablished = true;
-        mImsDedicatedBearerListenerEvent1.eventCount = 1;
-
-        mImsDedicatedBearerListenerEvent2 = new ImsDedicatedBearerListenerEvent();
-        mImsDedicatedBearerListenerEvent2.carrierId = CARRIER2_ID;
-        mImsDedicatedBearerListenerEvent2.slotId = SLOT_ID1;
-        mImsDedicatedBearerListenerEvent2.ratAtEnd = TelephonyManager.NETWORK_TYPE_NR;
-        mImsDedicatedBearerListenerEvent2.qci = 6;
-        mImsDedicatedBearerListenerEvent2.dedicatedBearerEstablished = true;
-        mImsDedicatedBearerListenerEvent2.eventCount = 1;
-
-        mImsDedicatedBearerListenerEvents =
-                new ImsDedicatedBearerListenerEvent[] {
-                    mImsDedicatedBearerListenerEvent1, mImsDedicatedBearerListenerEvent2
-                };
-
-
-        mImsDedicatedBearerEvent1 = new ImsDedicatedBearerEvent();
-        mImsDedicatedBearerEvent1.carrierId = CARRIER1_ID;
-        mImsDedicatedBearerEvent1.slotId = SLOT_ID1;
-        mImsDedicatedBearerEvent1.ratAtEnd = TelephonyManager.NETWORK_TYPE_LTE;
-        mImsDedicatedBearerEvent1.qci = 5;
-        mImsDedicatedBearerEvent1.bearerState =
-                TelephonyStatsLog.IMS_DEDICATED_BEARER_EVENT__BEARER_STATE__STATE_ADDED;
-        mImsDedicatedBearerEvent1.localConnectionInfoReceived = true;
-        mImsDedicatedBearerEvent1.remoteConnectionInfoReceived = true;
-        mImsDedicatedBearerEvent1.hasListeners = true;
-        mImsDedicatedBearerEvent1.count = 1;
-
-        mImsDedicatedBearerEvent2 = new ImsDedicatedBearerEvent();
-        mImsDedicatedBearerEvent2.carrierId = CARRIER1_ID;
-        mImsDedicatedBearerEvent2.slotId = SLOT_ID1;
-        mImsDedicatedBearerEvent2.ratAtEnd = TelephonyManager.NETWORK_TYPE_NR;
-        mImsDedicatedBearerEvent2.qci = 6;
-        mImsDedicatedBearerEvent2.bearerState =
-                TelephonyStatsLog.IMS_DEDICATED_BEARER_EVENT__BEARER_STATE__STATE_MODIFIED;
-        mImsDedicatedBearerEvent2.localConnectionInfoReceived = true;
-        mImsDedicatedBearerEvent2.remoteConnectionInfoReceived = true;
-        mImsDedicatedBearerEvent2.hasListeners = true;
-        mImsDedicatedBearerEvent2.count = 1;
-
-        mImsDedicatedBearerEvents =
-                new ImsDedicatedBearerEvent[] {
-                    mImsDedicatedBearerEvent1, mImsDedicatedBearerEvent2
-                };
-
-
-        mUceEventStats1 = new UceEventStats();
-        mUceEventStats1.carrierId = CARRIER1_ID;
-        mUceEventStats1.slotId = SLOT_ID1;
-        mUceEventStats1.type = 1;
-        mUceEventStats1.successful = true;
-        mUceEventStats1.commandCode = 0;
-        mUceEventStats1.networkResponse = 200;
-        mUceEventStats1.count = 1;
-
-        mUceEventStats2 = new UceEventStats();
-        mUceEventStats2.carrierId = CARRIER2_ID;
-        mUceEventStats2.slotId = SLOT_ID2;
-        mUceEventStats2.type = 2;
-        mUceEventStats2.successful = false;
-        mUceEventStats2.commandCode = 2;
-        mUceEventStats2.networkResponse = 0;
-        mUceEventStats2.count = 1;
-        mUceEventStatses = new UceEventStats[] {mUceEventStats1, mUceEventStats2};
-
-        mPresenceNotifyEvent1 = new PresenceNotifyEvent();
-        mPresenceNotifyEvent1.carrierId = CARRIER1_ID;
-        mPresenceNotifyEvent1.slotId = SLOT_ID1;
-        mPresenceNotifyEvent1.reason = 1;
-        mPresenceNotifyEvent1.contentBodyReceived = true;
-        mPresenceNotifyEvent1.rcsCapsCount = 1;
-        mPresenceNotifyEvent1.mmtelCapsCount = 1;
-        mPresenceNotifyEvent1.noCapsCount = 0;
-        mPresenceNotifyEvent1.count = 1;
-
-        mPresenceNotifyEvent2 = new PresenceNotifyEvent();
-        mPresenceNotifyEvent2.carrierId = CARRIER2_ID;
-        mPresenceNotifyEvent2.slotId = SLOT_ID2;
-        mPresenceNotifyEvent2.reason = 1;
-        mPresenceNotifyEvent2.contentBodyReceived = false;
-        mPresenceNotifyEvent2.rcsCapsCount = 0;
-        mPresenceNotifyEvent2.mmtelCapsCount = 0;
-        mPresenceNotifyEvent2.noCapsCount = 1;
-        mPresenceNotifyEvent2.count = 1;
-        mPresenceNotifyEvents = new PresenceNotifyEvent[] {mPresenceNotifyEvent1,
-                mPresenceNotifyEvent2};
-
-        //A destroyed SipDelegate
-        mSipDelegateStats1 = new SipDelegateStats();
-        mSipDelegateStats1.carrierId = CARRIER1_ID;
-        mSipDelegateStats1.slotId = SLOT_ID1;
-        mSipDelegateStats1.uptimeMillis = 1000L;
-        mSipDelegateStats1.destroyReason =
-                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP;
-
-        //An active SipDelegate
-        mSipDelegateStats2 = new SipDelegateStats();
-        mSipDelegateStats2.carrierId = CARRIER1_ID;
-        mSipDelegateStats2.slotId = SLOT_ID1;
-        mSipDelegateStats2.uptimeMillis = 1000L;
-        mSipDelegateStats2.destroyReason =
-                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD;
-
-        //An active SipDelegate
-        mSipDelegateStats3 = new SipDelegateStats();
-        mSipDelegateStats3.carrierId = CARRIER2_ID;
-        mSipDelegateStats3.slotId = SLOT_ID2;
-        mSipDelegateStats3.uptimeMillis = 3000L;
-        mSipDelegateStats3.destroyReason =
-                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SUBSCRIPTION_TORN_DOWN;
-
-        //A registered SipTransportFeatureTag
-        mSipTransportFeatureTagStats1 = new SipTransportFeatureTagStats();
-        mSipTransportFeatureTagStats1.carrierId = CARRIER1_ID;
-        mSipTransportFeatureTagStats1.slotId = SLOT_ID1;
-        mSipTransportFeatureTagStats1.featureTagName = TelephonyProtoEnums.IMS_FEATURE_TAG_CHAT_IM;
-        mSipTransportFeatureTagStats1.sipTransportDeniedReason =  RcsStats.NONE;
-        mSipTransportFeatureTagStats1.sipTransportDeregisteredReason = RcsStats.NONE;
-        mSipTransportFeatureTagStats1.associatedMillis = 1000L;
-
-        //A denied SipTransportFeatureTag
-        mSipTransportFeatureTagStats2 = new SipTransportFeatureTagStats();
-        mSipTransportFeatureTagStats2.carrierId = CARRIER1_ID;
-        mSipTransportFeatureTagStats2.slotId = SLOT_ID1;
-        mSipTransportFeatureTagStats2.featureTagName = 1;
-        mSipTransportFeatureTagStats2.sipTransportDeniedReason =
-                SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE;
-        mSipTransportFeatureTagStats2.sipTransportDeregisteredReason = RcsStats.NONE;
-        mSipTransportFeatureTagStats2.associatedMillis = 1000L;
-
-        mSipDelegateStatsArray = new SipDelegateStats[]{mSipDelegateStats2, mSipDelegateStats3};
-
-        mSipTransportFeatureTagStatsArray = new SipTransportFeatureTagStats[]
-                {mSipTransportFeatureTagStats1, mSipTransportFeatureTagStats2};
-
-        mGbaEvent1 = new GbaEvent();
-        mGbaEvent1.carrierId = CARRIER1_ID;
-        mGbaEvent1.slotId = SLOT_ID1;
-        mGbaEvent1.successful = true;
-        mGbaEvent1.failedReason = GBA_EVENT__FAILED_REASON__UNKNOWN;
-        mGbaEvent1.count = 1;
-
-        mGbaEvent2 = new GbaEvent();
-        mGbaEvent2.carrierId = CARRIER2_ID;
-        mGbaEvent2.slotId = SLOT_ID2;
-        mGbaEvent2.successful = false;
-        mGbaEvent2.failedReason = GBA_EVENT__FAILED_REASON__FEATURE_NOT_READY;
-        mGbaEvent2.count = 1;
-
-        mGbaEvent = new GbaEvent[] {mGbaEvent1, mGbaEvent2};
-
-        //stats slot 0
-        mSipMessageResponse1 = new SipMessageResponse();
-        mSipMessageResponse1.carrierId = CARRIER1_ID;
-        mSipMessageResponse1.slotId = SLOT_ID1;
-        //"INVITE"
-        mSipMessageResponse1.sipMessageMethod = 2;
-        mSipMessageResponse1.sipMessageResponse = 200;
-        mSipMessageResponse1.sipMessageDirection = 1;
-        mSipMessageResponse1.messageError = 0;
-        mSipMessageResponse1.count = 1;
-
-        //stats slot 1
-        mSipMessageResponse2 = new SipMessageResponse();
-        mSipMessageResponse2.carrierId = CARRIER2_ID;
-        mSipMessageResponse2.slotId = SLOT_ID2;
-        //"INVITE"
-        mSipMessageResponse2.sipMessageMethod = 2;
-        mSipMessageResponse2.sipMessageResponse = 200;
-        mSipMessageResponse2.sipMessageDirection = 0;
-        mSipMessageResponse2.messageError = 0;
-        mSipMessageResponse2.count = 1;
-
-        mSipMessageResponse =
-                new SipMessageResponse[] {mSipMessageResponse1, mSipMessageResponse2};
-
-        // stats slot 0
-        mSipTransportSession1 = new SipTransportSession();
-        mSipTransportSession1.carrierId = CARRIER1_ID;
-        mSipTransportSession1.slotId = SLOT_ID1;
-        //"INVITE"
-        mSipTransportSession1.sessionMethod = 2;
-        mSipTransportSession1.sipMessageDirection = 1;
-        mSipTransportSession1.sipResponse = 200;
-        mSipTransportSession1.sessionCount = 1;
-        mSipTransportSession1.endedGracefullyCount = 1;
-        mSipTransportSession1.isEndedGracefully = true;
-
-        // stats slot 1
-        mSipTransportSession2 = new SipTransportSession();
-        mSipTransportSession2.carrierId = CARRIER2_ID;
-        mSipTransportSession2.slotId = SLOT_ID2;
-        //"INVITE"
-        mSipTransportSession2.sessionMethod = 2;
-        mSipTransportSession2.sipMessageDirection = 0;
-        mSipTransportSession2.sipResponse = 200;
-        mSipTransportSession2.sessionCount = 1;
-        mSipTransportSession2.endedGracefullyCount = 1;
-        mSipTransportSession2.isEndedGracefully = true;
-
-        mSipTransportSession =
-                new SipTransportSession[] {mSipTransportSession1, mSipTransportSession2};
     }
 
     private static class TestablePersistAtomsStorage extends PersistAtomsStorage {
@@ -920,7 +488,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mTestFileOutputStream = mock(FileOutputStream.class);
         makeTestData();
 
         // by default, test loading with real file IO and saving with mocks
@@ -932,76 +499,6 @@
     @After
     public void tearDown() throws Exception {
         mTestFile.delete();
-        mTestFile = null;
-        mFolder = null;
-        mCall1Proto = null;
-        mCall2Proto = null;
-        mCall3Proto = null;
-        mCall4Proto = null;
-        mCarrier1LteUsageProto = null;
-        mCarrier1UmtsUsageProto = null;
-        mCarrier2LteUsageProto = null;
-        mCarrier3LteUsageProto = null;
-        mCarrier3GsmUsageProto = null;
-        mVoiceCallRatUsages = null;
-        mServiceSwitch1Proto = null;
-        mServiceSwitch2Proto = null;
-        mServiceState1Proto = null;
-        mServiceState2Proto = null;
-        mServiceState3Proto = null;
-        mServiceState4Proto = null;
-        mServiceState5Proto = null;
-        mServiceSwitches = null;
-        mServiceStates = null;
-        mImsRegistrationStatsLte0 = null;
-        mImsRegistrationStatsWifi0 = null;
-        mImsRegistrationStatsLte1 = null;
-        mImsRegistrationTerminationLte = null;
-        mImsRegistrationTerminationWifi = null;
-        mImsRegistrationStats = null;
-        mImsRegistrationTerminations = null;
-        mDataCallSession0 = null;
-        mDataCallSession1 = null;
-        mImsRegistrationFeatureTagStats1Proto = null;
-        mImsRegistrationFeatureTagStats2Proto = null;
-        mImsRegistrationFeatureTagStatses = null;
-        mRcsClientProvisioningStats1Proto = null;
-        mRcsClientProvisioningStats2Proto = null;
-        mRcsClientProvisioningStatses = null;
-        mRcsAcsProvisioningStats1Proto = null;
-        mRcsAcsProvisioningStats2Proto = null;
-        mRcsAcsProvisioningStatses = null;
-        mImsRegistrationServiceIm = null;
-        mImsRegistrationServiceFt = null;
-        mImsRegistrationServiceDescStats = null;
-        mImsDedicatedBearerListenerEvent1 = null;
-        mImsDedicatedBearerListenerEvent2 = null;
-        mImsDedicatedBearerListenerEvents = null;
-        mImsDedicatedBearerEvent1 = null;
-        mImsDedicatedBearerEvent2 = null;
-        mImsDedicatedBearerEvents = null;
-        mUceEventStats1 = null;
-        mUceEventStats2 = null;
-        mUceEventStatses = null;
-        mPresenceNotifyEvent1 = null;
-        mPresenceNotifyEvent2 = null;
-        mPresenceNotifyEvents = null;
-        mSipTransportFeatureTagStats1 = null;
-        mSipTransportFeatureTagStats2 = null;
-        mSipTransportFeatureTagStatsArray = null;
-        mSipDelegateStats1 = null;
-        mSipDelegateStats2 = null;
-        mSipDelegateStats3 = null;
-        mSipDelegateStatsArray = null;
-        mGbaEvent1 = null;
-        mGbaEvent2 = null;
-        mGbaEvent = null;
-        mSipMessageResponse1 = null;
-        mSipMessageResponse2 = null;
-        mSipMessageResponse = null;
-        mSipTransportSession1 = null;
-        mSipTransportSession2 = null;
-        mSipTransportSession = null;
         super.tearDown();
     }
 
@@ -1152,24 +649,6 @@
 
     @Test
     @SmallTest
-    public void addVoiceCallSession_tooManyCalls_withEmergencyCalls() throws Exception {
-        createEmptyTestFile();
-        // We initially have storage full of emergency calls except one.
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        addRepeatedCalls(mPersistAtomsStorage, mCall4Proto, 49);
-        mPersistAtomsStorage.addVoiceCallSession(mCall1Proto);
-
-        mPersistAtomsStorage.addVoiceCallSession(mCall4Proto);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // after adding one more emergency call, the previous non-emergency call should be evicted
-        verifyCurrentStateSavedToFileOnce();
-        VoiceCallSession[] calls = mPersistAtomsStorage.getVoiceCallSessions(0L);
-        assertHasCall(calls, mCall4Proto, /* expectedCount= */ 50);
-    }
-
-    @Test
-    @SmallTest
     public void addVoiceCallRatUsage_emptyProto() throws Exception {
         createEmptyTestFile();
         VoiceCallRatTracker ratTracker = VoiceCallRatTracker.fromProto(mVoiceCallRatUsages);
@@ -1388,8 +867,7 @@
                     newServiceState1Proto,
                     mServiceState2Proto,
                     mServiceState3Proto,
-                    mServiceState4Proto,
-                    mServiceState5Proto
+                    mServiceState4Proto
                 },
                 serviceStates);
         CellularDataServiceSwitch[] serviceSwitches =
@@ -1514,8 +992,7 @@
                     mServiceState1Proto,
                     mServiceState2Proto,
                     mServiceState3Proto,
-                    mServiceState4Proto,
-                    mServiceState5Proto
+                    mServiceState4Proto
                 },
                 serviceStates1);
         assertProtoArrayEquals(new CellularServiceState[0], serviceStates2);
@@ -1538,8 +1015,8 @@
         createEmptyTestFile();
 
         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegistrationStatsLte0));
-        mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
+        mPersistAtomsStorage.addImsRegistrationStats(mImsRegistrationStatsLte0);
+        mPersistAtomsStorage.incTimeMillis(100L);
 
         // service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
@@ -1552,10 +1029,10 @@
     public void addImsRegistrationStats_withExistingEntries() throws Exception {
         createEmptyTestFile();
         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegistrationStatsLte0));
+        mPersistAtomsStorage.addImsRegistrationStats(mImsRegistrationStatsLte0);
 
-        mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegistrationStatsWifi0));
-        mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
+        mPersistAtomsStorage.addImsRegistrationStats(mImsRegistrationStatsWifi0);
+        mPersistAtomsStorage.incTimeMillis(100L);
 
         // service state and service switch should be added successfully
         verifyCurrentStateSavedToFileOnce();
@@ -1573,7 +1050,7 @@
         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
 
         mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegistrationStatsLte0));
-        mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
+        mPersistAtomsStorage.incTimeMillis(100L);
 
         // mImsRegistrationStatsLte0's durations should be doubled
         verifyCurrentStateSavedToFileOnce();
@@ -1722,7 +1199,7 @@
         createTestFile(START_TIME_MILLIS);
 
         mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS);
+        mPersistAtomsStorage.incTimeMillis(100L);
         ImsRegistrationStats[] stats1 = mPersistAtomsStorage.getImsRegistrationStats(50L);
         mPersistAtomsStorage.incTimeMillis(100L);
         ImsRegistrationStats[] stats2 = mPersistAtomsStorage.getImsRegistrationStats(50L);
@@ -1736,14 +1213,14 @@
                 stats1);
         assertProtoArrayEquals(new ImsRegistrationStats[0], stats2);
         assertEquals(
-                START_TIME_MILLIS + DAY_IN_MILLIS + 100L,
+                START_TIME_MILLIS + 200L,
                 mPersistAtomsStorage.getAtomsProto().imsRegistrationStatsPullTimestampMillis);
         InOrder inOrder = inOrder(mTestFileOutputStream);
         assertEquals(
-                START_TIME_MILLIS + DAY_IN_MILLIS,
+                START_TIME_MILLIS + 100L,
                 getAtomsWritten(inOrder).imsRegistrationStatsPullTimestampMillis);
         assertEquals(
-                START_TIME_MILLIS + DAY_IN_MILLIS + 100L,
+                START_TIME_MILLIS + 200L,
                 getAtomsWritten(inOrder).imsRegistrationStatsPullTimestampMillis);
         inOrder.verifyNoMoreInteractions();
     }
@@ -1796,1318 +1273,6 @@
         inOrder.verifyNoMoreInteractions();
     }
 
-    @Test
-    @SmallTest
-    public void addDataCallSession_newEntry()
-            throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        mPersistAtomsStorage.addDataCallSession(mDataCallSession0);
-        mPersistAtomsStorage.addDataCallSession(mDataCallSession1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // there should be 2 data calls
-        verifyCurrentStateSavedToFileOnce();
-        DataCallSession[] dataCalls = mPersistAtomsStorage.getDataCallSessions(0L);
-        assertProtoArrayEqualsIgnoringOrder(
-                new DataCallSession[]{mDataCallSession0, mDataCallSession1},
-                dataCalls);
-    }
-
-    @Test
-    @SmallTest
-    public void addImsRegistrationFeatureTagStats_emptyProto() throws Exception {
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage
-                .addImsRegistrationFeatureTagStats(mImsRegistrationFeatureTagStats1Proto);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        verifyCurrentStateSavedToFileOnce();
-
-        ImsRegistrationFeatureTagStats[] expected =
-                new ImsRegistrationFeatureTagStats[] {
-                        mImsRegistrationFeatureTagStats1Proto
-                };
-        assertProtoArrayEquals(
-                expected, mPersistAtomsStorage.getImsRegistrationFeatureTagStats(0L));
-    }
-
-    @Test
-    @SmallTest
-    public void addDataCallSession_existingEntry()
-            throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        DataCallSession newDataCallSession0 = copyOf(mDataCallSession0);
-        newDataCallSession0.ongoing = false;
-        newDataCallSession0.ratAtEnd = TelephonyManager.NETWORK_TYPE_LTE;
-        newDataCallSession0.durationMinutes = 10;
-        newDataCallSession0.ratSwitchCount = 5;
-        DataCallSession totalDataCallSession0 = copyOf(newDataCallSession0);
-        totalDataCallSession0.durationMinutes =
-                mDataCallSession0.durationMinutes + newDataCallSession0.durationMinutes;
-        totalDataCallSession0.ratSwitchCount =
-                mDataCallSession0.ratSwitchCount + newDataCallSession0.ratSwitchCount;
-
-        mPersistAtomsStorage.addDataCallSession(mDataCallSession0);
-        mPersistAtomsStorage.addDataCallSession(newDataCallSession0);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // there should be 1 data call
-        verifyCurrentStateSavedToFileOnce();
-        DataCallSession[] dataCalls = mPersistAtomsStorage.getDataCallSessions(0L);
-        assertProtoArrayEqualsIgnoringOrder(
-                new DataCallSession[]{totalDataCallSession0}, dataCalls);
-    }
-
-    @Test
-    @SmallTest
-    public void addImsRegistrationFeatureTagStats_withExistingEntries() throws Exception {
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage
-                .addImsRegistrationFeatureTagStats(mImsRegistrationFeatureTagStats1Proto);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        mPersistAtomsStorage
-                .addImsRegistrationFeatureTagStats(mImsRegistrationFeatureTagStats2Proto);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        verifyCurrentStateSavedToFileOnce();
-
-        ImsRegistrationFeatureTagStats[] expected =
-                new ImsRegistrationFeatureTagStats[] {
-                        mImsRegistrationFeatureTagStats1Proto,
-                        mImsRegistrationFeatureTagStats2Proto
-                };
-        // 2 atoms stored on initially and when try to add 2 same atoms, should be increased.
-        assertProtoArrayEqualsIgnoringOrder(
-                expected, mPersistAtomsStorage.getImsRegistrationFeatureTagStats(0L));
-    }
-
-    @Test
-    @SmallTest
-    public void addImsRegistrationFeatureTagStats_tooManyEntries() throws Exception {
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        int maxCount = 10;
-        for (int i = 0; i < maxCount; i++) {
-            mPersistAtomsStorage
-                    .addImsRegistrationFeatureTagStats(
-                            copyOf(mImsRegistrationFeatureTagStats1Proto));
-            mPersistAtomsStorage.incTimeMillis(100L);
-        }
-
-        mPersistAtomsStorage
-                .addImsRegistrationFeatureTagStats(copyOf(mImsRegistrationFeatureTagStats2Proto));
-
-        verifyCurrentStateSavedToFileOnce();
-
-        ImsRegistrationFeatureTagStats[] result =
-                mPersistAtomsStorage.getImsRegistrationFeatureTagStats(0L);
-
-        // tried store 26 statses, but only 2 statses stored
-        // total time 3600L * maxCount
-        assertHasStatsCountTime(result, mImsRegistrationFeatureTagStats1Proto, 1,
-                maxCount * 3600L);
-        // total time 3600L * 1
-        assertHasStatsCountTime(result, mImsRegistrationFeatureTagStats2Proto, 1,
-                1 * 3600L);
-    }
-
-    @Test
-    @SmallTest
-    public void getImsRegistrationFeatureTagStats_tooFrequent() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
-        ImsRegistrationFeatureTagStats[] result =
-                mPersistAtomsStorage.getImsRegistrationFeatureTagStats(100L);
-
-        // should be denied
-        assertNull(result);
-    }
-
-    @Test
-    @SmallTest
-    public void getImsRegistrationFeatureTagStats_withSavedAtoms() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        ImsRegistrationFeatureTagStats[] statses1 =
-                mPersistAtomsStorage.getImsRegistrationFeatureTagStats(50L);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        ImsRegistrationFeatureTagStats[] statses2 =
-                mPersistAtomsStorage.getImsRegistrationFeatureTagStats(50L);
-
-        // first results of get should have two atoms, second should be empty
-        // pull timestamp should be updated and saved
-        assertProtoArrayEqualsIgnoringOrder(mImsRegistrationFeatureTagStatses, statses1);
-        assertProtoArrayEquals(new ImsRegistrationFeatureTagStats[0], statses2);
-        assertEquals(
-                START_TIME_MILLIS + 200L,
-                mPersistAtomsStorage.getAtomsProto()
-                        .imsRegistrationFeatureTagStatsPullTimestampMillis);
-        InOrder inOrder = inOrder(mTestFileOutputStream);
-        assertEquals(
-                START_TIME_MILLIS + 100L,
-                getAtomsWritten(inOrder).imsRegistrationFeatureTagStatsPullTimestampMillis);
-        assertEquals(
-                START_TIME_MILLIS + 200L,
-                getAtomsWritten(inOrder).imsRegistrationFeatureTagStatsPullTimestampMillis);
-        inOrder.verifyNoMoreInteractions();
-    }
-
-    @Test
-    @SmallTest
-    public void addRcsClientProvisioningStats_emptyProto() throws Exception {
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage
-                .addRcsClientProvisioningStats(mRcsClientProvisioningStats1Proto);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        mPersistAtomsStorage
-                .addRcsClientProvisioningStats(mRcsClientProvisioningStats2Proto);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        verifyCurrentStateSavedToFileOnce();
-
-        RcsClientProvisioningStats[] expected =
-                new RcsClientProvisioningStats[] {
-                        mRcsClientProvisioningStats1Proto,
-                        mRcsClientProvisioningStats2Proto
-                };
-
-        assertProtoArrayEqualsIgnoringOrder(
-                expected, mPersistAtomsStorage.getRcsClientProvisioningStats(0L));
-    }
-
-    @Test
-    @SmallTest
-    public void addRcsClientProvisioningStats_tooManyEntries() throws Exception {
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        // store 11 same atoms, but only 1 atoms stored with count 11
-        for (int i = 0; i < 11; i++) {
-            mPersistAtomsStorage
-                    .addRcsClientProvisioningStats(mRcsClientProvisioningStats1Proto);
-            mPersistAtomsStorage.incTimeMillis(100L);
-        }
-        // store 1 different atom and count 1
-        mPersistAtomsStorage
-                .addRcsClientProvisioningStats(mRcsClientProvisioningStats2Proto);
-
-        verifyCurrentStateSavedToFileOnce();
-
-        RcsClientProvisioningStats[] result =
-                mPersistAtomsStorage.getRcsClientProvisioningStats(0L);
-
-        // first atom has count 11, the other has 1
-        assertHasStatsAndCount(result, mRcsClientProvisioningStats1Proto, 11);
-        assertHasStatsAndCount(result, mRcsClientProvisioningStats2Proto, 1);
-    }
-
-    @Test
-    @SmallTest
-    public void getRcsClientProvisioningStats_tooFrequent() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
-        RcsClientProvisioningStats[] result =
-                mPersistAtomsStorage.getRcsClientProvisioningStats(100L);
-
-        // should be denied
-        assertNull(result);
-    }
-
-    @Test
-    @SmallTest
-    public void getRcsClientProvisioningStats_withSavedAtoms() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        RcsClientProvisioningStats[] statses1 =
-                mPersistAtomsStorage.getRcsClientProvisioningStats(50L);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        RcsClientProvisioningStats[] statses2 =
-                mPersistAtomsStorage.getRcsClientProvisioningStats(50L);
-
-        // first results of get should have two atoms, second should be empty
-        // pull timestamp should be updated and saved
-        assertProtoArrayEqualsIgnoringOrder(mRcsClientProvisioningStatses, statses1);
-        assertProtoArrayEquals(new RcsClientProvisioningStats[0], statses2);
-        assertEquals(
-                START_TIME_MILLIS + 200L,
-                mPersistAtomsStorage.getAtomsProto()
-                        .rcsClientProvisioningStatsPullTimestampMillis);
-        InOrder inOrder = inOrder(mTestFileOutputStream);
-        assertEquals(
-                START_TIME_MILLIS + 100L,
-                getAtomsWritten(inOrder).rcsClientProvisioningStatsPullTimestampMillis);
-        assertEquals(
-                START_TIME_MILLIS + 200L,
-                getAtomsWritten(inOrder).rcsClientProvisioningStatsPullTimestampMillis);
-        inOrder.verifyNoMoreInteractions();
-    }
-
-    @Test
-    @SmallTest
-    public void addRcsAcsProvisioningStats_emptyProto() throws Exception {
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage
-                .addRcsAcsProvisioningStats(mRcsAcsProvisioningStats1Proto);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        mPersistAtomsStorage
-                .addRcsAcsProvisioningStats(mRcsAcsProvisioningStats2Proto);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        verifyCurrentStateSavedToFileOnce();
-
-        RcsAcsProvisioningStats[] expected =
-                new RcsAcsProvisioningStats[] {
-                        mRcsAcsProvisioningStats1Proto,
-                        mRcsAcsProvisioningStats2Proto
-                };
-
-        assertProtoArrayEqualsIgnoringOrder(
-                expected, mPersistAtomsStorage.getRcsAcsProvisioningStats(0L));
-    }
-
-    @Test
-    @SmallTest
-    public void addRcsAcsProvisioningStats_updateExistingEntries() throws Exception {
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        // store 5 same atoms (1Proto), but only 1 atoms stored with count 5, total time 2000L * 5
-        // store 5 same atoms (2Proto), but only 1 atoms stored with count 5, total time 2000L * 5
-        for (int i = 0; i < 5; i++) {
-            mPersistAtomsStorage
-                    .addRcsAcsProvisioningStats(copyOf(mRcsAcsProvisioningStats1Proto));
-            mPersistAtomsStorage.incTimeMillis(100L);
-            mPersistAtomsStorage
-                    .addRcsAcsProvisioningStats(copyOf(mRcsAcsProvisioningStats2Proto));
-            mPersistAtomsStorage.incTimeMillis(100L);
-        }
-        // add one more atoms (2Proto), count 6, total time 2000L * 6
-        mPersistAtomsStorage
-                .addRcsAcsProvisioningStats(copyOf(mRcsAcsProvisioningStats2Proto));
-
-        verifyCurrentStateSavedToFileOnce();
-
-        RcsAcsProvisioningStats[] result =
-                mPersistAtomsStorage.getRcsAcsProvisioningStats(0L);
-
-        // atom (1Proto) : count = 5, time = 2000L * 5
-        assertHasStatsAndCountDuration(result, mRcsAcsProvisioningStats1Proto, 5, 2000L * 5);
-        // atom (2Proto) : count = 6, time = 2000L * 6
-        assertHasStatsAndCountDuration(result, mRcsAcsProvisioningStats2Proto, 6, 2000L * 6);
-    }
-
-    @Test
-    @SmallTest
-    public void getRcsAcsProvisioningStats_tooFrequent() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
-        RcsAcsProvisioningStats[] result =
-                mPersistAtomsStorage.getRcsAcsProvisioningStats(100L);
-
-        // should be denied
-        assertNull(result);
-    }
-
-    @Test
-    @SmallTest
-    public void getRcsAcstProvisioningStats_withSavedAtoms() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        RcsAcsProvisioningStats[] statses1 =
-                mPersistAtomsStorage.getRcsAcsProvisioningStats(50L);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        RcsAcsProvisioningStats[] statses2 =
-                mPersistAtomsStorage.getRcsAcsProvisioningStats(50L);
-
-        // first results of get should have two atoms, second should be empty
-        // pull timestamp should be updated and saved
-        assertProtoArrayEqualsIgnoringOrder(mRcsAcsProvisioningStatses, statses1);
-        assertProtoArrayEquals(new RcsAcsProvisioningStats[0], statses2);
-        assertEquals(
-                START_TIME_MILLIS + 200L,
-                mPersistAtomsStorage.getAtomsProto()
-                        .rcsAcsProvisioningStatsPullTimestampMillis);
-        InOrder inOrder = inOrder(mTestFileOutputStream);
-        assertEquals(
-                START_TIME_MILLIS + 100L,
-                getAtomsWritten(inOrder).rcsAcsProvisioningStatsPullTimestampMillis);
-        assertEquals(
-                START_TIME_MILLIS + 200L,
-                getAtomsWritten(inOrder).rcsAcsProvisioningStatsPullTimestampMillis);
-        inOrder.verifyNoMoreInteractions();
-    }
-
-    @Test
-    @SmallTest
-    public void addImsRegistrationServiceDescStats_emptyProto() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addImsRegistrationServiceDescStats(mImsRegistrationServiceIm);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // service state and service switch should be added successfully
-        verifyCurrentStateSavedToFileOnce();
-        ImsRegistrationServiceDescStats[] outputs =
-            mPersistAtomsStorage.getImsRegistrationServiceDescStats(0L);
-        assertProtoArrayEquals(
-                new ImsRegistrationServiceDescStats[] {mImsRegistrationServiceIm}, outputs);
-    }
-
-    @Test
-    @SmallTest
-    public void addImsRegistrationServiceDescStats_withExistingEntries() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addImsRegistrationServiceDescStats(mImsRegistrationServiceIm);
-
-        mPersistAtomsStorage.addImsRegistrationServiceDescStats(mImsRegistrationServiceFt);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // service state and service switch should be added successfully
-        verifyCurrentStateSavedToFileOnce();
-        ImsRegistrationServiceDescStats[] output =
-            mPersistAtomsStorage.getImsRegistrationServiceDescStats(0L);
-        assertProtoArrayEqualsIgnoringOrder(
-                new ImsRegistrationServiceDescStats[] {
-                    mImsRegistrationServiceIm,
-                    mImsRegistrationServiceFt
-                },
-                output);
-    }
-
-    @Test
-    @SmallTest
-    public void addImsRegistrationServiceDescStats_tooManyServiceDesc() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        Queue<ImsRegistrationServiceDescStats> expectedOutput = new LinkedList<>();
-        // Add 101 registration terminations
-        for (int i = 0; i < 26 + 1; i++) {
-            ImsRegistrationServiceDescStats stats = copyOf(mImsRegistrationServiceIm);
-            stats.registrationTech = i;
-            expectedOutput.add(stats);
-            mPersistAtomsStorage.addImsRegistrationServiceDescStats(stats);
-            mPersistAtomsStorage.incTimeMillis(100L);
-        }
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // The least recent (the first) registration termination should be evicted
-        verifyCurrentStateSavedToFileOnce();
-        ImsRegistrationServiceDescStats[] output =
-            mPersistAtomsStorage.getImsRegistrationServiceDescStats(0L);
-        expectedOutput.remove();
-        assertEquals(expectedOutput.size() - 1, output.length);
-    }
-
-    @Test
-    @SmallTest
-    public void getImsRegistrationServiceDescStats_tooFrequent() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
-        ImsRegistrationServiceDescStats[] output =
-            mPersistAtomsStorage.getImsRegistrationServiceDescStats(100L);
-
-        // should be denied
-        assertNull(output);
-    }
-
-    @Test
-    @SmallTest
-    public void getImsRegistrationServiceDescStats_withSavedAtoms() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        ImsRegistrationServiceDescStats[] output1 =
-            mPersistAtomsStorage.getImsRegistrationServiceDescStats(50L);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        ImsRegistrationServiceDescStats[] output2 =
-            mPersistAtomsStorage.getImsRegistrationServiceDescStats(50L);
-
-        // first set of results should equal to file contents, second should be empty, corresponding
-        // pull timestamp should be updated and saved
-        assertProtoArrayEqualsIgnoringOrder(
-                new ImsRegistrationServiceDescStats[] {
-                    mImsRegistrationServiceIm,
-                    mImsRegistrationServiceFt
-                },
-                output1);
-        assertProtoArrayEquals(new ImsRegistrationServiceDescStats[0], output2);
-        assertEquals(
-                START_TIME_MILLIS + 200L,
-                mPersistAtomsStorage.getAtomsProto()
-                    .imsRegistrationServiceDescStatsPullTimestampMillis);
-        InOrder inOrder = inOrder(mTestFileOutputStream);
-        assertEquals(
-                START_TIME_MILLIS + 100L,
-                getAtomsWritten(inOrder).imsRegistrationServiceDescStatsPullTimestampMillis);
-        assertEquals(
-                START_TIME_MILLIS + 200L,
-                getAtomsWritten(inOrder).imsRegistrationServiceDescStatsPullTimestampMillis);
-        inOrder.verifyNoMoreInteractions();
-    }
-
-    @Test
-    @SmallTest
-    public void getImsRegistrationStats_24hNormalization() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addImsRegistrationStats(copyOf(mImsRegistrationStatsWifi0));
-        mPersistAtomsStorage.incTimeMillis(DAY_IN_MILLIS / 2);
-
-        ImsRegistrationStats[] serviceStates = mPersistAtomsStorage.getImsRegistrationStats(0L);
-        mImsRegistrationStatsWifi0.registeredMillis *= 2;
-        mImsRegistrationStatsWifi0.voiceCapableMillis *= 2;
-        mImsRegistrationStatsWifi0.voiceAvailableMillis *= 2;
-        mImsRegistrationStatsWifi0.smsCapableMillis *= 2;
-        mImsRegistrationStatsWifi0.smsAvailableMillis *= 2;
-        mImsRegistrationStatsWifi0.videoCapableMillis *= 2;
-        mImsRegistrationStatsWifi0.videoAvailableMillis *= 2;
-        mImsRegistrationStatsWifi0.utCapableMillis *= 2;
-        mImsRegistrationStatsWifi0.utAvailableMillis *= 2;
-        assertProtoArrayEqualsIgnoringOrder(
-                new ImsRegistrationStats[] {
-                    mImsRegistrationStatsWifi0
-                },
-                serviceStates);
-    }
-
-    @Test
-    @SmallTest
-    public void addImsDedicatedBearerListenerEvent_emptyProto() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addImsDedicatedBearerListenerEvent(mImsDedicatedBearerListenerEvent1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // service state and service switch should be added successfully
-        verifyCurrentStateSavedToFileOnce();
-        ImsDedicatedBearerListenerEvent[] outputs =
-                mPersistAtomsStorage.getImsDedicatedBearerListenerEvent(0L);
-        assertProtoArrayEquals(
-                new ImsDedicatedBearerListenerEvent[] {mImsDedicatedBearerListenerEvent1}, outputs);
-    }
-
-    @Test
-    @SmallTest
-    public void addImsDedicatedBearerListenerEvent_withExistingEntries() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addImsDedicatedBearerListenerEvent(mImsDedicatedBearerListenerEvent1);
-
-        mPersistAtomsStorage.addImsDedicatedBearerListenerEvent(mImsDedicatedBearerListenerEvent2);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // service state and service switch should be added successfully
-        verifyCurrentStateSavedToFileOnce();
-        ImsDedicatedBearerListenerEvent[] output =
-                mPersistAtomsStorage.getImsDedicatedBearerListenerEvent(0L);
-        assertProtoArrayEqualsIgnoringOrder(
-                new ImsDedicatedBearerListenerEvent[] {
-                    mImsDedicatedBearerListenerEvent1, mImsDedicatedBearerListenerEvent2}, output);
-    }
-
-    @Test
-    @SmallTest
-    public void addImsDedicatedBearerListenerEvent_withSameProto() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        mPersistAtomsStorage.addImsDedicatedBearerListenerEvent(mImsDedicatedBearerListenerEvent1);
-        mPersistAtomsStorage.addImsDedicatedBearerListenerEvent(mImsDedicatedBearerListenerEvent1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // The least recent (the first) registration termination should be evicted
-        verifyCurrentStateSavedToFileOnce();
-        ImsDedicatedBearerListenerEvent[] output =
-                mPersistAtomsStorage.getImsDedicatedBearerListenerEvent(0L);
-        assertEquals(mImsDedicatedBearerListenerEvent1.carrierId, output[0].carrierId);
-        assertEquals(mImsDedicatedBearerListenerEvent1.slotId, output[0].slotId);
-        assertEquals(mImsDedicatedBearerListenerEvent1.ratAtEnd, output[0].ratAtEnd);
-        assertEquals(mImsDedicatedBearerListenerEvent1.qci, output[0].qci);
-        assertEquals(mImsDedicatedBearerListenerEvent1.dedicatedBearerEstablished,
-                output[0].dedicatedBearerEstablished);
-        assertEquals(mImsDedicatedBearerListenerEvent1.eventCount,
-                output[0].eventCount);
-    }
-
-    @Test
-    @SmallTest
-    public void addImsDedicatedBearerEvent_emptyProto() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // service state and service switch should be added successfully
-        verifyCurrentStateSavedToFileOnce();
-        ImsDedicatedBearerEvent[] outputs =
-            mPersistAtomsStorage.getImsDedicatedBearerEvent(0L);
-        assertProtoArrayEquals(
-                new ImsDedicatedBearerEvent[] {mImsDedicatedBearerEvent1}, outputs);
-    }
-
-    @Test
-    @SmallTest
-    public void addImsDedicatedBearerEvent_withExistingEntries() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent1);
-
-        mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent2);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // service state and service switch should be added successfully
-        verifyCurrentStateSavedToFileOnce();
-        ImsDedicatedBearerEvent[] output =
-            mPersistAtomsStorage.getImsDedicatedBearerEvent(0L);
-        assertProtoArrayEqualsIgnoringOrder(
-                    new ImsDedicatedBearerEvent[] {
-                        mImsDedicatedBearerEvent1, mImsDedicatedBearerEvent2}, output);
-    }
-
-    @Test
-    @SmallTest
-    public void addImsDedicatedBearerEvent_withSameProto() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent1);
-        mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // The least recent (the first) registration termination should be evicted
-        verifyCurrentStateSavedToFileOnce();
-        ImsDedicatedBearerEvent[] output =
-            mPersistAtomsStorage.getImsDedicatedBearerEvent(0L);
-        assertEquals(mImsDedicatedBearerEvent1.carrierId, output[0].carrierId);
-        assertEquals(mImsDedicatedBearerEvent1.slotId, output[0].slotId);
-        assertEquals(mImsDedicatedBearerEvent1.ratAtEnd, output[0].ratAtEnd);
-        assertEquals(mImsDedicatedBearerEvent1.qci, output[0].qci);
-        assertEquals(mImsDedicatedBearerEvent1.localConnectionInfoReceived,
-                output[0].localConnectionInfoReceived);
-        assertEquals(mImsDedicatedBearerEvent1.remoteConnectionInfoReceived,
-                output[0].remoteConnectionInfoReceived);
-        assertEquals(mImsDedicatedBearerEvent1.hasListeners,
-                output[0].hasListeners);
-    }
-
-    @Test
-    @SmallTest
-    public void addImsDedicatedBearerEvent_tooManyEntries() throws Exception {
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        // Add 11 stats, but max is 10
-        for (int i = 0; i < 11; i++) {
-            mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent1);
-            mPersistAtomsStorage.incTimeMillis(100L);
-        }
-        mPersistAtomsStorage.addImsDedicatedBearerEvent(mImsDedicatedBearerEvent2);
-
-        verifyCurrentStateSavedToFileOnce();
-        ImsDedicatedBearerEvent[] stats =
-            mPersistAtomsStorage.getImsDedicatedBearerEvent(0L);
-        assertHasStatsAndCount(stats, mImsDedicatedBearerEvent1, 11);
-        assertHasStatsAndCount(stats, mImsDedicatedBearerEvent2, 1);
-    }
-
-    @Test
-    @SmallTest
-    public void addImsDedicatedBearerEvent_updateExistingEntries() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-        ImsDedicatedBearerEvent newStats = copyOf(mImsDedicatedBearerEvent1);
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        mPersistAtomsStorage.addImsDedicatedBearerEvent(copyOf(mImsDedicatedBearerEvent1));
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // mImsDedicatedBearerEvent1's count should be doubled
-        verifyCurrentStateSavedToFileOnce();
-        ImsDedicatedBearerEvent[] stats =
-            mPersistAtomsStorage.getImsDedicatedBearerEvent(0L);
-        newStats.count *= 2;
-        assertProtoArrayEqualsIgnoringOrder(new ImsDedicatedBearerEvent[] {
-                mImsDedicatedBearerEvent2, newStats}, stats);
-    }
-
-
-    @Test
-    @SmallTest
-    public void addUceEventStats_emptyProto() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addUceEventStats(mUceEventStats1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // service state and service switch should be added successfully
-        verifyCurrentStateSavedToFileOnce();
-        UceEventStats[] outputs = mPersistAtomsStorage.getUceEventStats(0L);
-        assertProtoArrayEquals(
-                new UceEventStats[] {mUceEventStats1}, outputs);
-    }
-
-    @Test
-    @SmallTest
-    public void addUceEventStats_withExistingEntries() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addUceEventStats(mUceEventStats1);
-
-        mPersistAtomsStorage.addUceEventStats(mUceEventStats2);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // service state and service switch should be added successfully
-        verifyCurrentStateSavedToFileOnce();
-        UceEventStats[] output = mPersistAtomsStorage.getUceEventStats(0L);
-        assertProtoArrayEqualsIgnoringOrder(
-                new UceEventStats[] {mUceEventStats1, mUceEventStats2}, output);
-    }
-
-    @Test
-    @SmallTest
-    public void addUceEventStats_withSameProto() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        mPersistAtomsStorage.addUceEventStats(mUceEventStats1);
-        mPersistAtomsStorage.addUceEventStats(mUceEventStats1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // The least recent (the first) registration termination should be evicted
-        verifyCurrentStateSavedToFileOnce();
-        UceEventStats[] output = mPersistAtomsStorage.getUceEventStats(0L);
-        assertEquals(mUceEventStats1.carrierId, output[0].carrierId);
-        assertEquals(mUceEventStats1.slotId, output[0].slotId);
-        assertEquals(mUceEventStats1.type, output[0].type);
-        assertEquals(mUceEventStats1.successful, output[0].successful);
-        assertEquals(mUceEventStats1.commandCode, output[0].commandCode);
-        assertEquals(mUceEventStats1.networkResponse, output[0].networkResponse);
-        assertEquals(2, output[0].count);
-    }
-
-    @Test
-    @SmallTest
-    public void addPresenceNotifyEvent_withSameProto() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        PresenceNotifyEvent event1 = new PresenceNotifyEvent();
-        event1.carrierId = CARRIER1_ID;
-        event1.slotId = SLOT_ID1;
-        event1.reason = 1;
-        event1.contentBodyReceived = true;
-        event1.rcsCapsCount = 1;
-        event1.mmtelCapsCount = 1;
-        event1.noCapsCount = 0;
-        event1.count = 1;
-
-        PresenceNotifyEvent event2 = copyOf(event1);
-        event2.rcsCapsCount = 0;
-
-        mPersistAtomsStorage.addPresenceNotifyEvent(event1);
-        mPersistAtomsStorage.addPresenceNotifyEvent(event2);
-
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // The least recent (the first) registration termination should be evicted
-        verifyCurrentStateSavedToFileOnce();
-        PresenceNotifyEvent[] output = mPersistAtomsStorage.getPresenceNotifyEvent(0L);
-
-        assertEquals(event1.carrierId, output[0].carrierId);
-        assertEquals(event1.slotId, output[0].slotId);
-        assertEquals(event1.contentBodyReceived, output[0].contentBodyReceived);
-        assertEquals(1, output[0].rcsCapsCount);
-        assertEquals(2, output[0].mmtelCapsCount);
-        assertEquals(2, output[0].count);
-
-    }
-    @Test
-    @SmallTest
-    public void addPresenceNotifyEvent_withExistingEntries() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addPresenceNotifyEvent(mPresenceNotifyEvent1);
-        mPersistAtomsStorage.addPresenceNotifyEvent(mPresenceNotifyEvent2);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // service state and service switch should be added successfully
-        verifyCurrentStateSavedToFileOnce();
-        PresenceNotifyEvent[] output = mPersistAtomsStorage.getPresenceNotifyEvent(0L);
-        assertProtoArrayEqualsIgnoringOrder(
-                new PresenceNotifyEvent[] {mPresenceNotifyEvent1, mPresenceNotifyEvent2}, output);
-    }
-
-    @Test
-    @SmallTest
-    public void getPresenceNotifyEvent_tooFrequent() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
-        PresenceNotifyEvent[] output = mPersistAtomsStorage.getPresenceNotifyEvent(100L);
-
-        // should be denied
-        assertNull(output);
-    }
-
-    @Test
-    @SmallTest
-    public void getPresenceNotifyEvent_withSavedAtoms() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        PresenceNotifyEvent[] output1 = mPersistAtomsStorage.getPresenceNotifyEvent(50L);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        PresenceNotifyEvent[] output2 = mPersistAtomsStorage.getPresenceNotifyEvent(50L);
-
-        // first set of results should equal to file contents, second should be empty, corresponding
-        // pull timestamp should be updated and saved
-        assertProtoArrayEqualsIgnoringOrder(
-                new PresenceNotifyEvent[] {mPresenceNotifyEvent1, mPresenceNotifyEvent2}, output1);
-        assertProtoArrayEquals(new PresenceNotifyEvent[0], output2);
-        assertEquals(
-                START_TIME_MILLIS + 200L,
-                mPersistAtomsStorage.getAtomsProto().presenceNotifyEventPullTimestampMillis);
-        InOrder inOrder = inOrder(mTestFileOutputStream);
-        assertEquals(
-                START_TIME_MILLIS + 100L,
-                getAtomsWritten(inOrder).presenceNotifyEventPullTimestampMillis);
-        assertEquals(
-                START_TIME_MILLIS + 200L,
-                getAtomsWritten(inOrder).presenceNotifyEventPullTimestampMillis);
-        inOrder.verifyNoMoreInteractions();
-    }
-
-    @Test
-    @SmallTest
-    public void addSipTransportFeatureTag_emptyProto() throws Exception {
-        // verify add atom into new file
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addSipTransportFeatureTagStats(mSipTransportFeatureTagStats1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        verifyCurrentStateSavedToFileOnce();
-
-        SipTransportFeatureTagStats[] outputs =
-                mPersistAtomsStorage.getSipTransportFeatureTagStats(0L);
-        assertProtoArrayEquals(
-                new SipTransportFeatureTagStats[] {mSipTransportFeatureTagStats1}, outputs);
-    }
-
-    @Test
-    @SmallTest
-    public void addSipTransportFeatureTagStats_withExistingEntries() throws Exception {
-        // verify add atom on existing atom already stored
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        //Add two different SipTransportFeatureTagStats.
-        mPersistAtomsStorage.addSipTransportFeatureTagStats(mSipTransportFeatureTagStats1);
-        mPersistAtomsStorage.addSipTransportFeatureTagStats(mSipTransportFeatureTagStats2);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // SipTransportFeatureTagStats should be added successfully
-        verifyCurrentStateSavedToFileOnce();
-        SipTransportFeatureTagStats[] outputs =
-                mPersistAtomsStorage.getSipTransportFeatureTagStats(0L);
-
-        assertProtoArrayEqualsIgnoringOrder(new SipTransportFeatureTagStats[]
-                {mSipTransportFeatureTagStats1, mSipTransportFeatureTagStats2}, outputs);
-    }
-
-    @Test
-    @SmallTest
-    public void addSipTransportFeatureTagStats_tooManyEntries() throws Exception {
-        // verify add atom excess MAX count (100)
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        // Try to add 26 stats where MAX is 25
-        int max = 26;
-        SipTransportFeatureTagStats[] overMaxSipTransportFeatureTagStats =
-                new SipTransportFeatureTagStats[max];
-
-        for (int i = 0; i < max; i++) {
-            overMaxSipTransportFeatureTagStats[i] = copyOf(mSipTransportFeatureTagStats1);
-            overMaxSipTransportFeatureTagStats[i].sipTransportDeniedReason = i;
-            mPersistAtomsStorage
-                    .addSipTransportFeatureTagStats(overMaxSipTransportFeatureTagStats[i]);
-            mPersistAtomsStorage.incTimeMillis(100L);
-        }
-
-        mPersistAtomsStorage
-                .addSipTransportFeatureTagStats(mSipTransportFeatureTagStats2);
-        verifyCurrentStateSavedToFileOnce();
-
-        SipTransportFeatureTagStats[] outputs =
-                mPersistAtomsStorage.getSipTransportFeatureTagStats(0L);
-
-        // The last added SipTransportFeatureTagStat remains
-        // and two old stats should be removed
-        assertHasStats(outputs, overMaxSipTransportFeatureTagStats, max - 2);
-        assertHasStats(outputs, mSipTransportFeatureTagStats2, 1);
-    }
-
-    @Test
-    @SmallTest
-    public void addSipTransportFeatureTagStats_updateExistingEntries() throws Exception {
-        // verify count
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addSipTransportFeatureTagStats(copyOf(mSipTransportFeatureTagStats1));
-        mPersistAtomsStorage.incTimeMillis(100L);
-        verifyCurrentStateSavedToFileOnce();
-
-        // SipTransportFeatureTag's durations should be doubled
-        SipTransportFeatureTagStats newSipTransportFeatureTagStats1 =
-                copyOf(mSipTransportFeatureTagStats1);
-        newSipTransportFeatureTagStats1.associatedMillis *= 2;
-
-        SipTransportFeatureTagStats[] outputs =
-                mPersistAtomsStorage.getSipTransportFeatureTagStats(0L);
-
-        assertProtoArrayEqualsIgnoringOrder(
-                new SipTransportFeatureTagStats[] {
-                        newSipTransportFeatureTagStats1,
-                        mSipTransportFeatureTagStats2
-                }, outputs);
-    }
-
-    @Test
-    @SmallTest
-    public void getSipTransportFeatureTagStats_tooFrequent() throws Exception {
-        // verify get frequently
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
-
-        SipTransportFeatureTagStats[] outputs =
-                mPersistAtomsStorage.getSipTransportFeatureTagStats(100L);
-
-        // should be denied
-        assertNull(outputs);
-    }
-
-    @Test
-    @SmallTest
-    public void getSipTransportFeatureTagStats_withSavedAtoms() throws Exception {
-        // verify last get time after get atoms
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        SipTransportFeatureTagStats[] output1 =
-                mPersistAtomsStorage.getSipTransportFeatureTagStats(50L);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        SipTransportFeatureTagStats[] output2 =
-                mPersistAtomsStorage.getSipTransportFeatureTagStats(50L);
-
-        // first set of results should equal to file contents, second should be empty, corresponding
-        // pull timestamp should be updated and saved
-        assertProtoArrayEqualsIgnoringOrder(
-                new SipTransportFeatureTagStats[] {
-                        mSipTransportFeatureTagStats1,
-                        mSipTransportFeatureTagStats2
-                }, output1);
-        assertProtoArrayEquals(new SipTransportFeatureTagStats[0], output2);
-        assertEquals(START_TIME_MILLIS + 200L,
-                mPersistAtomsStorage.getAtomsProto()
-                        .sipTransportFeatureTagStatsPullTimestampMillis);
-
-        InOrder inOrder = inOrder(mTestFileOutputStream);
-        assertEquals(START_TIME_MILLIS + 100L,
-                getAtomsWritten(inOrder).sipTransportFeatureTagStatsPullTimestampMillis);
-        assertEquals(START_TIME_MILLIS + 200L,
-                getAtomsWritten(inOrder).sipTransportFeatureTagStatsPullTimestampMillis);
-        inOrder.verifyNoMoreInteractions();
-    }
-
-    @Test
-    @SmallTest
-    public void addSipDelegateStats_emptyProto() throws Exception {
-        // verify add atom into new file
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addSipDelegateStats(mSipDelegateStats1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        verifyCurrentStateSavedToFileOnce();
-
-        SipDelegateStats[] outputs = mPersistAtomsStorage.getSipDelegateStats(0L);
-        assertProtoArrayEquals(new SipDelegateStats[] {mSipDelegateStats1}, outputs);
-    }
-
-    @Test
-    @SmallTest
-    public void addSipDelegateStats_withExistingEntries() throws Exception {
-        // verify add atom on existing atom already stored
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addSipDelegateStats(copyOf(mSipDelegateStats1));
-        mPersistAtomsStorage.addSipDelegateStats(copyOf(mSipDelegateStats2));
-        mPersistAtomsStorage.addSipDelegateStats(copyOf(mSipDelegateStats3));
-        mPersistAtomsStorage.incTimeMillis(100L);
-        // Three SipDelegateStats should be added successfully
-        verifyCurrentStateSavedToFileOnce();
-
-        SipDelegateStats[] outputs =
-                mPersistAtomsStorage.getSipDelegateStats(0L);
-
-        assertProtoArrayEqualsIgnoringOrder(
-                new SipDelegateStats[] {mSipDelegateStats1, mSipDelegateStats2, mSipDelegateStats3},
-                outputs);
-    }
-
-    @Test
-    @SmallTest
-    public void addSipDelegateStats_tooManyEntries() throws Exception {
-        // verify add atom excess MAX count
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        // Try to add 11 stats where MAX is 10
-        int max = 11;
-        SipDelegateStats[] overMaxSipDelegateStats = new SipDelegateStats[max];
-        for (int i = 0; i < max; i++) {
-            overMaxSipDelegateStats[i] = copyOf(mSipDelegateStats1);
-            mPersistAtomsStorage
-                    .addSipDelegateStats(overMaxSipDelegateStats[i]);
-            mPersistAtomsStorage.incTimeMillis(100L);
-        }
-        mPersistAtomsStorage.addSipDelegateStats(mSipDelegateStats3);
-        verifyCurrentStateSavedToFileOnce();
-
-        SipDelegateStats[] outputs =
-                mPersistAtomsStorage.getSipDelegateStats(0L);
-
-        // The last added SipDelegate remains
-        // and two old stats should be removed
-        assertHasStats(outputs, overMaxSipDelegateStats, max - 2);
-        assertHasStats(outputs, mSipDelegateStats3, 1);
-    }
-
-    @Test
-    @SmallTest
-    public void addSipDelegateStats_updateExistingEntries() throws Exception {
-        // verify count
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        SipDelegateStats newSipDelegateStats3 = copyOf(mSipDelegateStats3);
-        newSipDelegateStats3.destroyReason =
-                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD;
-        mPersistAtomsStorage.addSipDelegateStats(newSipDelegateStats3);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        SipDelegateStats newSipDelegateStats1 = copyOf(mSipDelegateStats1);
-        newSipDelegateStats1.destroyReason =
-                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP;
-        mPersistAtomsStorage.addSipDelegateStats(newSipDelegateStats1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        verifyCurrentStateSavedToFileOnce();
-
-        SipDelegateStats[] outputs = mPersistAtomsStorage.getSipDelegateStats(0L);
-
-        assertProtoArrayEqualsIgnoringOrder(
-                new SipDelegateStats[] {mSipDelegateStats2, mSipDelegateStats3,
-                        newSipDelegateStats3, newSipDelegateStats1}, outputs);
-    }
-
-    @Test
-    @SmallTest
-    public void getSipDelegateStats_tooFrequent() throws Exception {
-        // verify get frequently
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(50L); // pull interval less than minimum
-
-        SipDelegateStats[] outputs = mPersistAtomsStorage.getSipDelegateStats(100L);
-        // should be denied
-        assertNull(outputs);
-    }
-
-    @Test
-    @SmallTest
-    public void getSipDelegateStats_withSavedAtoms() throws Exception {
-        // verify last get time after get atoms
-        createTestFile(START_TIME_MILLIS);
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        SipDelegateStats[] output1 = mPersistAtomsStorage.getSipDelegateStats(50L);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        SipDelegateStats[] output2 = mPersistAtomsStorage.getSipDelegateStats(50L);
-
-        // first set of results should equal to file contents, second should be empty, corresponding
-        // pull timestamp should be updated and saved
-        assertProtoArrayEqualsIgnoringOrder(
-                new SipDelegateStats[] {
-                        mSipDelegateStats2,
-                        mSipDelegateStats3}, output1);
-        assertProtoArrayEquals(new SipDelegateStats[0], output2);
-        assertEquals(
-                START_TIME_MILLIS + 200L,
-                mPersistAtomsStorage.getAtomsProto().sipDelegateStatsPullTimestampMillis);
-        InOrder inOrder = inOrder(mTestFileOutputStream);
-        assertEquals(
-                START_TIME_MILLIS + 100L,
-                getAtomsWritten(inOrder).sipDelegateStatsPullTimestampMillis);
-        assertEquals(
-                START_TIME_MILLIS + 200L,
-                getAtomsWritten(inOrder).sipDelegateStatsPullTimestampMillis);
-        inOrder.verifyNoMoreInteractions();
-    }
-
-    @Test
-    @SmallTest
-    public void addGbaEvent_emptyProto() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addGbaEvent(mGbaEvent1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // gba event should be added successfully
-        verifyCurrentStateSavedToFileOnce();
-        GbaEvent[] stats = mPersistAtomsStorage.getGbaEvent(0L);
-        assertProtoArrayEquals(new GbaEvent[] {mGbaEvent1}, stats);
-    }
-
-    @Test
-    @SmallTest
-    public void addGbaEvent_withExistingEntries() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addGbaEvent(mGbaEvent1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        mPersistAtomsStorage.addGbaEvent(mGbaEvent2);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // gba event1, gba event2 should be added successfully
-        verifyCurrentStateSavedToFileOnce();
-        GbaEvent[] stats = mPersistAtomsStorage.getGbaEvent(0L);
-        assertProtoArrayEqualsIgnoringOrder(
-                new GbaEvent[] {mGbaEvent1, mGbaEvent2}, stats);
-    }
-
-    @Test
-    @SmallTest
-    public void addGbaEvent_tooManyEntries() throws Exception {
-        createEmptyTestFile();
-
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        // Add 11 stats, but max is 10
-        for (int i = 0; i < 11; i++) {
-            mPersistAtomsStorage.addGbaEvent(mGbaEvent1);
-            mPersistAtomsStorage.incTimeMillis(100L);
-        }
-        mPersistAtomsStorage.addGbaEvent(mGbaEvent2);
-
-        verifyCurrentStateSavedToFileOnce();
-        GbaEvent[] stats = mPersistAtomsStorage.getGbaEvent(0L);
-        assertHasStatsAndCount(stats, mGbaEvent1, 11);
-        assertHasStatsAndCount(stats, mGbaEvent2, 1);
-    }
-
-    @Test
-    @SmallTest
-    public void addGbaEvent_updateExistingEntries() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-        GbaEvent newStats = copyOf(mGbaEvent1);
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        mPersistAtomsStorage.addGbaEvent(copyOf(mGbaEvent1));
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        // mGbaEvent1's count should be doubled
-        verifyCurrentStateSavedToFileOnce();
-        GbaEvent[] stats =
-                mPersistAtomsStorage.getGbaEvent(0L);
-        newStats.count *= 2;
-        assertProtoArrayEqualsIgnoringOrder(new GbaEvent[] {mGbaEvent2, newStats}, stats);
-    }
-
-    @Test
-    @SmallTest
-    public void addSipMessageResponse_emptyProto() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addSipMessageResponse(mSipMessageResponse1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        verifyCurrentStateSavedToFileOnce();
-        SipMessageResponse[] expected = mPersistAtomsStorage.getSipMessageResponse(0L);
-        assertProtoArrayEquals(new SipMessageResponse[] {mSipMessageResponse1}, expected);
-    }
-
-    @Test
-    @SmallTest
-    public void addSipMessageResponse_withExistingEntries() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addSipMessageResponse(mSipMessageResponse1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        mPersistAtomsStorage.addSipMessageResponse(mSipMessageResponse2);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        verifyCurrentStateSavedToFileOnce();
-        SipMessageResponse[] expected =
-                new SipMessageResponse[] {mSipMessageResponse1, mSipMessageResponse2};
-
-        assertProtoArrayEqualsIgnoringOrder(
-                expected, mPersistAtomsStorage.getSipMessageResponse(0L));
-    }
-
-    @Test
-    @SmallTest
-    public void addSipMessageResponse_tooManyEntries() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        // store 11 same atoms, but only 1 atoms stored with count 11
-        for (int i = 0; i < 11; i++) {
-            mPersistAtomsStorage.addSipMessageResponse(mSipMessageResponse1);
-            mPersistAtomsStorage.incTimeMillis(100L);
-        }
-        // store 1 different atom and count 1
-        mPersistAtomsStorage.addSipMessageResponse(mSipMessageResponse2);
-
-        verifyCurrentStateSavedToFileOnce();
-        SipMessageResponse[] result = mPersistAtomsStorage.getSipMessageResponse(0L);
-
-        // first atom has count 11, the other has 1
-        assertHasStats(result, mSipMessageResponse1, 11);
-        assertHasStats(result, mSipMessageResponse2, 1);
-    }
-
-    @Test
-    @SmallTest
-    public void addSipMessageResponse_updateExistingEntries() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addSipMessageResponse(copyOf(mSipMessageResponse2));
-        mPersistAtomsStorage.incTimeMillis(100L);
-        verifyCurrentStateSavedToFileOnce();
-
-        SipMessageResponse[] outputs = mPersistAtomsStorage.getSipMessageResponse(0L);
-        SipMessageResponse newSipMessageResponse = copyOf(mSipMessageResponse2);
-        newSipMessageResponse.count *= 2;
-        assertProtoArrayEqualsIgnoringOrder(
-                new SipMessageResponse[] {mSipMessageResponse1, newSipMessageResponse}, outputs);
-    }
-
-    @Test
-    @SmallTest
-    public void addCompleteSipTransportSession_emptyProto() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addCompleteSipTransportSession(mSipTransportSession1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        verifyCurrentStateSavedToFileOnce();
-        SipTransportSession[] expected = mPersistAtomsStorage.getSipTransportSession(0L);
-        assertProtoArrayEquals(new SipTransportSession[] {mSipTransportSession1}, expected);
-    }
-
-    @Test
-    @SmallTest
-    public void addCompleteSipTransportSession_withExistingEntries() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addCompleteSipTransportSession(mSipTransportSession1);
-        mPersistAtomsStorage.incTimeMillis(100L);
-        mPersistAtomsStorage.addCompleteSipTransportSession(mSipTransportSession2);
-        mPersistAtomsStorage.incTimeMillis(100L);
-
-        verifyCurrentStateSavedToFileOnce();
-        SipTransportSession[] expected =
-                new SipTransportSession[] {mSipTransportSession1, mSipTransportSession2};
-
-        assertProtoArrayEqualsIgnoringOrder(
-                expected, mPersistAtomsStorage.getSipTransportSession(0L));
-    }
-
-    @Test
-    @SmallTest
-    public void addCompleteSipTransportSession_tooManyEntries() throws Exception {
-        createEmptyTestFile();
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-
-        // store 11 same atoms, but only 1 atoms stored with count 11
-        for (int i = 0; i < 11; i++) {
-            mPersistAtomsStorage.addCompleteSipTransportSession(mSipTransportSession1);
-            mPersistAtomsStorage.incTimeMillis(100L);
-        }
-        // store 1 different atom and count 1
-        mPersistAtomsStorage.addCompleteSipTransportSession(mSipTransportSession2);
-
-        verifyCurrentStateSavedToFileOnce();
-        SipTransportSession[] result = mPersistAtomsStorage.getSipTransportSession(0L);
-
-        // first atom has count 11, the other has 1
-        assertHasStats(result, mSipTransportSession1, 11);
-        assertHasStats(result, mSipTransportSession2, 1);
-    }
-
-    @Test
-    @SmallTest
-    public void addCompleteSipTransportSession_updateExistingEntries() throws Exception {
-        createTestFile(START_TIME_MILLIS);
-        mPersistAtomsStorage = new TestablePersistAtomsStorage(mContext);
-        mPersistAtomsStorage.addCompleteSipTransportSession(copyOf(mSipTransportSession2));
-        mPersistAtomsStorage.incTimeMillis(100L);
-        verifyCurrentStateSavedToFileOnce();
-
-        SipTransportSession[] outputs = mPersistAtomsStorage.getSipTransportSession(0L);
-        SipTransportSession newSipTransportSession = copyOf(mSipTransportSession2);
-        newSipTransportSession.sessionCount *= 2;
-        newSipTransportSession.endedGracefullyCount *= 2;
-        assertProtoArrayEqualsIgnoringOrder(
-                new SipTransportSession[] {mSipTransportSession1,
-                        newSipTransportSession}, outputs);
-    }
-
     /* Utilities */
 
     private void createEmptyTestFile() throws Exception {
@@ -3132,32 +1297,6 @@
         atoms.imsRegistrationStats = mImsRegistrationStats;
         atoms.imsRegistrationTerminationPullTimestampMillis = lastPullTimeMillis;
         atoms.imsRegistrationTermination = mImsRegistrationTerminations;
-        atoms.imsRegistrationFeatureTagStatsPullTimestampMillis = lastPullTimeMillis;
-        atoms.imsRegistrationFeatureTagStats = mImsRegistrationFeatureTagStatses;
-        atoms.rcsClientProvisioningStatsPullTimestampMillis = lastPullTimeMillis;
-        atoms.rcsClientProvisioningStats = mRcsClientProvisioningStatses;
-        atoms.rcsAcsProvisioningStatsPullTimestampMillis = lastPullTimeMillis;
-        atoms.rcsAcsProvisioningStats = mRcsAcsProvisioningStatses;
-        atoms.imsRegistrationServiceDescStatsPullTimestampMillis = lastPullTimeMillis;
-        atoms.imsRegistrationServiceDescStats = mImsRegistrationServiceDescStats;
-        atoms.imsDedicatedBearerListenerEventPullTimestampMillis = lastPullTimeMillis;
-        atoms.imsDedicatedBearerListenerEvent = mImsDedicatedBearerListenerEvents;
-        atoms.imsDedicatedBearerEventPullTimestampMillis = lastPullTimeMillis;
-        atoms.imsDedicatedBearerEvent = mImsDedicatedBearerEvents;
-        atoms.uceEventStatsPullTimestampMillis = lastPullTimeMillis;
-        atoms.uceEventStats = mUceEventStatses;
-        atoms.presenceNotifyEventPullTimestampMillis = lastPullTimeMillis;
-        atoms.presenceNotifyEvent = mPresenceNotifyEvents;
-        atoms.sipTransportFeatureTagStatsPullTimestampMillis = lastPullTimeMillis;
-        atoms.sipTransportFeatureTagStats = mSipTransportFeatureTagStatsArray;
-        atoms.sipDelegateStatsPullTimestampMillis = lastPullTimeMillis;
-        atoms.sipDelegateStats = mSipDelegateStatsArray;
-        atoms.gbaEventPullTimestampMillis = lastPullTimeMillis;
-        atoms.gbaEvent = mGbaEvent;
-        atoms.sipMessageResponsePullTimestampMillis = lastPullTimeMillis;
-        atoms.sipMessageResponse = mSipMessageResponse;
-        atoms.sipTransportSessionPullTimestampMillis = lastPullTimeMillis;
-        atoms.sipTransportSession = mSipTransportSession;
         FileOutputStream stream = new FileOutputStream(mTestFile);
         stream.write(PersistAtoms.toByteArray(atoms));
         stream.close();
@@ -3212,70 +1351,6 @@
         return ImsRegistrationTermination.parseFrom(MessageNano.toByteArray(source));
     }
 
-    private static DataCallSession copyOf(DataCallSession source)
-            throws Exception {
-        return DataCallSession.parseFrom(MessageNano.toByteArray(source));
-    }
-
-    private static ImsRegistrationFeatureTagStats copyOf(ImsRegistrationFeatureTagStats source)
-            throws Exception {
-        return ImsRegistrationFeatureTagStats.parseFrom(MessageNano.toByteArray(source));
-    }
-
-    private static RcsAcsProvisioningStats copyOf(RcsAcsProvisioningStats source)
-            throws Exception {
-        return RcsAcsProvisioningStats.parseFrom(MessageNano.toByteArray(source));
-    }
-
-    private static ImsRegistrationServiceDescStats copyOf(ImsRegistrationServiceDescStats source)
-            throws Exception {
-        return ImsRegistrationServiceDescStats.parseFrom(MessageNano.toByteArray(source));
-    }
-
-    private static ImsDedicatedBearerListenerEvent copyOf(ImsDedicatedBearerListenerEvent source)
-            throws Exception {
-        return ImsDedicatedBearerListenerEvent.parseFrom(MessageNano.toByteArray(source));
-    }
-
-    private static ImsDedicatedBearerEvent copyOf(ImsDedicatedBearerEvent source)
-            throws Exception {
-        return ImsDedicatedBearerEvent.parseFrom(MessageNano.toByteArray(source));
-    }
-
-    private static UceEventStats copyOf(UceEventStats source)
-            throws Exception {
-        return UceEventStats.parseFrom(MessageNano.toByteArray(source));
-    }
-
-    private static PresenceNotifyEvent copyOf(PresenceNotifyEvent source)
-            throws Exception {
-        return PresenceNotifyEvent.parseFrom(MessageNano.toByteArray(source));
-    }
-
-    private static SipDelegateStats copyOf(SipDelegateStats source)
-            throws Exception {
-        return SipDelegateStats.parseFrom(MessageNano.toByteArray(source));
-    }
-    private static SipTransportFeatureTagStats copyOf(SipTransportFeatureTagStats source)
-            throws Exception {
-        return SipTransportFeatureTagStats.parseFrom(MessageNano.toByteArray(source));
-    }
-
-    private static GbaEvent copyOf(GbaEvent source)
-            throws Exception {
-        return GbaEvent.parseFrom(MessageNano.toByteArray(source));
-    }
-
-    private static SipMessageResponse copyOf(SipMessageResponse source)
-            throws Exception {
-        return SipMessageResponse.parseFrom(MessageNano.toByteArray(source));
-    }
-
-    private static SipTransportSession copyOf(SipTransportSession source)
-            throws Exception {
-        return SipTransportSession.parseFrom(MessageNano.toByteArray(source));
-    }
-
     private void assertAllPullTimestampEquals(long timestamp) {
         assertEquals(
                 timestamp,
@@ -3346,213 +1421,4 @@
         inOrder.verify(mTestFileOutputStream, times(1)).close();
         inOrder.verifyNoMoreInteractions();
     }
-
-    private static void assertHasStatsCountTime(
-            ImsRegistrationFeatureTagStats[] statses,
-            @Nullable ImsRegistrationFeatureTagStats expectedStats,
-            int expectedCount, long expectedTime) {
-        assertNotNull(statses);
-        int actualCount = 0;
-        long actualTime = 0;
-        for (ImsRegistrationFeatureTagStats stats : statses) {
-            if (stats != null && expectedStats != null) {
-                if (stats.carrierId == expectedStats.carrierId
-                        && stats.slotId == expectedStats.slotId
-                        && stats.featureTagName == expectedStats.featureTagName
-                        && stats.registrationTech == expectedStats.registrationTech) {
-                    actualCount++;
-                    actualTime += stats.registeredMillis;
-                }
-            }
-        }
-        assertEquals(expectedCount, actualCount);
-        assertEquals(expectedTime, actualTime);
-    }
-
-    private static void assertHasStatsAndCount(
-            RcsClientProvisioningStats[] statses,
-            @Nullable RcsClientProvisioningStats expectedStats, int expectedCount) {
-        assertNotNull(statses);
-        int actualCount = -1;
-        for (RcsClientProvisioningStats stats : statses) {
-            if (stats.carrierId == expectedStats.carrierId
-                    && stats.slotId == expectedStats.slotId
-                    && stats.event == expectedStats.event) {
-                actualCount = stats.count;
-            }
-        }
-        assertEquals(expectedCount, actualCount);
-    }
-
-    private static void assertHasStats(
-            ImsDedicatedBearerListenerEvent[] statses,
-            @Nullable ImsDedicatedBearerListenerEvent expectedStats, int expectedCount) {
-        assertNotNull(statses);
-        int actualCount = 0;
-        for (ImsDedicatedBearerListenerEvent stats : statses) {
-            if (stats != null && expectedStats != null) {
-                if (MessageNano.messageNanoEquals(stats, expectedStats)) {
-                    actualCount++;
-                }
-            }
-        }
-        assertEquals(expectedCount, actualCount);
-    }
-
-    private static void assertHasStatsAndCount(
-            ImsDedicatedBearerEvent[] statses,
-            @Nullable ImsDedicatedBearerEvent expectedStats, int expectedCount) {
-        assertNotNull(statses);
-        int actualCount = -1;
-        for (ImsDedicatedBearerEvent stats : statses) {
-            if (stats.carrierId == expectedStats.carrierId
-                    && stats.slotId == expectedStats.slotId
-                    && stats.ratAtEnd == expectedStats.ratAtEnd
-                    && stats.qci == expectedStats.qci
-                    && stats.bearerState == expectedStats.bearerState
-                    && stats.localConnectionInfoReceived
-                            == expectedStats.localConnectionInfoReceived
-                    && stats.remoteConnectionInfoReceived
-                            == expectedStats.remoteConnectionInfoReceived
-                    && stats.hasListeners == expectedStats.hasListeners) {
-                actualCount = stats.count;
-            }
-        }
-        assertEquals(expectedCount, actualCount);
-    }
-
-    private static void assertHasStatsAndCountDuration(
-            RcsAcsProvisioningStats[] statses,
-            @Nullable RcsAcsProvisioningStats expectedStats, int count, long duration) {
-        assertNotNull(statses);
-        int actualCount = -1;
-        long actualDuration = -1;
-        for (RcsAcsProvisioningStats stats : statses) {
-            if (stats.carrierId == expectedStats.carrierId
-                    && stats.slotId == expectedStats.slotId
-                    && stats.responseCode == expectedStats.responseCode
-                    && stats.responseType == expectedStats.responseType
-                    && stats.isSingleRegistrationEnabled
-                            == expectedStats.isSingleRegistrationEnabled) {
-                actualCount = stats.count;
-                actualDuration = stats.stateTimerMillis;
-            }
-        }
-        assertEquals(count, actualCount);
-        assertEquals(duration, actualDuration);
-    }
-
-    private static void assertHasStats(SipDelegateStats[] results,
-            Object expectedStats, int expectedCount) {
-        assertNotNull(results);
-        assertNotNull(expectedStats);
-
-        int realCount = 0;
-        if (expectedStats instanceof SipDelegateStats[]) {
-            SipDelegateStats[] expectedResults = (SipDelegateStats[]) expectedStats;
-            for (SipDelegateStats stat: results) {
-                for (SipDelegateStats estat : expectedResults) {
-                    if (stat != null && estat != null) {
-                        if (MessageNano.messageNanoEquals(stat, estat)) {
-                            realCount++;
-                            break;
-                        }
-                    }
-                }
-            }
-        } else {
-            SipDelegateStats expectedResult = (SipDelegateStats) expectedStats;
-            for (SipDelegateStats stat : results) {
-                if (stat != null && expectedStats != null) {
-                    if (MessageNano.messageNanoEquals(stat, expectedResult)) {
-                        realCount++;
-                    }
-                }
-            }
-        }
-        assertEquals(expectedCount, realCount);
-    }
-
-    private static void assertHasStats(SipTransportFeatureTagStats[] results,
-            Object expectedStats, int expectedCount) {
-        assertNotNull(results);
-        assertNotNull(expectedStats);
-
-        int realCount = 0;
-        if (expectedStats instanceof SipTransportFeatureTagStats[]) {
-            SipTransportFeatureTagStats[] expectedResults =
-                    (SipTransportFeatureTagStats[]) expectedStats;
-            for (SipTransportFeatureTagStats stat: results) {
-                for (SipTransportFeatureTagStats estat : expectedResults) {
-                    if (stat != null && estat != null) {
-                        if (MessageNano.messageNanoEquals(stat, estat)) {
-                            realCount++;
-                            break;
-                        }
-                    }
-                }
-            }
-        } else {
-            SipTransportFeatureTagStats expectedResult =
-                    (SipTransportFeatureTagStats) expectedStats;
-            for (SipTransportFeatureTagStats stat : results) {
-                if (stat != null && expectedStats != null) {
-                    if (MessageNano.messageNanoEquals(stat, expectedResult)) {
-                        realCount++;
-                    }
-                }
-            }
-        }
-        assertEquals(expectedCount, realCount);
-    }
-
-    private static void assertHasStatsAndCount(
-            GbaEvent[] statses,
-            @Nullable GbaEvent expectedStats, int expectedCount) {
-        assertNotNull(statses);
-        int actualCount = -1;
-        for (GbaEvent stats : statses) {
-            if (stats.carrierId == expectedStats.carrierId
-                    && stats.slotId == expectedStats.slotId
-                    && stats.successful == expectedStats.successful
-                    && stats.failedReason == expectedStats.failedReason) {
-                actualCount = stats.count;
-            }
-        }
-        assertEquals(expectedCount, actualCount);
-    }
-
-    private static void assertHasStats(
-            SipMessageResponse[] statses,
-            @Nullable SipMessageResponse expectedStats, int expectedCount) {
-        assertNotNull(statses);
-        int actualCount = -1;
-        for (SipMessageResponse stats : statses) {
-            if (stats.carrierId == expectedStats.carrierId
-                    && stats.slotId == expectedStats.slotId
-                    && stats.sipMessageMethod == expectedStats.sipMessageMethod
-                    && stats.sipMessageResponse == expectedStats.sipMessageResponse
-                    && stats.sipMessageDirection == expectedStats.sipMessageDirection) {
-                actualCount = stats.count;
-            }
-        }
-        assertEquals(expectedCount, actualCount);
-    }
-
-    private static void assertHasStats(
-            SipTransportSession[] statses,
-            @Nullable SipTransportSession expectedStats, int expectedCount) {
-        assertNotNull(statses);
-        int actualCount = -1;
-        for (SipTransportSession stats : statses) {
-            if (stats.carrierId == expectedStats.carrierId
-                    && stats.slotId == expectedStats.slotId
-                    && stats.sessionMethod == expectedStats.sessionMethod
-                    && stats.sipMessageDirection == expectedStats.sipMessageDirection
-                    && stats.sipResponse == expectedStats.sipResponse) {
-                actualCount = stats.sessionCount;
-            }
-        }
-        assertEquals(expectedCount, actualCount);
-    }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/RcsStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/RcsStatsTest.java
deleted file mode 100644
index 3a941e3..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/RcsStatsTest.java
+++ /dev/null
@@ -1,1254 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.telephony.metrics;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import android.telephony.TelephonyProtoEnums;
-import android.telephony.ims.DelegateRegistrationState;
-import android.telephony.ims.FeatureTagState;
-import android.telephony.ims.SipDelegateManager;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.ArraySet;
-import android.util.Log;
-
-import com.android.ims.rcs.uce.util.FeatureTags;
-import com.android.internal.telephony.TelephonyStatsLog;
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.nano.PersistAtomsProto.GbaEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsDedicatedBearerListenerEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationFeatureTagStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.ImsRegistrationServiceDescStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.PresenceNotifyEvent;
-import com.android.internal.telephony.nano.PersistAtomsProto.RcsAcsProvisioningStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.RcsClientProvisioningStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipDelegateStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipMessageResponse;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportFeatureTagStats;
-import com.android.internal.telephony.nano.PersistAtomsProto.SipTransportSession;
-import com.android.internal.telephony.nano.PersistAtomsProto.UceEventStats;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-public class RcsStatsTest extends TelephonyTest {
-    private static final String TAG = RcsStatsTest.class.getSimpleName();
-
-    private static final long START_TIME_MILLIS = 2000L;
-    private static final int SLOT_ID = 0;
-    private static final int SLOT2_ID = 1;
-    private static final int INVALID_SLOT_ID = -1;
-    private static final int CARRIER_ID = 100;
-    private static final int CARRIER2_ID = 200;
-    private static final int INVALID_CARRIER_ID = -1;
-    private static final int INVALID_SUB_ID = Integer.MIN_VALUE;
-
-    private class TestResult {
-        public String tagName;
-        public int tagValue;
-        public long duration;
-        public int deniedReason;
-        public int deregiReason;
-        TestResult(String tagName, int tagValue, long duration,
-                int deniedReason, int deregiReason) {
-            this.tagName = tagName;
-            this.tagValue = tagValue;
-            this.duration = duration;
-            this.deniedReason = deniedReason;
-            this.deregiReason = deregiReason;
-        }
-    }
-
-    private final int mSubId = 10;
-    private final int mSubId2 = 20;
-
-    private TestableRcsStats mRcsStats;
-
-    private class TestableRcsStats extends RcsStats {
-        private long mTimeMillis = START_TIME_MILLIS;
-        private boolean mEnabledInvalidSubId = false;
-
-        TestableRcsStats() {
-            super();
-        }
-
-        @Override
-        protected int getSlotId(int subId) {
-            if (mEnabledInvalidSubId) {
-                return INVALID_SLOT_ID;
-            }
-
-            if (subId == mSubId) {
-                return SLOT_ID;
-            } else if (subId == mSubId2) {
-                return SLOT2_ID;
-            }
-            return SLOT2_ID;
-        }
-
-        @Override
-        protected int getCarrierId(int subId) {
-            if (mEnabledInvalidSubId) {
-                return INVALID_CARRIER_ID;
-            }
-
-            if (subId == mSubId) {
-                return CARRIER_ID;
-            } else if (subId == mSubId2) {
-                return CARRIER2_ID;
-            }
-            return INVALID_CARRIER_ID;
-        }
-
-        @Override
-        protected boolean isValidCarrierId(int carrierId) {
-            if (carrierId == INVALID_CARRIER_ID) {
-                return false;
-            }
-            return true;
-        }
-
-        @Override
-        protected long getWallTimeMillis() {
-            // NOTE: super class constructor will be executed before private field is set, which
-            // gives the wrong start time (mTimeMillis will have its default value of 0L)
-            Log.d(TAG, "getWallTimeMillis return value : " + mTimeMillis);
-            return mTimeMillis == 0L ? START_TIME_MILLIS : mTimeMillis;
-        }
-
-        @Override
-        protected void logd(String msg) {
-            Log.w(TAG, msg);
-        }
-
-        @Override
-        protected int getSubId(int slotId) {
-            if (mEnabledInvalidSubId) {
-                return INVALID_SUB_ID;
-            }
-
-            if (slotId == SLOT_ID) {
-                return mSubId;
-            } else if (slotId == SLOT2_ID) {
-                return mSubId2;
-            }
-            return INVALID_SUB_ID;
-        }
-
-        public void setEnableInvalidSubId() {
-            mEnabledInvalidSubId = true;
-        }
-        private void setTimeMillis(long timeMillis) {
-            mTimeMillis = timeMillis;
-        }
-
-        private void incTimeMillis(long timeMillis) {
-            mTimeMillis += timeMillis;
-            Log.d(TAG, "incTimeMillis   mTimeMillis : " + mTimeMillis);
-        }
-
-        public int getRcsAcsProvisioningCachedSize() {
-            return mRcsAcsProvisioningStatsList.size();
-        }
-
-        public int getImsRegistrationServiceDescCachedSize() {
-            return mImsRegistrationServiceDescStatsList.size();
-        }
-
-        public long getRcsAcsProvisioningCachedTime(int carreirId, int slotId) {
-            for (RcsAcsProvisioningStats stats : mRcsAcsProvisioningStatsList) {
-                if (stats.carrierId == carreirId && stats.slotId == slotId) {
-                    return stats.stateTimerMillis;
-                }
-            }
-            return 0L;
-        }
-
-        public int getRcsProvisioningCallbackMapSize() {
-            return mRcsProvisioningCallbackMap.size();
-        }
-
-        public ImsDedicatedBearerListenerEvent dedicatedBearerListenerEventMap_get(
-                final int listenerId) {
-            return mDedicatedBearerListenerEventMap.get(listenerId);
-        }
-
-        public boolean dedicatedBearerListenerEventMap_containsKey(final int listenerId) {
-            return mDedicatedBearerListenerEventMap.containsKey(listenerId);
-        }
-
-        public void dedicatedBearerListenerEventMap_remove(final int listenerId) {
-            mDedicatedBearerListenerEventMap.remove(listenerId);
-        }
-    }
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-
-        mRcsStats = new TestableRcsStats();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mRcsStats = null;
-        super.tearDown();
-    }
-
-    @Test
-    @SmallTest
-    public void onImsRegistrationFeatureTagStats_withAtoms() throws Exception {
-        int slotId = SLOT_ID;
-        int carrierId = CARRIER_ID;
-        List<String> featureTagList = Arrays.asList(
-                "+g.3gpp.iari-ref=\"urn%3Aurn-7%3A3gpp-application.ims.iari.rcse.im\"",
-                "+g.3gpp.icsi-ref=\"urn%3Aurn-7%3A3gpp-service.ims.icsi.oma.cpm.session\"",
-                "+g.3gpp.icsi-ref=\"hh%3Ashin%3A-b.a.b.o\"",
-                "+g.gsma.rcs.isbot"
-        );
-
-        int registrationTech  = 0;
-
-        mRcsStats.onImsRegistrationFeatureTagStats(
-                mSubId, featureTagList, registrationTech);
-
-        mRcsStats.onStoreCompleteImsRegistrationFeatureTagStats(mSubId);
-
-        ArgumentCaptor<ImsRegistrationFeatureTagStats> captor =
-                ArgumentCaptor.forClass(ImsRegistrationFeatureTagStats.class);
-        verify(mPersistAtomsStorage, times(featureTagList.size()))
-                .addImsRegistrationFeatureTagStats(captor.capture());
-        List<ImsRegistrationFeatureTagStats> captorValues = captor.getAllValues();
-
-        assertEquals(captorValues.size(), featureTagList.size());
-        for (int index = 0; index < captorValues.size(); index++) {
-            ImsRegistrationFeatureTagStats stats = captorValues.get(index);
-            assertEquals(CARRIER_ID, stats.carrierId);
-            assertEquals(SLOT_ID, stats.slotId);
-            assertEquals(mRcsStats.convertTagNameToValue(featureTagList.get(index)),
-                    stats.featureTagName);
-            assertEquals(registrationTech, stats.registrationTech);
-        }
-    }
-
-    @Test
-    @SmallTest
-    public void onRcsClientProvisioningStats_withAtoms() throws Exception {
-        /*
-         * RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT
-         * RCS_CLIENT_PROVISIONING_STATS__EVENT__TRIGGER_RCS_RECONFIGURATION
-         * RCS_CLIENT_PROVISIONING_STATS__EVENT__DMA_CHANGED
-         */
-        int event =
-                TelephonyStatsLog.RCS_CLIENT_PROVISIONING_STATS__EVENT__CLIENT_PARAMS_SENT;
-
-        mRcsStats.onRcsClientProvisioningStats(mSubId, event);
-
-        ArgumentCaptor<RcsClientProvisioningStats> captor =
-                ArgumentCaptor.forClass(RcsClientProvisioningStats.class);
-        verify(mPersistAtomsStorage).addRcsClientProvisioningStats(captor.capture());
-        RcsClientProvisioningStats stats = captor.getValue();
-        assertEquals(CARRIER_ID, stats.carrierId);
-        assertEquals(SLOT_ID, stats.slotId);
-        assertEquals(event, stats.event);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onRcsAcsProvisioningStats_withAtoms() throws Exception {
-        boolean isSingleRegistrationEnabled = true;
-        int[] responseCode = {200, 401};
-        /*
-         * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR
-         * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML
-         * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PRE_PROVISIONING_XML
-         */
-        int[] responseType = {
-                TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML,
-                TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR};
-        int[] slotIds = {SLOT_ID, SLOT_ID};
-        int[] carrierIds = {CARRIER_ID, CARRIER_ID};
-
-        // this will be cached
-        mRcsStats.onRcsAcsProvisioningStats(
-                mSubId, responseCode[0], responseType[0], isSingleRegistrationEnabled);
-
-        long timeGap = 6000L;
-        mRcsStats.incTimeMillis(timeGap);
-
-        // this will be cached, previous will be stored
-        mRcsStats.onRcsAcsProvisioningStats(
-                mSubId, responseCode[1], responseType[1], isSingleRegistrationEnabled);
-
-        ArgumentCaptor<RcsAcsProvisioningStats> captor =
-                ArgumentCaptor.forClass(RcsAcsProvisioningStats.class);
-        verify(mPersistAtomsStorage).addRcsAcsProvisioningStats(captor.capture());
-        RcsAcsProvisioningStats stats = captor.getValue();
-        assertEquals(carrierIds[0], stats.carrierId);
-        assertEquals(slotIds[0], stats.slotId);
-        assertEquals(responseCode[0], stats.responseCode);
-        assertEquals(responseType[0], stats.responseType);
-        assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled);
-        assertEquals(timeGap, stats.stateTimerMillis);
-
-        // the last atoms will be cached
-        assertEquals(1, mRcsStats.getRcsAcsProvisioningCachedSize());
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onRcsAcsProvisioningStats_withAtomsInvalidSubId() throws Exception {
-        boolean isSingleRegistrationEnabled = true;
-        int[] responseCode = {200, 401};
-        int[] responseType = {
-                TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML,
-                TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR};
-        int[] slotIds = {SLOT_ID, SLOT_ID};
-        int[] carrierIds = {CARRIER_ID, CARRIER_ID};
-
-        // this will be cached
-        mRcsStats.onRcsAcsProvisioningStats(
-                mSubId, responseCode[0], responseType[0], isSingleRegistrationEnabled);
-
-        long timeGap = 6000L;
-        mRcsStats.incTimeMillis(timeGap);
-
-        // slotId and carrierId are invalid based on subId
-        mRcsStats.setEnableInvalidSubId();
-
-        // this will not be cached, previous will be stored
-        mRcsStats.onRcsAcsProvisioningStats(
-                mSubId, responseCode[1], responseType[1], isSingleRegistrationEnabled);
-
-        ArgumentCaptor<RcsAcsProvisioningStats> captor =
-                ArgumentCaptor.forClass(RcsAcsProvisioningStats.class);
-        verify(mPersistAtomsStorage).addRcsAcsProvisioningStats(captor.capture());
-        RcsAcsProvisioningStats stats = captor.getValue();
-        assertEquals(carrierIds[0], stats.carrierId);
-        assertEquals(slotIds[0], stats.slotId);
-        assertEquals(responseCode[0], stats.responseCode);
-        assertEquals(responseType[0], stats.responseType);
-        assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled);
-        assertEquals(timeGap, stats.stateTimerMillis);
-        // the last atoms will not be cached
-        assertEquals(0, mRcsStats.getRcsAcsProvisioningCachedSize());
-
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onRcsAcsProvisioningStats_byCallBack() throws Exception {
-        long timeGap = 6000L;
-        boolean isSingleRegistrationEnabled = true;
-        int responseCode = 200;
-        int responseType =
-                TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PRE_PROVISIONING_XML;
-        byte[] config = new byte[0];
-
-        RcsStats.RcsProvisioningCallback rcsProvisioningCallback =
-                mRcsStats.getRcsProvisioningCallback(mSubId, isSingleRegistrationEnabled);
-        // has one callback obj
-        assertEquals(mRcsStats.getRcsProvisioningCallbackMapSize(), 1);
-
-        rcsProvisioningCallback.onPreProvisioningReceived(config);
-        mRcsStats.incTimeMillis(timeGap);
-        rcsProvisioningCallback.onRemoved();
-        // callback will be removed, Map is empty.
-        assertEquals(mRcsStats.getRcsProvisioningCallbackMapSize(), 0);
-
-        ArgumentCaptor<RcsAcsProvisioningStats> captor =
-                ArgumentCaptor.forClass(RcsAcsProvisioningStats.class);
-        verify(mPersistAtomsStorage).addRcsAcsProvisioningStats(captor.capture());
-        RcsAcsProvisioningStats stats = captor.getValue();
-        assertEquals(CARRIER_ID, stats.carrierId);
-        assertEquals(SLOT_ID, stats.slotId);
-        assertEquals(responseCode, stats.responseCode);
-        assertEquals(responseType, stats.responseType);
-        assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled);
-        assertEquals(timeGap, stats.stateTimerMillis);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onRcsAcsProvisioningStats_byErrorCallBack() throws Exception {
-        long timeGap = 6000L;
-        boolean isSingleRegistrationEnabled = true;
-        int responseCode = 401;
-        int responseType =
-                TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR;
-
-        RcsStats.RcsProvisioningCallback rcsProvisioningCallback =
-                mRcsStats.getRcsProvisioningCallback(mSubId, false);
-        rcsProvisioningCallback =
-                mRcsStats.getRcsProvisioningCallback(mSubId2, isSingleRegistrationEnabled);
-        // has two callback obj, subId, subId2
-        assertEquals(mRcsStats.getRcsProvisioningCallbackMapSize(), 2);
-
-        rcsProvisioningCallback.onAutoConfigurationErrorReceived(responseCode, "responseCode");
-        mRcsStats.incTimeMillis(timeGap);
-        mRcsStats.onStoreCompleteRcsAcsProvisioningStats(mSubId2);
-        rcsProvisioningCallback.onRemoved();
-        // subId2's callback will be removed, Map has only one callback for subId.
-        assertEquals(mRcsStats.getRcsProvisioningCallbackMapSize(), 1);
-
-        // addRcsAcsProvisioningStats is called once.
-        ArgumentCaptor<RcsAcsProvisioningStats> captor =
-                ArgumentCaptor.forClass(RcsAcsProvisioningStats.class);
-        verify(mPersistAtomsStorage).addRcsAcsProvisioningStats(captor.capture());
-        RcsAcsProvisioningStats stats = captor.getValue();
-        assertEquals(CARRIER2_ID, stats.carrierId);
-        assertEquals(SLOT2_ID, stats.slotId);
-        assertEquals(responseCode, stats.responseCode);
-        assertEquals(responseType, stats.responseType);
-        assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled);
-        assertEquals(timeGap, stats.stateTimerMillis);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onStoreCompleteRcsAcsProvisioningStats_withSubId() throws Exception {
-        boolean isSingleRegistrationEnabled = true;
-        int[] responseCode = {401, 200};
-        /*
-         * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR
-         * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML
-         * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PRE_PROVISIONING_XML
-         */
-        int[] responseType = {TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR,
-                TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML};
-        int[] slotIds = {SLOT_ID, SLOT2_ID};
-        int[] carrierIds = {CARRIER_ID, CARRIER2_ID};
-
-        // this will be cached
-        mRcsStats.onRcsAcsProvisioningStats(
-                mSubId, responseCode[0], responseType[0], isSingleRegistrationEnabled);
-        // this will be cached
-        mRcsStats.onRcsAcsProvisioningStats(
-                mSubId2, responseCode[1], responseType[1], isSingleRegistrationEnabled);
-
-        long timeGap = 6000L;
-        mRcsStats.incTimeMillis(timeGap);
-
-        // cached atoms will be stored and removed
-        mRcsStats.onStoreCompleteRcsAcsProvisioningStats(mSubId);
-        mRcsStats.onStoreCompleteRcsAcsProvisioningStats(mSubId2);
-
-        ArgumentCaptor<RcsAcsProvisioningStats> captor =
-                ArgumentCaptor.forClass(RcsAcsProvisioningStats.class);
-        verify(mPersistAtomsStorage, times(slotIds.length))
-                .addRcsAcsProvisioningStats(captor.capture());
-        List<RcsAcsProvisioningStats> statsList = captor.getAllValues();
-        assertEquals(slotIds.length, statsList.size());
-        for (int i = 0; i < statsList.size(); i++) {
-            RcsAcsProvisioningStats stats = statsList.get(i);
-            assertEquals(carrierIds[i], stats.carrierId);
-            assertEquals(slotIds[i], stats.slotId);
-            assertEquals(responseCode[i], stats.responseCode);
-            assertEquals(responseType[i], stats.responseType);
-            assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled);
-            assertEquals(timeGap, stats.stateTimerMillis);
-        }
-        // cached data should be empty
-        assertEquals(0, mRcsStats.getRcsAcsProvisioningCachedSize());
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onFlushIncompleteRcsAcsProvisioningStats_withoutSubId() throws Exception {
-        boolean isSingleRegistrationEnabled = true;
-        int[] responseCode = {401, 200};
-        /*
-         * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR
-         * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML
-         * RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PRE_PROVISIONING_XML
-         */
-        int[] responseType = {TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__ERROR,
-                TelephonyStatsLog.RCS_ACS_PROVISIONING_STATS__RESPONSE_TYPE__PROVISIONING_XML};
-        int[] slotIds = {SLOT_ID, SLOT2_ID};
-        int[] carrierIds = {CARRIER_ID, CARRIER2_ID};
-
-        // this will be cached
-        mRcsStats.onRcsAcsProvisioningStats(
-                mSubId, responseCode[0], responseType[0], isSingleRegistrationEnabled);
-        // this will be cached
-        mRcsStats.onRcsAcsProvisioningStats(
-                mSubId2, responseCode[1], responseType[1], isSingleRegistrationEnabled);
-
-        long timeGap = 6000L;
-        mRcsStats.incTimeMillis(timeGap);
-
-        // cached atoms will be stored, but atoms are keeped
-        mRcsStats.onFlushIncompleteRcsAcsProvisioningStats();
-
-        ArgumentCaptor<RcsAcsProvisioningStats> captor =
-                ArgumentCaptor.forClass(RcsAcsProvisioningStats.class);
-        verify(mPersistAtomsStorage, times(slotIds.length))
-                .addRcsAcsProvisioningStats(captor.capture());
-        List<RcsAcsProvisioningStats> statsList = captor.getAllValues();
-        assertEquals(slotIds.length, statsList.size());
-        for (int i = 0; i < statsList.size(); i++) {
-            RcsAcsProvisioningStats stats = statsList.get(i);
-            assertEquals(carrierIds[i], stats.carrierId);
-            assertEquals(slotIds[i], stats.slotId);
-            assertEquals(responseCode[i], stats.responseCode);
-            assertEquals(responseType[i], stats.responseType);
-            assertEquals(isSingleRegistrationEnabled, stats.isSingleRegistrationEnabled);
-            assertEquals(timeGap, stats.stateTimerMillis);
-
-            // check cached atom's time should be updated
-            assertEquals(mRcsStats.getWallTimeMillis(),
-                    mRcsStats.getRcsAcsProvisioningCachedTime(carrierIds[i], slotIds[i]));
-        }
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onSipDelegateStats_addStats() throws Exception {
-        final int destroyReason = SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD;
-        final long timeGap = 6000L;
-        List<Set<String>> supportedTagsList = getSupportedTagsList();
-        Set<String> registeredTags = supportedTagsList.get(0);
-        // create and destroy a sipDelegate..
-        mRcsStats.createSipDelegateStats(mSubId, registeredTags);
-        mRcsStats.incTimeMillis(timeGap);
-        mRcsStats.onSipDelegateStats(mSubId, registeredTags,
-                SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD);
-
-        ArgumentCaptor<SipDelegateStats> captor =
-                ArgumentCaptor.forClass(SipDelegateStats.class);
-        verify(mPersistAtomsStorage).addSipDelegateStats(captor.capture());
-        SipDelegateStats stats = captor.getValue();
-        assertTrue(stats.dimension != 0);
-        assertEquals(CARRIER_ID, stats.carrierId);
-        assertEquals(SLOT_ID, stats.slotId);
-        assertEquals(timeGap, stats.uptimeMillis);
-        assertEquals(destroyReason, stats.destroyReason);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    private List<Set<String>> getSupportedTagsList() {
-        List<Set<String>> registeredTagsList = new ArrayList<>();
-        Set<String> supportedTags1 = new ArraySet<>();
-        supportedTags1.add(FeatureTags.FEATURE_TAG_STANDALONE_MSG);
-        supportedTags1.add(FeatureTags.FEATURE_TAG_CHAT_SESSION);
-        registeredTagsList.add(supportedTags1);
-
-        Set<String> supportedTags2 = new ArraySet<>();
-        supportedTags2.add(FeatureTags.FEATURE_TAG_FILE_TRANSFER);
-        supportedTags2.add(FeatureTags.FEATURE_TAG_CHAT_IM);
-        supportedTags2.add(FeatureTags.FEATURE_TAG_CALL_COMPOSER_ENRICHED_CALLING);
-        registeredTagsList.add(supportedTags2);
-
-        Set<String> supportedTags3 = new ArraySet<>();
-        supportedTags3.add(FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_SESSION);
-        supportedTags3.add(FeatureTags.FEATURE_TAG_CHATBOT_COMMUNICATION_USING_STANDALONE_MSG);
-        supportedTags3.add(FeatureTags.FEATURE_TAG_CHATBOT_VERSION_SUPPORTED);
-        registeredTagsList.add(supportedTags3);
-
-        return registeredTagsList;
-    }
-
-    @Test
-    @SmallTest
-    public void onSipDelegateStats_addMultipleEntries() throws Exception {
-        final long timeGap = 6000L;
-        List<Integer> destroyReasonList = new ArrayList<>();
-        destroyReasonList.add(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_UNKNOWN);
-        destroyReasonList.add(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_SERVICE_DEAD);
-        destroyReasonList.add(SipDelegateManager.SIP_DELEGATE_DESTROY_REASON_REQUESTED_BY_APP);
-        final int testSize = destroyReasonList.size();
-        List<Set<String>> supportedTagsList = getSupportedTagsList();
-
-        // create and destroy a sipDelegate multiple times
-        for (int i = 0; i < testSize; i++) {
-            mRcsStats.createSipDelegateStats(mSubId, supportedTagsList.get(i));
-        }
-
-        for (int i = 0; i < testSize; i++) {
-            mRcsStats.incTimeMillis(timeGap);
-            mRcsStats.onSipDelegateStats(mSubId, supportedTagsList.get(i),
-                    destroyReasonList.get(i));
-        }
-
-        List<ExpectedSipDelegateResult> expectedSipDelegateResults =
-                getExpectedResult(destroyReasonList);
-        final int expectedResultSize = expectedSipDelegateResults.size();
-        ArgumentCaptor<SipDelegateStats> captor =
-                ArgumentCaptor.forClass(SipDelegateStats.class);
-        verify(mPersistAtomsStorage, times(expectedResultSize))
-                .addSipDelegateStats(captor.capture());
-
-        List<SipDelegateStats> captorValues = captor.getAllValues();
-        assertEquals(captorValues.size(), expectedResultSize);
-        for (int i = 0; i < expectedResultSize; i++) {
-            SipDelegateStats stats = captorValues.get(i);
-            ExpectedSipDelegateResult expectedResult = expectedSipDelegateResults.get(i);
-            assertTrue(stats.dimension != 0);
-            assertEquals(CARRIER_ID, stats.carrierId);
-            assertEquals(SLOT_ID, stats.slotId);
-            assertEquals(timeGap * (i + 1), stats.uptimeMillis);
-            assertEquals(expectedResult.destroyReason, stats.destroyReason);
-        }
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    private class ExpectedSipDelegateResult {
-        public int id;
-        public int destroyReason;
-        ExpectedSipDelegateResult(int id, int destroyReason) {
-            this.id = id;
-            this.destroyReason = destroyReason;
-        }
-    }
-
-    private List<ExpectedSipDelegateResult> getExpectedResult(List<Integer> destroyReasonList) {
-        List<ExpectedSipDelegateResult> results = new ArrayList<>();
-        int size = destroyReasonList.size();
-
-        for (int i = 0; i < size; i++) {
-            results.add(new ExpectedSipDelegateResult(i, destroyReasonList.get(i)));
-        }
-
-        return results;
-    }
-
-    @Test
-    @SmallTest
-    public void onSipTransportFeatureTagStats_addMultipleEntries() throws Exception {
-        final long timeGap = 6000L;
-        Set<FeatureTagState> deniedTags = new ArraySet<>();
-        Set<FeatureTagState> deRegiTags = new ArraySet<>();
-        Set<String> regiTags = new ArraySet<>();
-
-        // create new featureTags
-        regiTags.add(FeatureTags.FEATURE_TAG_STANDALONE_MSG);
-        deniedTags.add(new FeatureTagState(FeatureTags.FEATURE_TAG_FILE_TRANSFER,
-                SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE));
-        mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags);
-
-        mRcsStats.incTimeMillis(timeGap);
-
-        // change status of featureTags
-        regiTags.clear();
-        deRegiTags.add(new FeatureTagState(FeatureTags.FEATURE_TAG_STANDALONE_MSG,
-                DelegateRegistrationState.DEREGISTERED_REASON_NOT_REGISTERED));
-        mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags);
-
-        mRcsStats.incTimeMillis(timeGap);
-
-        List<TestResult> expectedResults = getTestResult(timeGap, false);
-
-        int expectedResultSize = expectedResults.size();
-        ArgumentCaptor<SipTransportFeatureTagStats> captor =
-                ArgumentCaptor.forClass(SipTransportFeatureTagStats.class);
-        verify(mPersistAtomsStorage, times(expectedResultSize))
-                .addSipTransportFeatureTagStats(captor.capture());
-
-        List<SipTransportFeatureTagStats> captorValues = captor.getAllValues();
-
-        assertEquals(captorValues.size(), expectedResultSize);
-        for (int i = 0; i < captorValues.size(); i++) {
-            SipTransportFeatureTagStats stats = captorValues.get(i);
-            TestResult expectedResult = expectedResults.get(i);
-            assertEquals(CARRIER_ID, stats.carrierId);
-            assertEquals(SLOT_ID, stats.slotId);
-            assertEquals(expectedResult.tagValue, stats.featureTagName);
-            assertEquals(expectedResult.duration, stats.associatedMillis);
-            assertEquals(expectedResult.deniedReason, stats.sipTransportDeniedReason);
-            assertEquals(expectedResult.deregiReason, stats.sipTransportDeregisteredReason);
-        }
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onSipTransportFeatureTagStats_addInvalidEntries() throws Exception {
-        final long timeGap = 6000L;
-        Set<FeatureTagState> deniedTags = new ArraySet<>();
-        Set<FeatureTagState> deRegiTags = new ArraySet<>();
-        Set<String> regiTags = new ArraySet<>();
-
-        final int invalidSubId = INVALID_SUB_ID;
-
-        // create new featureTags with an invalidId
-        regiTags.add(FeatureTags.FEATURE_TAG_STANDALONE_MSG);
-        deniedTags.add(new FeatureTagState(FeatureTags.FEATURE_TAG_FILE_TRANSFER,
-                SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE));
-        mRcsStats.onSipTransportFeatureTagStats(invalidSubId, deniedTags, deRegiTags, regiTags);
-        mRcsStats.incTimeMillis(timeGap);
-
-        // change status of featureTags with an invalidId
-        regiTags.clear();
-        deRegiTags.add(new FeatureTagState(FeatureTags.FEATURE_TAG_STANDALONE_MSG,
-                DelegateRegistrationState.DEREGISTERED_REASON_NOT_REGISTERED));
-        mRcsStats.onSipTransportFeatureTagStats(invalidSubId, deniedTags, deRegiTags, regiTags);
-        mRcsStats.incTimeMillis(timeGap);
-
-        verify(mPersistAtomsStorage, never()).addSipTransportFeatureTagStats(any());
-    }
-
-
-    @Test
-    @SmallTest
-    public void onSipTransportFeatureTagStats_addCustomTag() throws Exception {
-        final long timeGap = 6000L;
-        Set<FeatureTagState> deniedTags = new ArraySet<>();
-        Set<FeatureTagState> deRegiTags = new ArraySet<>();
-        Set<String> regiTags = new ArraySet<>();
-
-        // create new featureTags
-        String customTag = "custom@tag";
-        regiTags.add(customTag);
-        mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags);
-
-        mRcsStats.incTimeMillis(timeGap);
-
-        // change status of featureTags
-        regiTags.clear();
-        deRegiTags.add(new FeatureTagState(customTag,
-                DelegateRegistrationState.DEREGISTERED_REASON_NOT_REGISTERED));
-        mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags);
-
-        mRcsStats.incTimeMillis(timeGap);
-
-        TestResult expectedResult = new TestResult(customTag,
-                TelephonyProtoEnums.IMS_FEATURE_TAG_CUSTOM, timeGap, RcsStats.NONE, RcsStats.NONE);
-
-        ArgumentCaptor<SipTransportFeatureTagStats> captor =
-                ArgumentCaptor.forClass(SipTransportFeatureTagStats.class);
-
-        verify(mPersistAtomsStorage).addSipTransportFeatureTagStats(captor.capture());
-        SipTransportFeatureTagStats stats = captor.getValue();
-
-        assertEquals(CARRIER_ID, stats.carrierId);
-        assertEquals(SLOT_ID, stats.slotId);
-        assertEquals(expectedResult.tagValue, stats.featureTagName);
-        assertEquals(expectedResult.duration, stats.associatedMillis);
-        assertEquals(expectedResult.deniedReason, stats.sipTransportDeniedReason);
-        assertEquals(expectedResult.deregiReason, stats.sipTransportDeregisteredReason);
-
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void concludeSipTransportFeatureTagsStat_addMultipleEntries() throws Exception {
-        final long timeGap = 6000L;
-        Set<FeatureTagState> deniedTags = new ArraySet<>();
-        Set<FeatureTagState> deRegiTags = new ArraySet<>();
-        Set<String> regiTags = new ArraySet<>();
-        // create new featureTags
-        regiTags.add(FeatureTags.FEATURE_TAG_STANDALONE_MSG);
-        deniedTags.add(new FeatureTagState(FeatureTags.FEATURE_TAG_FILE_TRANSFER,
-                SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE));
-        mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags);
-
-        mRcsStats.incTimeMillis(timeGap);
-
-        // change status of featureTags
-        regiTags.clear();
-        deRegiTags.add(new FeatureTagState(FeatureTags.FEATURE_TAG_STANDALONE_MSG,
-                DelegateRegistrationState.DEREGISTERED_REASON_NOT_REGISTERED));
-        mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags);
-
-
-        mRcsStats.incTimeMillis(timeGap);
-
-        // change status of featureTags and metrics are pulled.
-        deRegiTags.clear();
-        regiTags.add(FeatureTags.FEATURE_TAG_STANDALONE_MSG);
-        mRcsStats.onSipTransportFeatureTagStats(mSubId, deniedTags, deRegiTags, regiTags);
-
-        mRcsStats.incTimeMillis(timeGap);
-        mRcsStats.concludeSipTransportFeatureTagsStat();
-
-        List<TestResult> expectedResults = getTestResult(timeGap, true);
-
-        int expectedResultSize = expectedResults.size();
-        ArgumentCaptor<SipTransportFeatureTagStats> captor =
-                ArgumentCaptor.forClass(SipTransportFeatureTagStats.class);
-        verify(mPersistAtomsStorage, times(expectedResultSize))
-                .addSipTransportFeatureTagStats(captor.capture());
-
-        List<SipTransportFeatureTagStats> captorValues = captor.getAllValues();
-
-        assertEquals(captorValues.size(), expectedResultSize);
-        for (int i = 0; i < captorValues.size(); i++) {
-            SipTransportFeatureTagStats stats = captorValues.get(i);
-            TestResult expectedResult = expectedResults.get(i);
-            assertEquals(CARRIER_ID, stats.carrierId);
-            assertEquals(SLOT_ID, stats.slotId);
-            assertEquals(expectedResult.tagValue, stats.featureTagName);
-            assertEquals(expectedResult.duration, stats.associatedMillis);
-            assertEquals(expectedResult.deniedReason, stats.sipTransportDeniedReason);
-            assertEquals(expectedResult.deregiReason, stats.sipTransportDeregisteredReason);
-        }
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-
-    }
-
-    private List<TestResult> getTestResult(long timeGap, boolean concludeTest) {
-        List<TestResult> results = new ArrayList<>();
-        results.add(new TestResult(FeatureTags.FEATURE_TAG_FILE_TRANSFER,
-                TelephonyProtoEnums.IMS_FEATURE_TAG_FILE_TRANSFER,
-                timeGap,
-                SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE, RcsStats.NONE));
-        results.add(new TestResult(FeatureTags.FEATURE_TAG_STANDALONE_MSG,
-                TelephonyProtoEnums.IMS_FEATURE_TAG_STANDALONE_MSG,
-                timeGap, RcsStats.NONE, RcsStats.NONE));
-        if (concludeTest) {
-            results.add(new TestResult(FeatureTags.FEATURE_TAG_STANDALONE_MSG,
-                    TelephonyProtoEnums.IMS_FEATURE_TAG_STANDALONE_MSG,
-                    timeGap, RcsStats.NONE,
-                    DelegateRegistrationState.DEREGISTERED_REASON_NOT_REGISTERED));
-            results.add(new TestResult(FeatureTags.FEATURE_TAG_FILE_TRANSFER,
-                    TelephonyProtoEnums.IMS_FEATURE_TAG_FILE_TRANSFER,
-                    timeGap,
-                    SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE, RcsStats.NONE));
-            results.add(new TestResult(FeatureTags.FEATURE_TAG_FILE_TRANSFER,
-                    TelephonyProtoEnums.IMS_FEATURE_TAG_FILE_TRANSFER,
-                    timeGap,
-                    SipDelegateManager.DENIED_REASON_IN_USE_BY_ANOTHER_DELEGATE, RcsStats.NONE));
-            results.add(new TestResult(FeatureTags.FEATURE_TAG_STANDALONE_MSG,
-                    TelephonyProtoEnums.IMS_FEATURE_TAG_STANDALONE_MSG,
-                    timeGap, RcsStats.NONE, RcsStats.NONE));
-
-        }
-        return results;
-    }
-
-    @Test
-    @SmallTest
-    public void onSipMessageResponse_withAtoms() throws Exception {
-        String testSipMessageMethod = "MESSAGE";
-        int testSipRequestMessageDirection = 1; //INCOMING: 0, OUTGOING: 1
-        int testSipMessageResponse = 200;
-        int testMessageError = 0;
-        String testCallId = "testId";
-        // Request message
-        mRcsStats.onSipMessageRequest(testCallId, testSipMessageMethod,
-                testSipRequestMessageDirection);
-        // Response message
-        mRcsStats.onSipMessageResponse(mSubId, testCallId, testSipMessageResponse,
-                testMessageError);
-        ArgumentCaptor<SipMessageResponse> captor =
-                ArgumentCaptor.forClass(SipMessageResponse.class);
-        verify(mPersistAtomsStorage).addSipMessageResponse(captor.capture());
-        SipMessageResponse stats = captor.getValue();
-        assertEquals(CARRIER_ID, stats.carrierId);
-        assertEquals(SLOT_ID, stats.slotId);
-        assertEquals(TelephonyProtoEnums.SIP_REQUEST_MESSAGE, stats.sipMessageMethod);
-        assertEquals(testSipRequestMessageDirection, stats.sipMessageDirection);
-        assertEquals(testSipMessageResponse, stats.sipMessageResponse);
-        assertEquals(testMessageError, stats.messageError);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onSipTransportSession_withAtoms() throws Exception {
-        String testInviteSipMethod = "INVITE";
-        String testCallId = "testId";
-        int testSipResponse = 0;
-        int testSipRequestMessageDirection = 1; //INCOMING: 0, OUTGOING: 1
-        // Request Message
-        mRcsStats.earlySipTransportSession(
-                testInviteSipMethod, testCallId, testSipRequestMessageDirection);
-        // gracefully close
-        mRcsStats.onSipTransportSessionClosed(mSubId, testCallId, testSipResponse, true);
-        ArgumentCaptor<SipTransportSession> captor =
-                ArgumentCaptor.forClass(SipTransportSession.class);
-        verify(mPersistAtomsStorage).addCompleteSipTransportSession(captor.capture());
-        SipTransportSession stats = captor.getValue();
-        assertEquals(CARRIER_ID, stats.carrierId);
-        assertEquals(SLOT_ID, stats.slotId);
-        assertEquals(TelephonyProtoEnums.SIP_REQUEST_INVITE, stats.sessionMethod);
-        assertEquals(testSipRequestMessageDirection, stats.sipMessageDirection);
-        assertEquals(testSipResponse, stats.sipResponse);
-        assertEquals(true/*isEndedGracefully*/, stats.isEndedGracefully);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onImsDedicatedBearerListenerEvent_Added() throws Exception {
-        final int listenerId = 1;
-        int ratAtEnd = TelephonyProtoEnums.NETWORK_TYPE_LTE;
-        final int qci = 5;
-
-        mRcsStats.dedicatedBearerListenerEventMap_remove(listenerId);
-        mRcsStats.onImsDedicatedBearerListenerAdded(listenerId, SLOT_ID, ratAtEnd, qci);
-        assertTrue(mRcsStats.dedicatedBearerListenerEventMap_containsKey(listenerId));
-        ImsDedicatedBearerListenerEvent testProto =
-                mRcsStats.dedicatedBearerListenerEventMap_get(listenerId);
-        assertEquals(SLOT_ID, testProto.slotId);
-        assertEquals(ratAtEnd, testProto.ratAtEnd);
-        assertEquals(qci, testProto.qci);
-        assertFalse(testProto.dedicatedBearerEstablished);
-        verify(mPersistAtomsStorage, never()).addImsDedicatedBearerListenerEvent(any());
-
-        // same listenerId, different contents. should be ignored
-        ratAtEnd = TelephonyProtoEnums.NETWORK_TYPE_NR;
-        mRcsStats.onImsDedicatedBearerListenerAdded(listenerId, SLOT_ID + 1, ratAtEnd + 1, qci + 1);
-        testProto = mRcsStats.dedicatedBearerListenerEventMap_get(listenerId);
-        assertEquals(SLOT_ID, testProto.slotId);
-        assertNotEquals(ratAtEnd, testProto.ratAtEnd);
-        assertEquals(qci, testProto.qci);
-        verify(mPersistAtomsStorage, never()).addImsDedicatedBearerListenerEvent(any());
-
-        mRcsStats.dedicatedBearerListenerEventMap_remove(listenerId);
-    }
-
-    @Test
-    @SmallTest
-    public void onImsDedicatedBearerListenerEvent_bearerEstablished() throws Exception {
-        final int listenerId = 2;
-        final int rat = TelephonyProtoEnums.NETWORK_TYPE_LTE;
-        final int qci = 6;
-
-        mRcsStats.dedicatedBearerListenerEventMap_remove(listenerId);
-        mRcsStats.onImsDedicatedBearerListenerUpdateSession(listenerId, SLOT_ID, rat, qci, true);
-        verify(mPersistAtomsStorage, never()).addImsDedicatedBearerListenerEvent(any());
-
-        mRcsStats.dedicatedBearerListenerEventMap_remove(listenerId);
-        mRcsStats.onImsDedicatedBearerListenerAdded(listenerId, SLOT_ID, rat, qci);
-        assertTrue(mRcsStats.dedicatedBearerListenerEventMap_containsKey(listenerId));
-        mRcsStats.onImsDedicatedBearerListenerUpdateSession(listenerId, SLOT_ID, rat, qci, true);
-        ImsDedicatedBearerListenerEvent testProto =
-                mRcsStats.dedicatedBearerListenerEventMap_get(listenerId);
-        assertEquals(qci, testProto.qci);
-        assertTrue(testProto.dedicatedBearerEstablished);
-
-        verify(mPersistAtomsStorage, never()).addImsDedicatedBearerListenerEvent(any());
-    }
-
-    @Test
-    @SmallTest
-    public void onImsDedicatedBearerListenerEvent_Removed() throws Exception {
-        final int listenerId = 3;
-        final int rat = TelephonyProtoEnums.NETWORK_TYPE_LTE;
-        final int qci = 7;
-
-        mRcsStats.dedicatedBearerListenerEventMap_remove(listenerId);
-        mRcsStats.onImsDedicatedBearerListenerRemoved(listenerId);
-        verify(mPersistAtomsStorage, never()).addImsDedicatedBearerListenerEvent(any());
-
-        mRcsStats.onImsDedicatedBearerListenerAdded(listenerId, SLOT_ID, rat, qci);
-        mRcsStats.onImsDedicatedBearerListenerUpdateSession(listenerId, SLOT_ID, rat, qci, true);
-        mRcsStats.onImsDedicatedBearerListenerRemoved(listenerId);
-        verify(mPersistAtomsStorage, times(1)).addImsDedicatedBearerListenerEvent(any());
-
-        // and values should be same
-        ArgumentCaptor<ImsDedicatedBearerListenerEvent> captor =
-                ArgumentCaptor.forClass(ImsDedicatedBearerListenerEvent.class);
-        verify(mPersistAtomsStorage).addImsDedicatedBearerListenerEvent(captor.capture());
-        ImsDedicatedBearerListenerEvent stats = captor.getValue();
-        assertEquals(CARRIER_ID, stats.carrierId);
-        assertEquals(SLOT_ID, stats.slotId);
-        assertEquals(rat, stats.ratAtEnd);
-        assertEquals(qci, stats.qci);
-        assertEquals(true, stats.dedicatedBearerEstablished);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-
-        assertFalse(mRcsStats.dedicatedBearerListenerEventMap_containsKey(listenerId));
-    }
-
-    @Test
-    @SmallTest
-    public void onImsDedicatedBearerEvent_withAtoms() throws Exception {
-        // reference comments in test_imsDedicatedBearerListenerEvent for canditate value
-        int ratAtEnd = TelephonyStatsLog
-                .IMS_DEDICATED_BEARER_LISTENER_EVENT__RAT_AT_END__NETWORK_TYPE_LTE_CA;
-        int qci = 6;
-        /*
-         * IMS_DEDICATED_BEARER_EVENT__BEARER_STATE__STATE_ADDED = 1;
-         * IMS_DEDICATED_BEARER_EVENT__BEARER_STATE__STATE_MODIFIED = 2;
-         * IMS_DEDICATED_BEARER_EVENT__BEARER_STATE__STATE_DELETED = 3;
-         */
-        int bearerState = TelephonyStatsLog.IMS_DEDICATED_BEARER_EVENT__BEARER_STATE__STATE_ADDED;
-        boolean localConnectionInfoReceived = false;
-        boolean remoteConnectionInfoReceived = true;
-        boolean hasListeners = true;
-
-        mRcsStats.onImsDedicatedBearerEvent(SLOT_ID, ratAtEnd, qci, bearerState,
-                localConnectionInfoReceived, remoteConnectionInfoReceived, hasListeners);
-
-        ArgumentCaptor<ImsDedicatedBearerEvent> captor =
-                ArgumentCaptor.forClass(ImsDedicatedBearerEvent.class);
-        verify(mPersistAtomsStorage).addImsDedicatedBearerEvent(captor.capture());
-        ImsDedicatedBearerEvent stats = captor.getValue();
-        assertEquals(CARRIER_ID, stats.carrierId);
-        assertEquals(SLOT_ID, stats.slotId);
-        assertEquals(ratAtEnd, stats.ratAtEnd);
-        assertEquals(qci, stats.qci);
-        assertEquals(bearerState, stats.bearerState);
-        assertEquals(localConnectionInfoReceived, stats.localConnectionInfoReceived);
-        assertEquals(remoteConnectionInfoReceived, stats.remoteConnectionInfoReceived);
-        assertEquals(hasListeners, stats.hasListeners);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onImsRegistrationServiceDescStats_withAtoms() throws Exception {
-        int registrationTech  = 0; //ImsRegistrationImplBase.REGISTRATION_TECH_LTE
-        ArrayList<String> serviceIdList = new ArrayList<>();
-        serviceIdList.add("org.openmobilealliance:File-Transfer-HTTP");
-        serviceIdList.add("org.openmobilealliance:IM-session");
-        serviceIdList.add("Unknown1");
-        ArrayList<String> serviceIdVersionList = new ArrayList<>();
-        serviceIdVersionList.add("1.0");
-        serviceIdVersionList.add("1.0");
-        serviceIdVersionList.add("3.0");
-
-        mRcsStats.onImsRegistrationServiceDescStats(mSubId, serviceIdList, serviceIdVersionList,
-                registrationTech);
-
-        // getWallTimeMillis
-        /*
-         * UCE_EVENT__TYPE__PUBLISH = 0;
-         * UCE_EVENT__TYPE__SUBSCRIBE = 1;
-         * UCE_EVENT__TYPE__INCOMING_OPTION = 2;
-         * UCE_EVENT__TYPE__OUTGOING_OPTION = 3;
-         */
-        int type = TelephonyStatsLog.UCE_EVENT_STATS__TYPE__PUBLISH;
-        boolean successful = true;
-        /*
-         * UCE_EVENT__COMMAND_CODE__SERVICE_UNKNOWN = 0;
-         * UCE_EVENT__COMMAND_CODE__GENERIC_FAILURE = 1;
-         * UCE_EVENT__COMMAND_CODE__INVALID_PARAM = 2;
-         * UCE_EVENT__COMMAND_CODE__FETCH_ERROR = 3;
-         * UCE_EVENT__COMMAND_CODE__REQUEST_TIMEOUT = 4;
-         * UCE_EVENT__COMMAND_CODE__INSUFFICIENT_MEMORY = 5;
-         * UCE_EVENT__COMMAND_CODE__LOST_NETWORK_CONNECTION = 6;
-         * UCE_EVENT__COMMAND_CODE__NOT_SUPPORTED = 7;
-         * UCE_EVENT__COMMAND_CODE__NOT_FOUND = 8;
-         * UCE_EVENT__COMMAND_CODE__SERVICE_UNAVAILABLE = 9;
-         * UCE_EVENT__COMMAND_CODE__NO_CHANGE = 10;
-         */
-        int commandCode = TelephonyStatsLog.UCE_EVENT_STATS__COMMAND_CODE__SERVICE_UNAVAILABLE;
-        int networkResponse = 200;
-
-        mRcsStats.onUceEventStats(mSubId, type, successful, commandCode, networkResponse);
-
-        {
-            ArgumentCaptor<UceEventStats> captor = ArgumentCaptor.forClass(UceEventStats.class);
-            verify(mPersistAtomsStorage).addUceEventStats(captor.capture());
-            UceEventStats stats = captor.getValue();
-            assertEquals(CARRIER_ID, stats.carrierId);
-            assertEquals(SLOT_ID, stats.slotId);
-            assertEquals(successful, stats.successful);
-            assertEquals(commandCode, stats.commandCode);
-            assertEquals(networkResponse, stats.networkResponse);
-            verifyNoMoreInteractions(mPersistAtomsStorage);
-        }
-
-        long timeGap = 6000L;
-        mRcsStats.incTimeMillis(timeGap);
-
-        mRcsStats.onStoreCompleteImsRegistrationServiceDescStats(mSubId);
-
-        ArgumentCaptor<ImsRegistrationServiceDescStats> captor =
-                ArgumentCaptor.forClass(ImsRegistrationServiceDescStats.class);
-        verify(mPersistAtomsStorage, times(3))
-                .addImsRegistrationServiceDescStats(captor.capture());
-        List<ImsRegistrationServiceDescStats> captorValues = captor.getAllValues();
-
-        assertEquals(captorValues.size(), serviceIdList.size());
-
-        for (int index = 0; index < captorValues.size(); index++) {
-            ImsRegistrationServiceDescStats stats = captorValues.get(index);
-            assertEquals(CARRIER_ID, stats.carrierId);
-            assertEquals(SLOT_ID, stats.slotId);
-            int serviceId = mRcsStats.convertServiceIdToValue(serviceIdList.get(index));
-            assertEquals(serviceId, stats.serviceIdName);
-            float serviceVersionFloat = Float.parseFloat(serviceIdVersionList.get(index));
-            assertEquals(serviceVersionFloat, stats.serviceIdVersion, 0.1f);
-            assertEquals(registrationTech, stats.registrationTech);
-            assertEquals(timeGap, stats.publishedMillis);
-        }
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onImsRegistrationServiceDescStats_withAtomsInvalidSubId() throws Exception {
-        int registrationTech  = 0; //ImsRegistrationImplBase.REGISTRATION_TECH_LTE
-        ArrayList<String> serviceIdList = new ArrayList<>();
-        serviceIdList.add("org.openmobilealliance:File-Transfer-HTTP");
-        serviceIdList.add("org.openmobilealliance:IM-session");
-        serviceIdList.add("Unknown1");
-        ArrayList<String> serviceIdVersionList = new ArrayList<>();
-        serviceIdVersionList.add("1.0");
-        serviceIdVersionList.add("1.0");
-        serviceIdVersionList.add("3.0");
-
-        mRcsStats.onImsRegistrationServiceDescStats(mSubId, serviceIdList, serviceIdVersionList,
-                registrationTech);
-
-        // getWallTimeMillis
-        /*
-         * UCE_EVENT__TYPE__PUBLISH = 0;
-         * UCE_EVENT__TYPE__SUBSCRIBE = 1;
-         * UCE_EVENT__TYPE__INCOMING_OPTION = 2;
-         * UCE_EVENT__TYPE__OUTGOING_OPTION = 3;
-         */
-        int type = TelephonyStatsLog.UCE_EVENT_STATS__TYPE__PUBLISH;
-        boolean successful = true;
-        /*
-         * UCE_EVENT__COMMAND_CODE__SERVICE_UNKNOWN = 0;
-         * UCE_EVENT__COMMAND_CODE__GENERIC_FAILURE = 1;
-         * UCE_EVENT__COMMAND_CODE__INVALID_PARAM = 2;
-         * UCE_EVENT__COMMAND_CODE__FETCH_ERROR = 3;
-         * UCE_EVENT__COMMAND_CODE__REQUEST_TIMEOUT = 4;
-         * UCE_EVENT__COMMAND_CODE__INSUFFICIENT_MEMORY = 5;
-         * UCE_EVENT__COMMAND_CODE__LOST_NETWORK_CONNECTION = 6;
-         * UCE_EVENT__COMMAND_CODE__NOT_SUPPORTED = 7;
-         * UCE_EVENT__COMMAND_CODE__NOT_FOUND = 8;
-         * UCE_EVENT__COMMAND_CODE__SERVICE_UNAVAILABLE = 9;
-         * UCE_EVENT__COMMAND_CODE__NO_CHANGE = 10;
-         */
-        int commandCode = TelephonyStatsLog.UCE_EVENT_STATS__COMMAND_CODE__SERVICE_UNAVAILABLE;
-        int networkResponse = 200;
-        mRcsStats.onUceEventStats(mSubId, type, successful, commandCode, networkResponse);
-
-        // slotId and carrierId are invalid based on subId
-        mRcsStats.setEnableInvalidSubId();
-        long timeGap = 6000L;
-        mRcsStats.incTimeMillis(timeGap);
-        mRcsStats.onUceEventStats(mSubId, type, successful, commandCode, networkResponse);
-
-        ArgumentCaptor<ImsRegistrationServiceDescStats> captor =
-                ArgumentCaptor.forClass(ImsRegistrationServiceDescStats.class);
-        verify(mPersistAtomsStorage, times(3))
-                .addImsRegistrationServiceDescStats(captor.capture());
-        List<ImsRegistrationServiceDescStats> captorValues = captor.getAllValues();
-
-        assertEquals(captorValues.size(), serviceIdList.size());
-
-        for (int index = 0; index < captorValues.size(); index++) {
-            ImsRegistrationServiceDescStats stats = captorValues.get(index);
-            assertEquals(CARRIER_ID, stats.carrierId);
-            assertEquals(SLOT_ID, stats.slotId);
-            int serviceId = mRcsStats.convertServiceIdToValue(serviceIdList.get(index));
-            assertEquals(serviceId, stats.serviceIdName);
-            float serviceVersionFloat = Float.parseFloat(serviceIdVersionList.get(index));
-            assertEquals(serviceVersionFloat, stats.serviceIdVersion, 0.1f);
-            assertEquals(registrationTech, stats.registrationTech);
-            assertEquals(timeGap, stats.publishedMillis);
-        }
-        assertEquals(0, mRcsStats.getImsRegistrationServiceDescCachedSize());
-    }
-
-    @Test
-    @SmallTest
-    public void onUceEventStats_withAtoms() throws Exception {
-        int messageType = TelephonyStatsLog.UCE_EVENT_STATS__TYPE__PUBLISH;
-        boolean successful = true;
-        int commandCode = TelephonyStatsLog.UCE_EVENT_STATS__COMMAND_CODE__REQUEST_TIMEOUT;
-        int networkResponse = 408;
-
-        mRcsStats.onUceEventStats(mSubId, messageType, successful, commandCode, networkResponse);
-
-        ArgumentCaptor<UceEventStats> captor = ArgumentCaptor.forClass(UceEventStats.class);
-        verify(mPersistAtomsStorage).addUceEventStats(captor.capture());
-        UceEventStats stats = captor.getValue();
-        assertEquals(CARRIER_ID, stats.carrierId);
-        assertEquals(SLOT_ID, stats.slotId);
-        assertEquals(successful, stats.successful);
-        assertEquals(commandCode, stats.commandCode);
-        assertEquals(networkResponse, stats.networkResponse);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onPresenceNotifyEvent_withAtoms() throws Exception {
-        String reason = "deactivated";
-        boolean contentBodyReceived = true;
-        boolean rcsCaps = true;
-        boolean mmtelCaps = false;
-        boolean noCaps = false;
-
-        mRcsStats.onPresenceNotifyEvent(mSubId, reason, contentBodyReceived,
-                rcsCaps, mmtelCaps, noCaps);
-
-        ArgumentCaptor<PresenceNotifyEvent> captor =
-                ArgumentCaptor.forClass(PresenceNotifyEvent.class);
-        verify(mPersistAtomsStorage).addPresenceNotifyEvent(captor.capture());
-        PresenceNotifyEvent stats = captor.getValue();
-        assertEquals(CARRIER_ID, stats.carrierId);
-        assertEquals(SLOT_ID, stats.slotId);
-        int reasonInt = mRcsStats.convertPresenceNotifyReason(reason);
-        assertEquals(reasonInt, stats.reason);
-        assertEquals(contentBodyReceived, stats.contentBodyReceived);
-        assertEquals(1, stats.rcsCapsCount);
-        assertEquals(0, stats.mmtelCapsCount);
-        assertEquals(0, stats.noCapsCount);
-        assertEquals(1, stats.rcsCapsCount);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onGbaEvent_withAtoms() throws Exception {
-        boolean successful = false;
-        /*
-         * GBA_EVENT__FAILED_REASON__UNKNOWN
-         * GBA_EVENT__FAILED_REASON__FEATURE_NOT_SUPPORTED
-         * GBA_EVENT__FAILED_REASON__FEATURE_NOT_READY
-         * GBA_EVENT__FAILED_REASON__NETWORK_FAILURE
-         * GBA_EVENT__FAILED_REASON__INCORRECT_NAF_ID
-         * GBA_EVENT__FAILED_REASON__SECURITY_PROTOCOL_NOT_SUPPORTED
-         */
-        int failedReason = TelephonyStatsLog.GBA_EVENT__FAILED_REASON__FEATURE_NOT_READY;
-
-        mRcsStats.onGbaFailureEvent(mSubId, failedReason);
-
-        ArgumentCaptor<GbaEvent> captor = ArgumentCaptor.forClass(GbaEvent.class);
-        verify(mPersistAtomsStorage).addGbaEvent(captor.capture());
-        GbaEvent stats = captor.getValue();
-        assertEquals(CARRIER_ID, stats.carrierId);
-        assertEquals(SLOT_ID, stats.slotId);
-        assertEquals(successful, stats.successful);
-        assertEquals(failedReason, stats.failedReason);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/ServiceStateStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/ServiceStateStatsTest.java
index 96db966..8c6752c 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/ServiceStateStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/ServiceStateStatsTest.java
@@ -23,7 +23,6 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -46,16 +45,16 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 public class ServiceStateStatsTest extends TelephonyTest {
     private static final long START_TIME_MILLIS = 2000L;
     private static final int CARRIER1_ID = 1;
     private static final int CARRIER2_ID = 1187;
 
-    // Mocked classes
-    private UiccSlot mPhysicalSlot0;
-    private UiccSlot mPhysicalSlot1;
-    private Phone mSecondPhone;
+    @Mock private UiccSlot mPhysicalSlot0;
+    @Mock private UiccSlot mPhysicalSlot1;
+    @Mock private Phone mSecondPhone;
 
     private TestableServiceStateStats mServiceStateStats;
 
@@ -85,9 +84,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mPhysicalSlot0 = mock(UiccSlot.class);
-        mPhysicalSlot1 = mock(UiccSlot.class);
-        mSecondPhone = mock(Phone.class);
 
         doReturn(CARRIER1_ID).when(mPhone).getCarrierId();
         doReturn(mImsPhone).when(mPhone).getImsPhone();
@@ -103,14 +99,12 @@
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         mockWwanPsRat(TelephonyManager.NETWORK_TYPE_LTE);
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mImsStats).getImsVoiceRadioTech();
 
         mServiceStateStats = new TestableServiceStateStats(mPhone);
     }
 
     @After
     public void tearDown() throws Exception {
-        mServiceStateStats = null;
         super.tearDown();
     }
 
@@ -138,7 +132,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -170,7 +163,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -200,7 +192,7 @@
         doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getVoiceNetworkType();
         doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mServiceState).getDataNetworkType();
         mockWwanPsRat(TelephonyManager.NETWORK_TYPE_UNKNOWN);
-        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech();
+        doReturn(true).when(mImsPhone).isWifiCallingEnabled();
         mServiceStateStats.onServiceStateChanged(mServiceState);
 
         mServiceStateStats.incTimeMillis(100L);
@@ -213,8 +205,10 @@
     @Test
     @SmallTest
     public void conclude_noSimCardEmergencyOnly() throws Exception {
+        // Using default service state for LTE
         doReturn(CardState.CARDSTATE_ABSENT).when(mPhysicalSlot0).getCardState();
-        mockLimitedService(TelephonyManager.NETWORK_TYPE_UMTS);
+        doReturn(ServiceState.STATE_EMERGENCY_ONLY).when(mServiceState).getVoiceRegState();
+        doReturn(ServiceState.STATE_EMERGENCY_ONLY).when(mServiceState).getDataRegState();
         doReturn(-1).when(mPhone).getCarrierId();
         mServiceStateStats.onServiceStateChanged(mServiceState);
 
@@ -227,8 +221,8 @@
         verify(mPersistAtomsStorage)
                 .addCellularServiceStateAndCellularDataServiceSwitch(captor.capture(), eq(null));
         CellularServiceState state = captor.getValue();
-        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, state.voiceRat);
-        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, state.dataRat);
+        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
+        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
         assertEquals(ServiceState.ROAMING_TYPE_NOT_ROAMING, state.voiceRoamingType);
         assertEquals(ServiceState.ROAMING_TYPE_NOT_ROAMING, state.dataRoamingType);
         assertFalse(state.isEndc);
@@ -236,7 +230,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(-1, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(true, state.isEmergencyOnly);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -270,7 +263,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(-1, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
@@ -301,7 +293,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         state = captor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -312,60 +303,12 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
     @Test
     @SmallTest
-    public void onImsVoiceRegistrationChanged_wifiCallingWhileOos() throws Exception {
-        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getVoiceNetworkType();
-        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getDataNetworkType();
-        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mImsStats).getImsVoiceRadioTech();
-        mockWwanCsRat(TelephonyManager.NETWORK_TYPE_UNKNOWN);
-        mockWwanPsRat(TelephonyManager.NETWORK_TYPE_UNKNOWN);
-        mServiceStateStats.onServiceStateChanged(mServiceState);
-        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech();
-
-        mServiceStateStats.incTimeMillis(100L);
-        mServiceStateStats.onImsVoiceRegistrationChanged();
-        mServiceStateStats.incTimeMillis(200L);
-        mServiceStateStats.conclude();
-
-        // There should be 2 separate service state updates, which should be different objects
-        ArgumentCaptor<CellularServiceState> captor =
-                ArgumentCaptor.forClass(CellularServiceState.class);
-        verify(mPersistAtomsStorage, times(2))
-                .addCellularServiceStateAndCellularDataServiceSwitch(captor.capture(), eq(null));
-        assertNotSame(captor.getAllValues().get(0), captor.getAllValues().get(1));
-        CellularServiceState state = captor.getAllValues().get(0);
-        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, state.voiceRat);
-        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, state.dataRat);
-        assertEquals(ServiceState.ROAMING_TYPE_NOT_ROAMING, state.voiceRoamingType);
-        assertEquals(ServiceState.ROAMING_TYPE_NOT_ROAMING, state.dataRoamingType);
-        assertFalse(state.isEndc);
-        assertEquals(0, state.simSlotIndex);
-        assertFalse(state.isMultiSim);
-        assertEquals(CARRIER1_ID, state.carrierId);
-        assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
-        state = captor.getAllValues().get(1);
-        assertEquals(TelephonyManager.NETWORK_TYPE_IWLAN, state.voiceRat);
-        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, state.dataRat);
-        assertEquals(ServiceState.ROAMING_TYPE_NOT_ROAMING, state.voiceRoamingType);
-        assertEquals(ServiceState.ROAMING_TYPE_NOT_ROAMING, state.dataRoamingType);
-        assertFalse(state.isEndc);
-        assertEquals(0, state.simSlotIndex);
-        assertFalse(state.isMultiSim);
-        assertEquals(CARRIER1_ID, state.carrierId);
-        assertEquals(200L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
-        verifyNoMoreInteractions(mPersistAtomsStorage);
-    }
-
-    @Test
-    @SmallTest
-    public void onServiceStateChanged_sameRats() throws Exception {
+    public void update_sameRats() throws Exception {
         // Using default service state for LTE
 
         mServiceStateStats.onServiceStateChanged(mServiceState);
@@ -387,13 +330,12 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
     @Test
     @SmallTest
-    public void onServiceStateChanged_differentDataRats() throws Exception {
+    public void update_differentDataRats() throws Exception {
         doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getDataNetworkType();
         mockWwanPsRat(TelephonyManager.NETWORK_TYPE_UNKNOWN);
 
@@ -414,7 +356,7 @@
                 .addCellularServiceStateAndCellularDataServiceSwitch(
                         serviceStateCaptor.capture(), serviceSwitchCaptor.capture());
         CellularServiceState state = serviceStateCaptor.getAllValues().get(0);
-        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, state.voiceRat);
+        assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, state.dataRat);
         assertEquals(ServiceState.ROAMING_TYPE_NOT_ROAMING, state.voiceRoamingType);
         assertEquals(ServiceState.ROAMING_TYPE_NOT_ROAMING, state.dataRoamingType);
@@ -423,7 +365,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         state = serviceStateCaptor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -434,7 +375,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         CellularDataServiceSwitch serviceSwitch = serviceSwitchCaptor.getAllValues().get(0);
         assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, serviceSwitch.ratFrom);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, serviceSwitch.ratTo);
@@ -448,14 +388,14 @@
 
     @Test
     @SmallTest
-    public void onServiceStateChanged_differentVoiceRats() throws Exception {
+    public void update_differentVoiceRats() throws Exception {
         // Using default service state for LTE
 
         mServiceStateStats.onServiceStateChanged(mServiceState);
         mServiceStateStats.incTimeMillis(100L);
         // Voice RAT changes to IWLAN and data RAT stays in LTE according to WWAN PS RAT
         doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mServiceState).getDataNetworkType();
-        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech();
+        doReturn(true).when(mImsPhone).isWifiCallingEnabled();
         mServiceStateStats.onServiceStateChanged(mServiceState);
         mServiceStateStats.incTimeMillis(100L);
 
@@ -490,9 +430,10 @@
 
     @Test
     @SmallTest
-    public void onServiceStateChanged_iwlanButNotWifiCalling() throws Exception {
+    public void update_iwlanButNotWifiCalling() throws Exception {
         // Using default service state for LTE as WWAN PS RAT
         doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mServiceState).getDataNetworkType();
+        doReturn(false).when(mImsPhone).isWifiCallingEnabled();
 
         mServiceStateStats.onServiceStateChanged(mServiceState);
 
@@ -512,13 +453,12 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(0L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
     @Test
     @SmallTest
-    public void onServiceStateChanged_endc() throws Exception {
+    public void update_endc() throws Exception {
         // Using default service state for LTE without ENDC
 
         mServiceStateStats.onServiceStateChanged(mServiceState);
@@ -552,7 +492,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         state = captor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -563,7 +502,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(200L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         state = captor.getAllValues().get(2);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -574,7 +512,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(400L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         state = captor.getAllValues().get(3);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -585,20 +522,21 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(800L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
     @Test
     @SmallTest
-    public void onServiceStateChanged_simSwapSameRat() throws Exception {
+    public void update_simSwapSameRat() throws Exception {
         // Using default service state for LTE
 
         mServiceStateStats.onServiceStateChanged(mServiceState);
         mServiceStateStats.incTimeMillis(100L);
         // SIM removed, emergency call only
         doReturn(CardState.CARDSTATE_ABSENT).when(mPhysicalSlot0).getCardState();
-        mockLimitedService(TelephonyManager.NETWORK_TYPE_UMTS);
+        doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
+        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getDataNetworkType();
+        mockWwanPsRat(TelephonyManager.NETWORK_TYPE_UNKNOWN);
         doReturn(-1).when(mPhone).getCarrierId();
         mServiceStateStats.onServiceStateChanged(mServiceState);
         mServiceStateStats.incTimeMillis(5000L);
@@ -607,8 +545,6 @@
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getDataNetworkType();
         mockWwanPsRat(TelephonyManager.NETWORK_TYPE_LTE);
-        mockWwanCsRat(TelephonyManager.NETWORK_TYPE_LTE);
-        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mImsStats).getImsVoiceRadioTech();
         doReturn(CARRIER2_ID).when(mPhone).getCarrierId();
         mServiceStateStats.onServiceStateChanged(mServiceState);
         mServiceStateStats.incTimeMillis(200L);
@@ -629,9 +565,8 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         state = captor.getAllValues().get(1);
-        assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, state.voiceRat);
+        assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_UNKNOWN, state.dataRat);
         assertEquals(ServiceState.ROAMING_TYPE_NOT_ROAMING, state.voiceRoamingType);
         assertEquals(ServiceState.ROAMING_TYPE_NOT_ROAMING, state.dataRoamingType);
@@ -640,7 +575,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(-1, state.carrierId);
         assertEquals(5000L, state.totalTimeMillis);
-        assertEquals(true, state.isEmergencyOnly);
         state = captor.getAllValues().get(2);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -651,13 +585,12 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER2_ID, state.carrierId);
         assertEquals(200L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
     @Test
     @SmallTest
-    public void onServiceStateChanged_roaming() throws Exception {
+    public void update_roaming() throws Exception {
         // Using default service state for LTE
 
         mServiceStateStats.onServiceStateChanged(mServiceState);
@@ -666,8 +599,6 @@
         doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
         doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getDataNetworkType();
         mockWwanPsRat(TelephonyManager.NETWORK_TYPE_UMTS);
-        mockWwanCsRat(TelephonyManager.NETWORK_TYPE_UMTS);
-        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mImsStats).getImsVoiceRadioTech();
         doReturn(ServiceState.ROAMING_TYPE_INTERNATIONAL).when(mServiceState).getVoiceRoamingType();
         mServiceStateStats.onServiceStateChanged(mServiceState);
         mServiceStateStats.incTimeMillis(200L);
@@ -695,7 +626,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         state = serviceStateCaptor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.dataRat);
@@ -706,7 +636,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(200L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         state = serviceStateCaptor.getAllValues().get(2);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.dataRat);
@@ -717,7 +646,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(400L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         CellularDataServiceSwitch serviceSwitch = serviceSwitchCaptor.getAllValues().get(0);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, serviceSwitch.ratFrom);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, serviceSwitch.ratTo);
@@ -732,7 +660,7 @@
 
     @Test
     @SmallTest
-    public void onServiceStateChanged_dualSim() throws Exception {
+    public void update_dualSim() throws Exception {
         // Using default service state for LTE
         // Only difference between the 2 slots is slot index
         mockDualSim(CARRIER1_ID);
@@ -745,9 +673,7 @@
         mSecondServiceStateStats.incTimeMillis(100L);
         doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
         doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getDataNetworkType();
-        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mImsStats).getImsVoiceRadioTech();
         mockWwanPsRat(TelephonyManager.NETWORK_TYPE_UMTS);
-        mockWwanCsRat(TelephonyManager.NETWORK_TYPE_UMTS);
         mServiceStateStats.onServiceStateChanged(mServiceState);
         mServiceStateStats.incTimeMillis(200L);
         mSecondServiceStateStats.onServiceStateChanged(mServiceState);
@@ -773,7 +699,6 @@
         assertTrue(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         state = serviceStateCaptor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -784,7 +709,6 @@
         assertTrue(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         state = serviceStateCaptor.getAllValues().get(2);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.dataRat);
@@ -795,7 +719,6 @@
         assertTrue(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(200L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         state = serviceStateCaptor.getAllValues().get(3);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, state.dataRat);
@@ -806,7 +729,6 @@
         assertTrue(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(200L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         CellularDataServiceSwitch serviceSwitch = serviceSwitchCaptor.getAllValues().get(0);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, serviceSwitch.ratFrom);
         assertEquals(TelephonyManager.NETWORK_TYPE_UMTS, serviceSwitch.ratTo);
@@ -828,7 +750,7 @@
 
     @Test
     @SmallTest
-    public void onServiceStateChanged_airplaneMode() throws Exception {
+    public void update_airplaneMode() throws Exception {
         // Using default service state for LTE
 
         mServiceStateStats.onServiceStateChanged(mServiceState);
@@ -866,7 +788,6 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(100L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         state = captor.getAllValues().get(1);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.voiceRat);
         assertEquals(TelephonyManager.NETWORK_TYPE_LTE, state.dataRat);
@@ -877,55 +798,14 @@
         assertFalse(state.isMultiSim);
         assertEquals(CARRIER1_ID, state.carrierId);
         assertEquals(200L, state.totalTimeMillis);
-        assertEquals(false, state.isEmergencyOnly);
         verifyNoMoreInteractions(mPersistAtomsStorage);
     }
 
     private void mockWwanPsRat(@NetworkType int rat) {
-        mockWwanRat(
-                NetworkRegistrationInfo.DOMAIN_PS,
-                rat,
-                rat == TelephonyManager.NETWORK_TYPE_UNKNOWN
-                        ? NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING
-                        : NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-    }
-
-    private void mockWwanCsRat(@NetworkType int rat) {
-        mockWwanRat(
-                NetworkRegistrationInfo.DOMAIN_CS,
-                rat,
-                rat == TelephonyManager.NETWORK_TYPE_UNKNOWN
-                        ? NetworkRegistrationInfo.REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING
-                        : NetworkRegistrationInfo.REGISTRATION_STATE_HOME);
-    }
-
-    private void mockWwanRat(
-            @NetworkRegistrationInfo.Domain int domain,
-            @NetworkType int rat,
-            @NetworkRegistrationInfo.RegistrationState int regState) {
-        doReturn(
-                        new NetworkRegistrationInfo.Builder()
-                                .setAccessNetworkTechnology(rat)
-                                .setRegistrationState(regState)
-                                .build())
-                .when(mServiceState)
-                .getNetworkRegistrationInfo(domain, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
-    }
-
-    private void mockLimitedService(@NetworkType int rat) {
-        doReturn(rat).when(mServiceState).getVoiceNetworkType();
-        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getDataNetworkType();
-        mockWwanPsRat(TelephonyManager.NETWORK_TYPE_UNKNOWN);
-        doReturn(
-                        new NetworkRegistrationInfo.Builder()
-                                .setAccessNetworkTechnology(rat)
-                                .setRegistrationState(
-                                        NetworkRegistrationInfo.REGISTRATION_STATE_DENIED)
-                                .setEmergencyOnly(true)
-                                .build())
+        doReturn(new NetworkRegistrationInfo.Builder().setAccessNetworkTechnology(rat).build())
                 .when(mServiceState)
                 .getNetworkRegistrationInfo(
-                        NetworkRegistrationInfo.DOMAIN_CS,
+                        NetworkRegistrationInfo.DOMAIN_PS,
                         AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/SimSlotStateTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/SimSlotStateTest.java
index 0a64ee3..e05faec 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/SimSlotStateTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/SimSlotStateTest.java
@@ -21,42 +21,31 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
 import com.android.internal.telephony.uicc.UiccCard;
-import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UiccSlot;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 
 public class SimSlotStateTest extends TelephonyTest {
-    // Mocked classes
-    private UiccSlot mInactiveSlot;
-    private UiccSlot mEmptySlot;
-    private UiccSlot mPhysicalSlot;
-    private UiccSlot mEsimSlot;
-    private UiccCard mInactiveCard;
-    private UiccCard mActiveCard;
-    private UiccPort mInactivePort;
-    private UiccPort mActivePort;
+    @Mock private UiccSlot mInactiveSlot;
+    @Mock private UiccSlot mEmptySlot;
+    @Mock private UiccSlot mPhysicalSlot;
+    @Mock private UiccSlot mEsimSlot;
+
+    @Mock private UiccCard mInactiveCard;
+    @Mock private UiccCard mActiveCard;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mInactiveSlot = mock(UiccSlot.class);
-        mEmptySlot = mock(UiccSlot.class);
-        mPhysicalSlot = mock(UiccSlot.class);
-        mEsimSlot = mock(UiccSlot.class);
-        mInactiveCard = mock(UiccCard.class);
-        mActiveCard = mock(UiccCard.class);
-        mInactivePort = mock(UiccPort.class);
-        mActivePort = mock(UiccPort.class);
 
         doReturn(false).when(mInactiveSlot).isActive();
 
@@ -71,11 +60,8 @@
         doReturn(CardState.CARDSTATE_PRESENT).when(mEsimSlot).getCardState();
         doReturn(true).when(mEsimSlot).isEuicc();
 
-        doReturn(0).when(mInactivePort).getNumApplications();
-        doReturn(4).when(mActivePort).getNumApplications();
-
-        doReturn(new UiccPort[]{mInactivePort}).when(mInactiveCard).getUiccPortList();
-        doReturn(new UiccPort[]{mActivePort}).when(mActiveCard).getUiccPortList();
+        doReturn(0).when(mInactiveCard).getNumApplications();
+        doReturn(4).when(mActiveCard).getNumApplications();
     }
 
     @After
@@ -363,29 +349,6 @@
     }
 
     @Test
-    public void testDsds_dualSimMEPFeature() {
-        doReturn(mActiveCard).when(mEsimSlot).getUiccCard();
-        doReturn(new UiccPort[]{mInactivePort, mActivePort}).when(mActiveCard).getUiccPortList();
-        setupDualSim(mEmptySlot, mEsimSlot);
-        doReturn(mEsimSlot).when(mUiccController).getUiccSlotForPhone(eq(0));
-        doReturn(mEsimSlot).when(mUiccController).getUiccSlotForPhone(eq(1));
-
-        boolean isEsim0 = SimSlotState.isEsim(0);
-        boolean isEsim1 = SimSlotState.isEsim(1);
-
-        assertTrue(isEsim0);
-        assertTrue(isEsim1);
-
-        SimSlotState state = SimSlotState.getCurrentState();
-        boolean isMultiSim = SimSlotState.isMultiSim();
-
-        assertEquals(2, state.numActiveSlots);
-        assertEquals(1, state.numActiveSims);
-        assertEquals(1, state.numActiveEsims);
-        assertFalse(isMultiSim); // one Uicc Port does not have active sim profile
-    }
-
-    @Test
     @SmallTest
     public void isEsim_singlePhysicalSim() {
         doReturn(mPhysicalSlot).when(mUiccController).getUiccSlotForPhone(eq(0));
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
index 111e5d2..c4e6e27 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/TelephonyMetricsTest.java
@@ -24,12 +24,12 @@
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_DEACTIVATE_DATA_CALL;
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SEND_SMS;
 import static com.android.internal.telephony.RILConstants.RIL_REQUEST_SETUP_DATA_CALL;
-import static com.android.internal.telephony.data.LinkBandwidthEstimator.NUM_SIGNAL_LEVEL;
 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_ADDRESS;
 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_DNS;
 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_GATEWAY;
 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_IFNAME;
 import static com.android.internal.telephony.dataconnection.DcTrackerTest.FAKE_PCSCF_ADDRESS;
+import static com.android.internal.telephony.dataconnection.LinkBandwidthEstimator.NUM_SIGNAL_LEVEL;
 import static com.android.internal.telephony.nano.TelephonyProto.PdpType.PDP_TYPE_IPV4V6;
 
 import static org.junit.Assert.assertArrayEquals;
@@ -37,7 +37,6 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 
 import android.net.InetAddresses;
 import android.net.LinkAddress;
@@ -61,7 +60,7 @@
 import com.android.internal.telephony.SmsResponse;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.UUSInfo;
-import com.android.internal.telephony.data.LinkBandwidthEstimator;
+import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator;
 import com.android.internal.telephony.nano.TelephonyProto;
 import com.android.internal.telephony.nano.TelephonyProto.BandwidthEstimatorStats;
 import com.android.internal.telephony.nano.TelephonyProto.ImsConnectionState;
@@ -83,15 +82,21 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
 
 public class TelephonyMetricsTest extends TelephonyTest {
-    // Mocked classes
+
+    @Mock
     private ImsCallSession mImsCallSession;
+
+    @Mock
     private ServiceState mServiceState;
+
+    @Mock
     private GsmCdmaConnection mConnection;
 
     private TelephonyMetrics mMetrics;
@@ -103,9 +108,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mImsCallSession = mock(ImsCallSession.class);
-        mServiceState = mock(ServiceState.class);
-        mConnection = mock(GsmCdmaConnection.class);
         mMetrics = new TelephonyMetrics();
         mMetrics.setContext(mContext);
         mUusInfo = new UUSInfo(1, 2, new byte[]{1, 2});
@@ -128,9 +130,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mMetrics = null;
-        mUusInfo = null;
-        mImsReasonInfo = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java b/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
index 5ae6d39..f64bc6e 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/metrics/VoiceCallSessionStatsTest.java
@@ -18,13 +18,6 @@
 
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_CS;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__BEARER_AT_END__CALL_BEARER_IMS;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_FIVE_MINUTES;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_HOUR;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_MINUTE;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_TEN_MINUTES;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_THIRTY_MINUTES;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_MORE_THAN_ONE_HOUR;
-import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MO;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__DIRECTION__CALL_DIRECTION_MT;
 import static com.android.internal.telephony.TelephonyStatsLog.VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
@@ -39,19 +32,14 @@
 import static com.google.common.truth.Truth.assertWithMessage;
 
 import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
 
-import android.telephony.AccessNetworkConstants;
-import android.telephony.Annotation.NetworkType;
 import android.telephony.DisconnectCause;
-import android.telephony.NetworkRegistrationInfo;
 import android.telephony.PreciseDisconnectCause;
 import android.telephony.ServiceState;
 import android.telephony.TelephonyManager;
@@ -76,13 +64,13 @@
 import com.android.internal.telephony.protobuf.nano.MessageNano;
 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
 import com.android.internal.telephony.uicc.UiccCard;
-import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UiccSlot;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -94,25 +82,25 @@
     private static final int CARRIER_ID_SLOT_0 = 1;
     private static final int CARRIER_ID_SLOT_1 = 1187;
 
-    // Mocked classes
-    private Phone mSecondPhone;
-    private ServiceStateTracker mSecondServiceStateTracker;
-    private ServiceState mSecondServiceState;
-    private UiccSlot mPhysicalSlot;
-    private UiccSlot mEsimSlot;
-    private UiccSlot mEmptySlot;
-    private UiccCard mInactiveCard;
-    private UiccCard mActiveCard;
-    private UiccPort mInactivePort;
-    private UiccPort mActivePort;
-    private ImsPhoneConnection mImsConnection0;
-    private ImsPhoneConnection mImsConnection1;
-    private GsmCdmaConnection mGsmConnection0;
-    private GsmCdmaConnection mGsmConnection1;
-    private GsmCdmaCall mCsCall0;
-    private GsmCdmaCall mCsCall1;
-    private ImsPhoneCall mImsCall0;
-    private ImsPhoneCall mImsCall1;
+    @Mock private Phone mSecondPhone;
+    @Mock private ServiceStateTracker mSecondServiceStateTracker;
+    @Mock private ServiceState mSecondServiceState;
+
+    @Mock private UiccSlot mPhysicalSlot;
+    @Mock private UiccSlot mEsimSlot;
+    @Mock private UiccSlot mEmptySlot;
+    @Mock private UiccCard mInactiveCard;
+    @Mock private UiccCard mActiveCard;
+
+    @Mock private ImsPhoneConnection mImsConnection0;
+    @Mock private ImsPhoneConnection mImsConnection1;
+    @Mock private GsmCdmaConnection mGsmConnection0;
+    @Mock private GsmCdmaConnection mGsmConnection1;
+
+    @Mock private GsmCdmaCall mCsCall0;
+    @Mock private GsmCdmaCall mCsCall1;
+    @Mock private ImsPhoneCall mImsCall0;
+    @Mock private ImsPhoneCall mImsCall1;
 
     private static class TestableVoiceCallSessionStats extends VoiceCallSessionStats {
         private long mTimeMillis = 0L;
@@ -141,24 +129,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mSecondPhone = mock(Phone.class);
-        mSecondServiceStateTracker = mock(ServiceStateTracker.class);
-        mSecondServiceState = mock(ServiceState.class);
-        mPhysicalSlot = mock(UiccSlot.class);
-        mEsimSlot = mock(UiccSlot.class);
-        mEmptySlot = mock(UiccSlot.class);
-        mInactiveCard = mock(UiccCard.class);
-        mActiveCard = mock(UiccCard.class);
-        mInactivePort = mock(UiccPort.class);
-        mActivePort = mock(UiccPort.class);
-        mImsConnection0 = mock(ImsPhoneConnection.class);
-        mImsConnection1 = mock(ImsPhoneConnection.class);
-        mGsmConnection0 = mock(GsmCdmaConnection.class);
-        mGsmConnection1 = mock(GsmCdmaConnection.class);
-        mCsCall0 = mock(GsmCdmaCall.class);
-        mCsCall1 = mock(GsmCdmaCall.class);
-        mImsCall0 = mock(ImsPhoneCall.class);
-        mImsCall1 = mock(ImsPhoneCall.class);
 
         replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[] {mPhone, mSecondPhone});
         doReturn(CARRIER_ID_SLOT_0).when(mPhone).getCarrierId();
@@ -168,9 +138,15 @@
         doReturn(mSecondServiceStateTracker).when(mSecondPhone).getServiceStateTracker();
         doReturn(mSecondServiceState).when(mSecondServiceStateTracker).getServiceState();
 
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_UNKNOWN);
+        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getDataNetworkType();
+        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getVoiceNetworkType();
         doReturn(false).when(mServiceState).getVoiceRoaming();
-        setServiceState(mSecondServiceState, TelephonyManager.NETWORK_TYPE_UNKNOWN);
+        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN)
+                .when(mSecondServiceState)
+                .getDataNetworkType();
+        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN)
+                .when(mSecondServiceState)
+                .getVoiceNetworkType();
         doReturn(false).when(mSecondServiceState).getVoiceRoaming();
 
         doReturn(true).when(mPhysicalSlot).isActive();
@@ -181,8 +157,8 @@
         doReturn(true).when(mEsimSlot).isActive();
         doReturn(CardState.CARDSTATE_PRESENT).when(mEsimSlot).getCardState();
         doReturn(true).when(mEsimSlot).isEuicc();
-        doReturn(0).when(mInactivePort).getNumApplications();
-        doReturn(4).when(mActivePort).getNumApplications();
+        doReturn(0).when(mInactiveCard).getNumApplications();
+        doReturn(4).when(mActiveCard).getNumApplications();
 
         doReturn(new UiccSlot[] {mPhysicalSlot}).when(mUiccController).getUiccSlots();
         doReturn(mPhysicalSlot).when(mUiccController).getUiccSlot(eq(0));
@@ -208,18 +184,15 @@
 
     @After
     public void tearDown() throws Exception {
-        mVoiceCallSessionStats0 = null;
-        mVoiceCallSessionStats1 = null;
         super.tearDown();
     }
 
     @Test
     @SmallTest
     public void singleImsCall_moRejected() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(false).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
-        doReturn(0L).when(mImsConnection0).getDurationMillis();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
         doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
         VoiceCallSession expectedCall =
@@ -237,7 +210,6 @@
         expectedCall.mainCodecQuality =
                 VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND;
         expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-        expectedCall.callDuration = VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
         VoiceCallRatUsage expectedRatUsage =
                 makeRatUsageProto(
                         CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 1L);
@@ -271,10 +243,9 @@
     @Test
     @SmallTest
     public void singleImsCall_moFailed() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(false).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
-        doReturn(0L).when(mImsConnection0).getDurationMillis();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
         doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
         VoiceCallSession expectedCall =
@@ -285,7 +256,6 @@
                         ImsReasonInfo.CODE_SIP_FORBIDDEN);
         expectedCall.setupFailed = true;
         expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-        expectedCall.callDuration = VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
         VoiceCallRatUsage expectedRatUsage =
                 makeRatUsageProto(
                         CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 2200L, 1L);
@@ -312,10 +282,9 @@
     @Test
     @SmallTest
     public void singleImsCall_moAccepted() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(false).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
-        doReturn(1000L).when(mImsConnection0).getDurationMillis();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
         doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
         VoiceCallSession expectedCall =
@@ -332,8 +301,6 @@
         expectedCall.mainCodecQuality =
                 VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_SUPER_WIDEBAND;
         expectedCall.disconnectExtraMessage = "normal call clearing";
-        expectedCall.callDuration =
-                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_MINUTE;
         VoiceCallRatUsage expectedRatUsage =
                 makeRatUsageProto(
                         CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 100000L, 1L);
@@ -373,10 +340,9 @@
     @Test
     @SmallTest
     public void singleImsCall_mtRejected() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
-        doReturn(0L).when(mImsConnection0).getDurationMillis();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
         doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
         VoiceCallSession expectedCall =
@@ -390,7 +356,6 @@
         expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
         expectedCall.mainCodecQuality =
                 VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
-        expectedCall.callDuration = VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_UNKNOWN;
         VoiceCallRatUsage expectedRatUsage =
                 makeRatUsageProto(
                         CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 8000L, 1L);
@@ -420,11 +385,10 @@
     @Test
     @SmallTest
     public void singleImsCall_mtAccepted() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
-        doReturn(60006L).when(mImsConnection0).getDurationMillis();
         doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
         VoiceCallSession expectedCall =
                 makeSlot0CallProto(
@@ -439,8 +403,6 @@
         expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
         expectedCall.mainCodecQuality =
                 VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
-        expectedCall.callDuration =
-                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_FIVE_MINUTES;
         VoiceCallRatUsage expectedRatUsage =
                 makeRatUsageProto(
                         CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 12000L, 1L);
@@ -477,11 +439,10 @@
     @SmallTest
     public void singleImsCall_dsdsModeSingleSim() {
         doReturn(mInactiveCard).when(mEsimSlot).getUiccCard();
-        doReturn(new UiccPort[]{mInactivePort}).when(mInactiveCard).getUiccPortList();
         doReturn(new UiccSlot[] {mPhysicalSlot, mEsimSlot}).when(mUiccController).getUiccSlots();
         doReturn(mEsimSlot).when(mUiccController).getUiccSlot(eq(1));
         doReturn(mEsimSlot).when(mUiccController).getUiccSlotForPhone(eq(1));
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
@@ -522,11 +483,10 @@
     @SmallTest
     public void singleImsCall_dsdsMode() {
         doReturn(mActiveCard).when(mEsimSlot).getUiccCard();
-        doReturn(new UiccPort[]{mActivePort}).when(mActiveCard).getUiccPortList();
         doReturn(new UiccSlot[] {mPhysicalSlot, mEsimSlot}).when(mUiccController).getUiccSlots();
         doReturn(mEsimSlot).when(mUiccController).getUiccSlot(eq(1));
         doReturn(mEsimSlot).when(mUiccController).getUiccSlotForPhone(eq(1));
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
@@ -567,11 +527,10 @@
     @SmallTest
     public void singleImsCall_esim() {
         doReturn(mActiveCard).when(mEsimSlot).getUiccCard();
-        doReturn(new UiccPort[]{mActivePort}).when(mActiveCard).getUiccPortList();
         doReturn(new UiccSlot[] {mPhysicalSlot, mEsimSlot}).when(mUiccController).getUiccSlots();
         doReturn(mEsimSlot).when(mUiccController).getUiccSlot(eq(1));
         doReturn(mEsimSlot).when(mUiccController).getUiccSlotForPhone(eq(1));
-        setServiceState(mSecondServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mSecondServiceState).getVoiceNetworkType();
         doReturn(true).when(mImsConnection1).isIncoming();
         doReturn(2000L).when(mImsConnection1).getCreateTime();
         doReturn(mImsCall1).when(mImsConnection1).getCall();
@@ -610,7 +569,7 @@
     @Test
     @SmallTest
     public void singleImsCall_emergency() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
         doReturn(true).when(mImsConnection0).isEmergencyCall();
@@ -651,7 +610,7 @@
     @Test
     @SmallTest
     public void singleImsCall_roaming() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mServiceState).getVoiceRoaming();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
@@ -692,10 +651,9 @@
     @Test
     @SmallTest
     public void singleImsCall_codecSwitch() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
-        doReturn(300000L).when(mImsConnection0).getDurationMillis();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
         doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
         VoiceCallSession expectedCall =
@@ -712,8 +670,6 @@
                 1L << AudioCodec.AUDIO_CODEC_AMR | 1L << AudioCodec.AUDIO_CODEC_EVS_SWB;
         expectedCall.mainCodecQuality =
                 VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
-        expectedCall.callDuration =
-                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_TEN_MINUTES;
 
         mVoiceCallSessionStats0.setTimeMillis(2000L);
         doReturn(Call.State.INCOMING).when(mImsCall0).getState();
@@ -746,10 +702,9 @@
     @Test
     @SmallTest
     public void singleImsCall_ratSwitch() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
-        doReturn(600001L).when(mImsConnection0).getDurationMillis();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
         doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
         VoiceCallSession expectedCall =
@@ -768,8 +723,6 @@
         expectedCall.ratSwitchCount = 2L;
         expectedCall.ratAtEnd = TelephonyManager.NETWORK_TYPE_UMTS;
         expectedCall.bandAtEnd = 0;
-        expectedCall.callDuration =
-                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_THIRTY_MINUTES;
         VoiceCallRatUsage expectedRatUsageLte =
                 makeRatUsageProto(
                         CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 4000L, 1L);
@@ -795,10 +748,10 @@
         doReturn(Call.State.ACTIVE).when(mImsConnection0).getState();
         mVoiceCallSessionStats0.onCallStateChanged(mImsCall0);
         mVoiceCallSessionStats0.setTimeMillis(4000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_HSPA);
+        doReturn(TelephonyManager.NETWORK_TYPE_HSPA).when(mServiceState).getVoiceNetworkType();
         mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
         mVoiceCallSessionStats0.setTimeMillis(6000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_UMTS);
+        doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
         mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
         mVoiceCallSessionStats0.setTimeMillis(8000L);
         mVoiceCallSessionStats0.onImsCallTerminated(
@@ -820,11 +773,10 @@
     @Test
     @SmallTest
     public void singleImsCall_rttOnDial() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
         doReturn(true).when(mImsConnection0).hasRttTextStream();
-        doReturn(1800001L).when(mImsConnection0).getDurationMillis();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
         doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
         VoiceCallSession expectedCall =
@@ -839,8 +791,6 @@
         expectedCall.mainCodecQuality =
                 VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
         expectedCall.rttEnabled = true;
-        expectedCall.callDuration =
-                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_LESS_THAN_ONE_HOUR;
 
         mVoiceCallSessionStats0.setTimeMillis(2000L);
         doReturn(Call.State.INCOMING).when(mImsCall0).getState();
@@ -864,11 +814,10 @@
     @Test
     @SmallTest
     public void singleImsCall_rttStartedMidCall() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
-        doReturn(3600005L).when(mImsConnection0).getDurationMillis();
         doReturn(new ArrayList(List.of(mImsConnection0))).when(mImsCall0).getConnections();
         VoiceCallSession expectedCall =
                 makeSlot0CallProto(
@@ -884,8 +833,6 @@
         expectedCall.mainCodecQuality =
                 VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
         expectedCall.rttEnabled = true;
-        expectedCall.callDuration =
-                VOICE_CALL_SESSION__CALL_DURATION__CALL_DURATION_MORE_THAN_ONE_HOUR;
 
         mVoiceCallSessionStats0.setTimeMillis(2000L);
         doReturn(Call.State.INCOMING).when(mImsCall0).getState();
@@ -917,7 +864,7 @@
     @Test
     @SmallTest
     public void concurrentImsCalls_firstCallHangupFirst() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         // call 0 starts first, MO
         doReturn(false).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
@@ -1011,7 +958,7 @@
         mVoiceCallSessionStats0.onCallStateChanged(mImsCall1);
         // RAT change, LTE to HSPA
         mVoiceCallSessionStats0.setTimeMillis(80000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_HSPA);
+        doReturn(TelephonyManager.NETWORK_TYPE_HSPA).when(mServiceState).getVoiceNetworkType();
         mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
         // call 0 hangup by remote
         mVoiceCallSessionStats0.setTimeMillis(90000L);
@@ -1020,7 +967,7 @@
                 new ImsReasonInfo(ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, 0));
         // RAT change, HSPA to UMTS
         mVoiceCallSessionStats0.setTimeMillis(100000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_UMTS);
+        doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
         mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
         // call 1 hangup by local
         mVoiceCallSessionStats0.setTimeMillis(120000L);
@@ -1045,7 +992,7 @@
     @Test
     @SmallTest
     public void concurrentImsCalls_firstCallHangupLast() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         // call 0 starts first, MO
         doReturn(false).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
@@ -1139,7 +1086,7 @@
         mVoiceCallSessionStats0.onCallStateChanged(mImsCall1);
         // RAT change, LTE to HSPA
         mVoiceCallSessionStats0.setTimeMillis(80000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_HSPA);
+        doReturn(TelephonyManager.NETWORK_TYPE_HSPA).when(mServiceState).getVoiceNetworkType();
         mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
         // call 1 hangup by remote
         mVoiceCallSessionStats0.setTimeMillis(90000L);
@@ -1148,7 +1095,7 @@
                 new ImsReasonInfo(ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE, 0));
         // RAT change, HSPA to UMTS
         mVoiceCallSessionStats0.setTimeMillis(100000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_UMTS);
+        doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
         mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
         // call 0 hangup by local
         mVoiceCallSessionStats0.setTimeMillis(120000L);
@@ -1173,7 +1120,7 @@
     @Test
     @SmallTest
     public void concurrentImsCalls_firstCallHangupDuringSecondCallSetup() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         // call 0 starts first, MO
         doReturn(false).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
@@ -1263,7 +1210,7 @@
         mVoiceCallSessionStats0.onCallStateChanged(mImsCall1);
         // RAT change, LTE to HSPA
         mVoiceCallSessionStats0.setTimeMillis(80000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_HSPA);
+        doReturn(TelephonyManager.NETWORK_TYPE_HSPA).when(mServiceState).getVoiceNetworkType();
         mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
         // call 1 hangup by remote
         mVoiceCallSessionStats0.setTimeMillis(90000L);
@@ -1317,13 +1264,13 @@
         final AtomicReference<VoiceCallRatUsage[]> ratUsage = setupRatUsageCapture();
 
         mVoiceCallSessionStats0.setTimeMillis(2000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(Call.State.DIALING).when(mCsCall0).getState();
         doReturn(Call.State.DIALING).when(mGsmConnection0).getState();
         doReturn(DisconnectCause.NOT_DISCONNECTED).when(mGsmConnection0).getDisconnectCause();
         mVoiceCallSessionStats0.onRilDial(mGsmConnection0);
         mVoiceCallSessionStats0.setTimeMillis(3000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_UMTS);
+        doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
         mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
         mVoiceCallSessionStats0.setTimeMillis(3100L);
         mVoiceCallSessionStats0.onAudioCodecChanged(mGsmConnection0, DriverCall.AUDIO_QUALITY_AMR);
@@ -1366,9 +1313,9 @@
         expectedCall.ratSwitchCount = 1L;
         expectedCall.setupFailed = true;
         expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
-        expectedCall.codecBitmask = 0L;
+        expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
         expectedCall.mainCodecQuality =
-                VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_UNKNOWN;
+                VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
         VoiceCallRatUsage expectedRatUsageLte =
                 makeRatUsageProto(
                         CARRIER_ID_SLOT_0, TelephonyManager.NETWORK_TYPE_LTE, 2000L, 3000L, 1L);
@@ -1378,14 +1325,16 @@
         final AtomicReference<VoiceCallRatUsage[]> ratUsage = setupRatUsageCapture();
 
         mVoiceCallSessionStats0.setTimeMillis(2000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(Call.State.DIALING).when(mCsCall0).getState();
         doReturn(Call.State.DIALING).when(mGsmConnection0).getState();
         doReturn(DisconnectCause.NOT_DISCONNECTED).when(mGsmConnection0).getDisconnectCause();
         mVoiceCallSessionStats0.onRilDial(mGsmConnection0);
         mVoiceCallSessionStats0.setTimeMillis(3000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_UMTS);
+        doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
         mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
+        mVoiceCallSessionStats0.setTimeMillis(3100L);
+        mVoiceCallSessionStats0.onAudioCodecChanged(mGsmConnection0, DriverCall.AUDIO_QUALITY_AMR);
         mVoiceCallSessionStats0.setTimeMillis(15000L);
         doReturn(DisconnectCause.LOST_SIGNAL).when(mGsmConnection0).getDisconnectCause();
         mVoiceCallSessionStats0.onRilCallListChanged(List.of(mGsmConnection0));
@@ -1434,13 +1383,13 @@
         final AtomicReference<VoiceCallRatUsage[]> ratUsage = setupRatUsageCapture();
 
         mVoiceCallSessionStats0.setTimeMillis(2000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(Call.State.DIALING).when(mCsCall0).getState();
         doReturn(Call.State.DIALING).when(mGsmConnection0).getState();
         doReturn(DisconnectCause.NOT_DISCONNECTED).when(mGsmConnection0).getDisconnectCause();
         mVoiceCallSessionStats0.onRilDial(mGsmConnection0);
         mVoiceCallSessionStats0.setTimeMillis(3000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_UMTS);
+        doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
         mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
         mVoiceCallSessionStats0.setTimeMillis(3100L);
         mVoiceCallSessionStats0.onAudioCodecChanged(mGsmConnection0, DriverCall.AUDIO_QUALITY_AMR);
@@ -1471,7 +1420,7 @@
     @Test
     @SmallTest
     public void singleCsCall_mtRejected() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_UMTS);
+        doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mGsmConnection0).isIncoming();
         doReturn(2000L).when(mGsmConnection0).getCreateTime();
         doReturn(mCsCall0).when(mGsmConnection0).getCall();
@@ -1488,8 +1437,7 @@
         expectedCall.setupFailed = true;
         expectedCall.ratAtConnected = TelephonyManager.NETWORK_TYPE_UNKNOWN;
         expectedCall.bandAtEnd = 0;
-        expectedCall.codecBitmask =
-                (1L << AudioCodec.AUDIO_CODEC_AMR) | (1L << AudioCodec.AUDIO_CODEC_AMR_WB);
+        expectedCall.codecBitmask = 1L << AudioCodec.AUDIO_CODEC_AMR;
         expectedCall.mainCodecQuality =
                 VOICE_CALL_SESSION__MAIN_CODEC_QUALITY__CODEC_QUALITY_NARROWBAND;
         VoiceCallRatUsage expectedRatUsage =
@@ -1502,12 +1450,10 @@
         mVoiceCallSessionStats0.setTimeMillis(2500L);
         doReturn(Call.State.INCOMING).when(mCsCall0).getState();
         doReturn(Call.State.INCOMING).when(mGsmConnection0).getState();
-        doReturn(DriverCall.AUDIO_QUALITY_AMR_WB).when(mGsmConnection0).getAudioCodec();
         doReturn(DisconnectCause.NOT_DISCONNECTED).when(mGsmConnection0).getDisconnectCause();
         mVoiceCallSessionStats0.onRilCallListChanged(List.of(mGsmConnection0));
         mVoiceCallSessionStats0.setTimeMillis(3000L);
         mVoiceCallSessionStats0.onAudioCodecChanged(mGsmConnection0, DriverCall.AUDIO_QUALITY_AMR);
-        doReturn(DriverCall.AUDIO_QUALITY_AMR).when(mGsmConnection0).getAudioCodec();
         mVoiceCallSessionStats0.setTimeMillis(15000L);
         doReturn(DisconnectCause.NORMAL).when(mGsmConnection0).getDisconnectCause();
         doReturn(PreciseDisconnectCause.CALL_REJECTED)
@@ -1528,7 +1474,7 @@
     @Test
     @SmallTest
     public void singleCsCall_mtAccepted() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_UMTS);
+        doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mGsmConnection0).isIncoming();
         doReturn(2000L).when(mGsmConnection0).getCreateTime();
         doReturn(mCsCall0).when(mGsmConnection0).getCall();
@@ -1585,7 +1531,7 @@
     @Test
     @SmallTest
     public void singleCall_srvccFailed() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
@@ -1634,7 +1580,7 @@
         mVoiceCallSessionStats0.onRilSrvccStateChanged(
                 TelephonyManager.SRVCC_STATE_HANDOVER_STARTED);
         mVoiceCallSessionStats0.setTimeMillis(10000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_UMTS);
+        doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
         mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
         mVoiceCallSessionStats0.setTimeMillis(11000L);
         mVoiceCallSessionStats0.onRilSrvccStateChanged(
@@ -1663,7 +1609,7 @@
     @Test
     @SmallTest
     public void singleCall_srvccCanceled() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
@@ -1731,7 +1677,7 @@
     @Test
     @SmallTest
     public void singleCall_srvccSuccess() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
@@ -1795,7 +1741,7 @@
         mVoiceCallSessionStats0.onRilSrvccStateChanged(
                 TelephonyManager.SRVCC_STATE_HANDOVER_STARTED);
         mVoiceCallSessionStats0.setTimeMillis(7000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_UMTS);
+        doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
         mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
         mVoiceCallSessionStats0.setTimeMillis(8000L);
         mVoiceCallSessionStats0.onRilSrvccStateChanged(
@@ -1824,11 +1770,10 @@
     @Test
     @SmallTest
     public void concurrentCalls_srvcc() {
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
         doReturn(mImsPhone).when(mPhone).getImsPhone();
         doReturn(new ArrayList(List.of(mImsConnection0, mImsConnection1)))
-                .when(mImsPhone)
-                .getHandoverConnection();
+                .when(mImsPhone).getHandoverConnection();
         // call 0 starts first, MO
         doReturn(false).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
@@ -1929,7 +1874,7 @@
                 TelephonyManager.SRVCC_STATE_HANDOVER_STARTED);
         // RAT change, LTE to UMTS
         mVoiceCallSessionStats0.setTimeMillis(80000L);
-        setServiceState(mServiceState, TelephonyManager.NETWORK_TYPE_UMTS);
+        doReturn(TelephonyManager.NETWORK_TYPE_UMTS).when(mServiceState).getVoiceNetworkType();
         mVoiceCallSessionStats0.onServiceStateChanged(mServiceState);
         mVoiceCallSessionStats0.setTimeMillis(85000L);
         mVoiceCallSessionStats0.onRilSrvccStateChanged(
@@ -1961,9 +1906,10 @@
     @Test
     @SmallTest
     public void singleWifiCall_preferred() {
-        setServiceStateWithWifiCalling(mServiceState, TelephonyManager.NETWORK_TYPE_LTE);
+        doReturn(TelephonyManager.NETWORK_TYPE_LTE).when(mServiceState).getVoiceNetworkType();
+        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mServiceState).getDataNetworkType();
         doReturn(mImsPhone).when(mPhone).getImsPhone();
-        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech();
+        doReturn(true).when(mImsPhone).isWifiCallingEnabled();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
@@ -2009,9 +1955,10 @@
     @Test
     @SmallTest
     public void singleWifiCall_airPlaneMode() {
-        setServiceStateWithWifiCalling(mServiceState, TelephonyManager.NETWORK_TYPE_UNKNOWN);
+        doReturn(TelephonyManager.NETWORK_TYPE_UNKNOWN).when(mServiceState).getVoiceNetworkType();
+        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mServiceState).getDataNetworkType();
         doReturn(mImsPhone).when(mPhone).getImsPhone();
-        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mImsStats).getImsVoiceRadioTech();
+        doReturn(true).when(mImsPhone).isWifiCallingEnabled();
         doReturn(true).when(mImsConnection0).isIncoming();
         doReturn(2000L).when(mImsConnection0).getCreateTime();
         doReturn(mImsCall0).when(mImsConnection0).getCall();
@@ -2056,59 +2003,14 @@
 
     private AtomicReference<VoiceCallRatUsage[]> setupRatUsageCapture() {
         final AtomicReference<VoiceCallRatUsage[]> ratUsage = new AtomicReference<>(null);
-        doAnswer(
-                invocation -> {
-                        VoiceCallRatTracker tracker =
-                                    (VoiceCallRatTracker) invocation.getArguments()[0];
-                        ratUsage.set(tracker.toProto());
-                        return null; // for void
-                })
-                .when(mPersistAtomsStorage)
-                .addVoiceCallRatUsage(any());
+        doAnswer(invocation -> {
+            VoiceCallRatTracker tracker = (VoiceCallRatTracker) invocation.getArguments()[0];
+            ratUsage.set(tracker.toProto());
+            return null; // for void
+        }).when(mPersistAtomsStorage).addVoiceCallRatUsage(any());
         return ratUsage;
     }
 
-    private static void setServiceState(ServiceState mock, @NetworkType int rat) {
-        doReturn(rat).when(mock).getVoiceNetworkType();
-        doReturn(rat).when(mock).getDataNetworkType();
-        NetworkRegistrationInfo regInfo =
-                new NetworkRegistrationInfo.Builder()
-                        .setAccessNetworkTechnology(rat)
-                        .setRegistrationState(
-                                rat == TelephonyManager.NETWORK_TYPE_UNKNOWN
-                                        ? NetworkRegistrationInfo
-                                                .REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING
-                                        : NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                        .build();
-        doReturn(regInfo).when(mock)
-                .getNetworkRegistrationInfo(
-                        anyInt(), eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
-    }
-
-    private static void setServiceStateWithWifiCalling(ServiceState mock, @NetworkType int rat) {
-        doReturn(rat).when(mock).getVoiceNetworkType();
-        doReturn(TelephonyManager.NETWORK_TYPE_IWLAN).when(mock).getDataNetworkType();
-        NetworkRegistrationInfo wwanRegInfo =
-                new NetworkRegistrationInfo.Builder()
-                        .setAccessNetworkTechnology(rat)
-                        .setRegistrationState(
-                                rat == TelephonyManager.NETWORK_TYPE_UNKNOWN
-                                        ? NetworkRegistrationInfo
-                                                .REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING
-                                        : NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
-                        .build();
-        doReturn(wwanRegInfo).when(mock)
-                .getNetworkRegistrationInfo(
-                        anyInt(), eq(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
-        NetworkRegistrationInfo wlanRegInfo =
-                new NetworkRegistrationInfo.Builder()
-                        .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_IWLAN).build();
-        doReturn(wlanRegInfo).when(mock)
-                .getNetworkRegistrationInfo(
-                        eq(NetworkRegistrationInfo.DOMAIN_PS),
-                        eq(AccessNetworkConstants.TRANSPORT_TYPE_WLAN));
-    }
-
     private static VoiceCallSession makeSlot0CallProto(
             int bearer, int direction, int rat, int reason) {
         VoiceCallSession call = new VoiceCallSession();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactoryTest.java b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactoryTest.java
index ddc24da..2339f08 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactoryTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzSignalInputFilterPredicateFactoryTest.java
@@ -19,17 +19,16 @@
 import static com.android.internal.telephony.nitz.NitzSignalInputFilterPredicateFactory.createBogusElapsedRealtimeCheck;
 import static com.android.internal.telephony.nitz.NitzSignalInputFilterPredicateFactory.createIgnoreNitzPropertyCheck;
 import static com.android.internal.telephony.nitz.NitzSignalInputFilterPredicateFactory.createRateLimitCheck;
-import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.ARBITRARY_AGE;
 import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.UNIQUE_US_ZONE_SCENARIO1;
 
-import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
+import android.os.TimestampedValue;
+
 import com.android.internal.telephony.NitzData;
-import com.android.internal.telephony.NitzSignal;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.nitz.NitzSignalInputFilterPredicateFactory.NitzSignalInputFilterPredicateImpl;
 import com.android.internal.telephony.nitz.NitzSignalInputFilterPredicateFactory.TrivalentPredicate;
@@ -46,21 +45,20 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
+        super.setUp("NitzSignalInputFilterPredicateFactoryTest");
         mFakeDeviceState = new FakeDeviceState();
     }
 
     @After
     public void tearDown() throws Exception {
-        mFakeDeviceState = null;
         super.tearDown();
     }
 
     @Test
     public void testNitzSignalInputFilterPredicateImpl_nullSecondArgumentRejected() {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        NitzSignal nitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> nitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
         TrivalentPredicate[] triPredicates = {};
         NitzSignalInputFilterPredicateImpl impl =
                 new NitzSignalInputFilterPredicateImpl(triPredicates);
@@ -74,8 +72,8 @@
     @Test
     public void testNitzSignalInputFilterPredicateImpl_defaultIsTrue() {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        NitzSignal nitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> nitzSignal = scenario
+                .createNitzSignal(mFakeDeviceState.elapsedRealtime());
         NitzSignalInputFilterPredicateImpl impl =
                 new NitzSignalInputFilterPredicateImpl(new TrivalentPredicate[0]);
         assertTrue(impl.mustProcessNitzSignal(null, nitzSignal));
@@ -84,8 +82,8 @@
     @Test
     public void testNitzSignalInputFilterPredicateImpl_nullIsIgnored() {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        NitzSignal nitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> nitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
         TrivalentPredicate nullPredicate = (x, y) -> null;
         TrivalentPredicate[] triPredicates = { nullPredicate };
         NitzSignalInputFilterPredicateImpl impl =
@@ -96,8 +94,8 @@
     @Test
     public void testNitzSignalInputFilterPredicateImpl_trueIsHonored() {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        NitzSignal nitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> nitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
         TrivalentPredicate nullPredicate = (x, y) -> null;
         TrivalentPredicate truePredicate = (x, y) -> true;
         TrivalentPredicate exceptionPredicate = (x, y) -> {
@@ -116,8 +114,8 @@
     @Test
     public void testNitzSignalInputFilterPredicateImpl_falseIsHonored() {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        NitzSignal nitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> nitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
         TrivalentPredicate nullPredicate = (x, y) -> null;
         TrivalentPredicate falsePredicate = (x, y) -> false;
         TrivalentPredicate exceptionPredicate = (x, y) -> {
@@ -147,42 +145,24 @@
     @Test
     public void testTrivalentPredicate_bogusElapsedRealtimeCheck() {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        long elapsedRealtimeMillis = mFakeDeviceState.elapsedRealtimeMillis();
-        NitzSignal baseNitzSignal =
-                scenario.createNitzSignal(elapsedRealtimeMillis, ARBITRARY_AGE);
+        long elapsedRealtimeClock = mFakeDeviceState.elapsedRealtime();
+        TimestampedValue<NitzData> nitzSignal = scenario.createNitzSignal(elapsedRealtimeClock);
 
         TrivalentPredicate triPredicate =
                 createBogusElapsedRealtimeCheck(mContext, mFakeDeviceState);
-        assertNull(triPredicate.mustProcessNitzSignal(null, baseNitzSignal));
+        assertNull(triPredicate.mustProcessNitzSignal(null, nitzSignal));
 
         // Any signal that claims to be from the future must be rejected.
-        {
-            long receiptElapsedMillis = elapsedRealtimeMillis + 1;
-            long ageMillis = 0;
-            NitzSignal bogusNitzSignal = new NitzSignal(
-                    receiptElapsedMillis, baseNitzSignal.getNitzData(), ageMillis);
-            assertFalse(triPredicate.mustProcessNitzSignal(null, bogusNitzSignal));
-        }
-
-        // Age should be ignored: the predicate is intended to check receipt time isn't obviously
-        // corrupt / fabricated to be in the future. Larger ages could imply that the NITZ was
-        // received by the modem before the elapsed realtime clock started ticking, but we don't
-        // currently check for that.
-        {
-            long receiptElapsedMillis = elapsedRealtimeMillis + 1;
-            long ageMillis = 10000;
-            NitzSignal bogusNitzSignal = new NitzSignal(
-                    receiptElapsedMillis, baseNitzSignal.getNitzData(), ageMillis);
-
-            assertFalse(triPredicate.mustProcessNitzSignal(null, bogusNitzSignal));
-        }
+        TimestampedValue<NitzData> bogusNitzSignal = new TimestampedValue<>(
+                elapsedRealtimeClock + 1, nitzSignal.getValue());
+        assertFalse(triPredicate.mustProcessNitzSignal(null, bogusNitzSignal));
     }
 
     @Test
     public void testTrivalentPredicate_noOldSignalCheck() {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        NitzSignal nitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> nitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
 
         TrivalentPredicate triPredicate =
                 NitzSignalInputFilterPredicateFactory.createNoOldSignalCheck();
@@ -191,108 +171,36 @@
     }
 
     @Test
-    public void testTrivalentPredicate_rateLimitCheck_elapsedRealtime_zeroAge() {
+    public void testTrivalentPredicate_rateLimitCheck_elapsedRealtime() {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
         int nitzSpacingThreshold = mFakeDeviceState.getNitzUpdateSpacingMillis();
-        // Change the other setting that can affect the predicate behavior so it is not a factor in
-        // the test.
-        mFakeDeviceState.setNitzUpdateDiffMillis(Integer.MAX_VALUE);
+        NitzData baseNitzData = scenario.createNitzData();
 
         TrivalentPredicate triPredicate = createRateLimitCheck(mFakeDeviceState);
 
-        long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtimeMillis();
-        NitzData baseNitzData = scenario.createNitzData();
-        int baseAgeMillis = 0;
-        NitzSignal baseNitzSignal =
-                new NitzSignal(baseElapsedRealtimeMillis, baseNitzData, baseAgeMillis);
+        long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtime();
+        TimestampedValue<NitzData> baseSignal =
+                new TimestampedValue<>(baseElapsedRealtimeMillis, baseNitzData);
 
         // Two identical signals: no spacing so the new signal should not be processed.
-        assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, baseNitzSignal));
-
-        // Two signals not spaced apart enough in receipt time: the new signal should not be
-        // processed.
         {
-            int timeAdjustment = nitzSpacingThreshold - 1;
-            int unixTimeAdjustment = 0;
-            long ageAdjustment = 0;
-            NitzSignal newSignal = createAdjustedNitzSignal(
-                    baseNitzSignal, timeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, newSignal));
+            assertFalse(triPredicate.mustProcessNitzSignal(baseSignal, baseSignal));
+        }
+
+        // Two signals not spaced apart enough: the new signal should not processed.
+        {
+            int elapsedTimeIncrement = nitzSpacingThreshold - 1;
+            TimestampedValue<NitzData> newSignal =
+                    createIncrementedNitzSignal(baseSignal, elapsedTimeIncrement);
+            assertFalse(triPredicate.mustProcessNitzSignal(baseSignal, newSignal));
         }
 
         // Two signals spaced apart: the new signal should be processed.
         {
-            int timeAdjustment = nitzSpacingThreshold + 1;
-            int unixTimeAdjustment = 0;
-            long ageAdjustment = 0;
-            NitzSignal newSignal = createAdjustedNitzSignal(
-                    baseNitzSignal, timeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, newSignal));
-        }
-    }
-
-    @Test
-    public void testTrivalentPredicate_rateLimitCheck_elapsedRealtime_withAge() {
-        Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        int nitzSpacingThreshold = 60000;
-        mFakeDeviceState.setNitzUpdateSpacingMillis(nitzSpacingThreshold);
-
-        // Change the other setting that can affect the predicate behavior so it is not a factor in
-        // the test.
-        mFakeDeviceState.setNitzUpdateDiffMillis(Integer.MAX_VALUE);
-
-        TrivalentPredicate triPredicate = createRateLimitCheck(mFakeDeviceState);
-
-        // Create a NITZ signal to be the first of two NITZ signals received.
-        long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtimeMillis();
-        NitzData baseNitzData = scenario.createNitzData();
-        int baseAgeMillis = 20000;
-        NitzSignal baseNitzSignal =
-                new NitzSignal(baseElapsedRealtimeMillis, baseNitzData, baseAgeMillis);
-
-        // Two identical signals: no spacing so the new signal should not be processed.
-        assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, baseNitzSignal));
-
-        // Two signals not spaced apart enough: the new signal should not be processed.
-        // The age is changed to prove it doesn't affect this check.
-        {
-            int elapsedRealtimeAdjustment = nitzSpacingThreshold - 1;
-            int unixTimeAdjustment = 0;
-            long ageAdjustment = 10000;
-            NitzSignal newSignal = createAdjustedNitzSignal(
-                    baseNitzSignal, elapsedRealtimeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, newSignal));
-        }
-
-        // Two signals not spaced apart enough: the new signal should not be processed.
-        // The age is changed to prove it doesn't affect this check.
-        {
-            int elapsedRealtimeAdjustment = nitzSpacingThreshold - 1;
-            int unixTimeAdjustment = 0;
-            long ageAdjustment = -10000;
-            NitzSignal newSignal = createAdjustedNitzSignal(
-                    baseNitzSignal, elapsedRealtimeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, newSignal));
-        }
-
-        // Two signals spaced far enough apart: the new signal should be processed.
-        {
-            int elapsedRealtimeAdjustment = nitzSpacingThreshold + 1;
-            int unixTimeAdjustment = 0;
-            long ageAdjustment = 10000;
-            NitzSignal newSignal = createAdjustedNitzSignal(
-                    baseNitzSignal, elapsedRealtimeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, newSignal));
-        }
-
-        // Two signals spaced far enough apart: the new signal should be processed.
-        {
-            int elapsedRealtimeAdjustment = nitzSpacingThreshold + 1;
-            int unixTimeAdjustment = 0;
-            long ageAdjustment = -10000;
-            NitzSignal newSignal = createAdjustedNitzSignal(
-                    baseNitzSignal, elapsedRealtimeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, newSignal));
+            int elapsedTimeIncrement = nitzSpacingThreshold + 1;
+            TimestampedValue<NitzData> newSignal =
+                    createIncrementedNitzSignal(baseSignal, elapsedTimeIncrement);
+            assertTrue(triPredicate.mustProcessNitzSignal(baseSignal, newSignal));
         }
     }
 
@@ -300,23 +208,20 @@
     public void testTrivalentPredicate_rateLimitCheck_offsetDifference() {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
         int nitzSpacingThreshold = mFakeDeviceState.getNitzUpdateSpacingMillis();
+        NitzData baseNitzData = scenario.createNitzData();
 
         TrivalentPredicate triPredicate = createRateLimitCheck(mFakeDeviceState);
 
-        long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtimeMillis();
-        NitzData baseNitzData = scenario.createNitzData();
-        long baseAgeMillis = 0;
-        NitzSignal baseNitzSignal = new NitzSignal(
-                baseElapsedRealtimeMillis, baseNitzData, baseAgeMillis);
+        long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtime();
+        TimestampedValue<NitzData> baseSignal =
+                new TimestampedValue<>(baseElapsedRealtimeMillis, baseNitzData);
 
-        // Create a new NitzSignal that would normally be filtered.
-        int timeAdjustment = nitzSpacingThreshold - 1;
-        long ageAdjustment = 0;
-        NitzSignal intermediateNitzSignal = createAdjustedNitzSignal(
-                baseNitzSignal, timeAdjustment, timeAdjustment, ageAdjustment);
-        NitzData intermediateNitzData = intermediateNitzSignal.getNitzData();
-        assertAgeAdjustedUnixEpochTimeIsIdentical(baseNitzSignal, intermediateNitzSignal);
-        assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, intermediateNitzSignal));
+        // Create a new NitzSignal that should be filtered.
+        int elapsedTimeIncrement = nitzSpacingThreshold - 1;
+        TimestampedValue<NitzData> intermediateNitzSignal =
+                createIncrementedNitzSignal(baseSignal, elapsedTimeIncrement);
+        NitzData intermediateNitzData = intermediateNitzSignal.getValue();
+        assertFalse(triPredicate.mustProcessNitzSignal(baseSignal, intermediateNitzSignal));
 
         // Two signals spaced apart so that the second would be filtered, but they contain different
         // offset information so should be detected as "different" and processed.
@@ -327,181 +232,102 @@
                     intermediateNitzData.getDstAdjustmentMillis(),
                     intermediateNitzData.getCurrentTimeInMillis(),
                     intermediateNitzData.getEmulatorHostTimeZone());
-            NitzSignal differentOffsetSignal = new NitzSignal(
-                    baseNitzSignal.getReceiptElapsedRealtimeMillis() + timeAdjustment,
-                    differentOffsetNitzData,
-                    baseNitzSignal.getAgeMillis());
-            assertAgeAdjustedUnixEpochTimeIsIdentical(baseNitzSignal, differentOffsetSignal);
-            assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, differentOffsetSignal));
+            TimestampedValue<NitzData> differentOffsetSignal = new TimestampedValue<>(
+                    baseSignal.getReferenceTimeMillis() + elapsedTimeIncrement,
+                    differentOffsetNitzData);
+            assertTrue(triPredicate.mustProcessNitzSignal(baseSignal, differentOffsetSignal));
         }
     }
 
     @Test
-    public void testTrivalentPredicate_rateLimitCheck_unixEpochTimeDifferences_withZeroAge() {
+    public void testTrivalentPredicate_rateLimitCheck_utcTimeDifferences() {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        // Change the other setting that can affect the predicate behavior so it is not a factor in
-        // the test.
-        mFakeDeviceState.setNitzUpdateSpacingMillis(Integer.MAX_VALUE);
-        int nitzUnixDiffThreshold = mFakeDeviceState.getNitzUpdateDiffMillis();
+        int nitzSpacingThreshold = mFakeDeviceState.getNitzUpdateSpacingMillis();
+        int nitzUtcDiffThreshold = mFakeDeviceState.getNitzUpdateDiffMillis();
+        NitzData baseNitzData = scenario.createNitzData();
 
         TrivalentPredicate triPredicate = createRateLimitCheck(mFakeDeviceState);
 
-        long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtimeMillis();
-        NitzData baseNitzData = scenario.createNitzData();
-        int baseAgeMillis = 0;
-        NitzSignal baseNitzSignal =
-                new NitzSignal(baseElapsedRealtimeMillis, baseNitzData, baseAgeMillis);
+        long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtime();
+        TimestampedValue<NitzData> baseSignal =
+                new TimestampedValue<>(baseElapsedRealtimeMillis, baseNitzData);
 
-        // Two signals spaced contain Unix epoch times that are not sufficiently different and so
-        // should be filtered.
+        // Create a new NitzSignal that should be filtered.
+        int elapsedTimeIncrement = nitzSpacingThreshold - 1;
+        TimestampedValue<NitzData> intermediateSignal =
+                createIncrementedNitzSignal(baseSignal, elapsedTimeIncrement);
+        NitzData intermediateNitzData = intermediateSignal.getValue();
+        assertFalse(triPredicate.mustProcessNitzSignal(baseSignal, intermediateSignal));
+
+        // Two signals spaced apart so that the second would normally be filtered and it contains
+        // a UTC time that is not sufficiently different.
         {
-            int elapsedRealtimeAdjustment = 0;
-            int unixTimeAdjustment = nitzUnixDiffThreshold - 1;
-            long ageAdjustment = 0;
-            NitzSignal nitzSignal = createAdjustedNitzSignal(baseNitzSignal,
-                    elapsedRealtimeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
+            NitzData incrementedUtcTimeNitzData = NitzData.createForTests(
+                    intermediateNitzData.getLocalOffsetMillis(),
+                    intermediateNitzData.getDstAdjustmentMillis(),
+                    intermediateNitzData.getCurrentTimeInMillis() + nitzUtcDiffThreshold - 1,
+                    intermediateNitzData.getEmulatorHostTimeZone());
+
+            TimestampedValue<NitzData> incrementedNitzSignal = new TimestampedValue<>(
+                    intermediateSignal.getReferenceTimeMillis(), incrementedUtcTimeNitzData);
+            assertFalse(triPredicate.mustProcessNitzSignal(baseSignal, incrementedNitzSignal));
         }
 
-        // Two signals spaced contain Unix epoch times that are not sufficiently different and so
-        // should be filtered.
+        // Two signals spaced apart so that the second would normally be filtered but it contains
+        // a UTC time that is sufficiently different.
         {
-            int elapsedRealtimeAdjustment = 0;
-            int unixTimeAdjustment = -(nitzUnixDiffThreshold - 1);
-            long ageAdjustment = 0;
-            NitzSignal nitzSignal = createAdjustedNitzSignal(baseNitzSignal,
-                    elapsedRealtimeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
+            NitzData incrementedUtcTimeNitzData = NitzData.createForTests(
+                    intermediateNitzData.getLocalOffsetMillis(),
+                    intermediateNitzData.getDstAdjustmentMillis(),
+                    intermediateNitzData.getCurrentTimeInMillis() + nitzUtcDiffThreshold + 1,
+                    intermediateNitzData.getEmulatorHostTimeZone());
+
+            TimestampedValue<NitzData> incrementedNitzSignal = new TimestampedValue<>(
+                    intermediateSignal.getReferenceTimeMillis(), incrementedUtcTimeNitzData);
+            assertTrue(triPredicate.mustProcessNitzSignal(baseSignal, incrementedNitzSignal));
         }
 
-        // Two signals spaced contain Unix epoch times that are sufficiently different and so should
-        // not be filtered.
+        // Two signals spaced apart so that the second would normally be filtered and it contains
+        // a UTC time that is not sufficiently different.
         {
-            int elapsedRealtimeAdjustment = 0;
-            int unixTimeAdjustment = nitzUnixDiffThreshold + 1;
-            long ageAdjustment = 0;
-            NitzSignal nitzSignal = createAdjustedNitzSignal(baseNitzSignal,
-                    elapsedRealtimeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
+            NitzData decrementedUtcTimeNitzData = NitzData.createForTests(
+                    intermediateNitzData.getLocalOffsetMillis(),
+                    intermediateNitzData.getDstAdjustmentMillis(),
+                    intermediateNitzData.getCurrentTimeInMillis() - nitzUtcDiffThreshold + 1,
+                    intermediateNitzData.getEmulatorHostTimeZone());
+
+            TimestampedValue<NitzData> decrementedNitzSignal = new TimestampedValue<>(
+                    intermediateSignal.getReferenceTimeMillis(), decrementedUtcTimeNitzData);
+            assertFalse(triPredicate.mustProcessNitzSignal(baseSignal, decrementedNitzSignal));
         }
 
-        // Two signals spaced contain Unix epoch times that are sufficiently different and so should
-        // not be filtered.
+        // Two signals spaced apart so that the second would normally be filtered but it contains
+        // a UTC time that is sufficiently different.
         {
-            int elapsedRealtimeAdjustment = 0;
-            int unixTimeAdjustment = -(nitzUnixDiffThreshold + 1);
-            long ageAdjustment = 0;
-            NitzSignal nitzSignal = createAdjustedNitzSignal(baseNitzSignal,
-                    elapsedRealtimeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
-        }
-    }
+            NitzData decrementedUtcTimeNitzData = NitzData.createForTests(
+                    intermediateNitzData.getLocalOffsetMillis(),
+                    intermediateNitzData.getDstAdjustmentMillis(),
+                    intermediateNitzData.getCurrentTimeInMillis() + nitzUtcDiffThreshold + 1,
+                    intermediateNitzData.getEmulatorHostTimeZone());
 
-    @Test
-    public void testTrivalentPredicate_rateLimitCheck_unixEpochTimeDifferences_withAge() {
-        Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        // Change the other setting that can affect the predicate behavior so it is not a factor in
-        // the test.
-        mFakeDeviceState.setNitzUpdateSpacingMillis(Integer.MAX_VALUE);
-        int nitzUnixDiffThreshold = mFakeDeviceState.getNitzUpdateDiffMillis();
-
-        TrivalentPredicate triPredicate = createRateLimitCheck(mFakeDeviceState);
-
-        long baseElapsedRealtimeMillis = mFakeDeviceState.elapsedRealtimeMillis();
-        NitzData baseNitzData = scenario.createNitzData();
-        int baseAgeMillis = 20000;
-        NitzSignal baseNitzSignal =
-                new NitzSignal(baseElapsedRealtimeMillis, baseNitzData, baseAgeMillis);
-
-        // This is another NitzSignal that represents the same time as baseNitzSignal, but it has
-        // been cached by the modem for a different amount of time, so has different values even
-        // though it encodes for the same Unix epoch time. Used to construct test signals below.
-        int intermediateSignalAgeAdjustment = -10000;
-        int intermediateUnixTimeAdjustment = 0;
-        NitzSignal intermediateNitzSignal = createAdjustedNitzSignal(baseNitzSignal,
-                intermediateSignalAgeAdjustment, intermediateUnixTimeAdjustment,
-                intermediateSignalAgeAdjustment);
-        assertAgeAdjustedUnixEpochTimeIsIdentical(baseNitzSignal, intermediateNitzSignal);
-
-        // Two signals spaced contain Unix epoch times that are not sufficiently different and so
-        // should be filtered.
-        {
-            int elapsedRealtimeAdjustment = 0;
-            int unixTimeAdjustment = nitzUnixDiffThreshold - 1;
-            long ageAdjustment = 0;
-            NitzSignal nitzSignal = createAdjustedNitzSignal(intermediateNitzSignal,
-                    elapsedRealtimeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
-        }
-
-        // Two signals spaced contain Unix epoch times that are not sufficiently different and so
-        // should be filtered.
-        {
-            int elapsedRealtimeAdjustment = 0;
-            int unixTimeAdjustment = -(nitzUnixDiffThreshold - 1);
-            long ageAdjustment = 0;
-            NitzSignal nitzSignal = createAdjustedNitzSignal(intermediateNitzSignal,
-                    elapsedRealtimeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertFalse(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
-        }
-
-        // Two signals spaced contain Unix epoch times that are sufficiently different and so should
-        // not be filtered.
-        {
-            int elapsedRealtimeAdjustment = 0;
-            int unixTimeAdjustment = nitzUnixDiffThreshold + 1;
-            long ageAdjustment = 0;
-            NitzSignal nitzSignal = createAdjustedNitzSignal(intermediateNitzSignal,
-                    elapsedRealtimeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
-        }
-
-        // Two signals spaced contain Unix epoch times that are sufficiently different and so should
-        // not be filtered.
-        {
-            int elapsedRealtimeAdjustment = 0;
-            int unixTimeAdjustment = -(nitzUnixDiffThreshold + 1);
-            long ageAdjustment = 0;
-            NitzSignal nitzSignal = createAdjustedNitzSignal(intermediateNitzSignal,
-                    elapsedRealtimeAdjustment, unixTimeAdjustment, ageAdjustment);
-            assertTrue(triPredicate.mustProcessNitzSignal(baseNitzSignal, nitzSignal));
+            TimestampedValue<NitzData> decrementedNitzSignal = new TimestampedValue<>(
+                    intermediateSignal.getReferenceTimeMillis(), decrementedUtcTimeNitzData);
+            assertTrue(triPredicate.mustProcessNitzSignal(baseSignal, decrementedNitzSignal));
         }
     }
 
     /**
-     * Creates an NITZ signal based on the supplied signal but with all the fields associated with
-     * the time (receipt time, Unix epoch and age) adjusted by the specified amounts.
+     * Creates an NITZ signal based on the the supplied signal but with all the fields related to
+     * elapsed time incremented by the specified number of milliseconds.
      */
-    private static NitzSignal createAdjustedNitzSignal(
-            NitzSignal baseNitzSignal, int elapsedRealtimeMillisAdjustment,
-            int unixMillisAdjustment, long ageMillisAdjustment) {
-        long adjustedReceiptElapsedMillis =
-                baseNitzSignal.getReceiptElapsedRealtimeMillis() + elapsedRealtimeMillisAdjustment;
-        NitzData adjustedNitzData =
-                createAdjustedNitzData(baseNitzSignal.getNitzData(), unixMillisAdjustment);
-        long adjustedAgeMillis = baseNitzSignal.getAgeMillis() + ageMillisAdjustment;
-        return new NitzSignal(adjustedReceiptElapsedMillis, adjustedNitzData, adjustedAgeMillis);
-    }
-
-    /** Creates a new NitzData by adjusting the Unix epoch time in the supplied NitzData */
-    private static NitzData createAdjustedNitzData(NitzData baseData, int unixMillisAdjustment) {
-        return NitzData.createForTests(
-                baseData.getLocalOffsetMillis(),
-                baseData.getDstAdjustmentMillis(),
-                baseData.getCurrentTimeInMillis() + unixMillisAdjustment,
-                baseData.getEmulatorHostTimeZone());
-    }
-
-    /**
-     * Used during tests to confirm that two NitzSignal test objects represent the same Unix epoch
-     * time, even though their receipt times and ages may differ.
-     */
-    private static void assertAgeAdjustedUnixEpochTimeIsIdentical(
-            NitzSignal signal1, NitzSignal signal2) {
-        long referenceTimeDifference = signal2.getAgeAdjustedElapsedRealtimeMillis()
-                - signal1.getAgeAdjustedElapsedRealtimeMillis();
-        long unixEpochTimeDifference = signal2.getNitzData().getCurrentTimeInMillis()
-                - signal1.getNitzData().getCurrentTimeInMillis();
-        assertEquals(referenceTimeDifference, unixEpochTimeDifference);
+    private static TimestampedValue<NitzData> createIncrementedNitzSignal(
+            TimestampedValue<NitzData> baseSignal, int incrementMillis) {
+        NitzData baseData = baseSignal.getValue();
+        return new TimestampedValue<>(baseSignal.getReferenceTimeMillis() + incrementMillis,
+                NitzData.createForTests(
+                        baseData.getLocalOffsetMillis(),
+                        baseData.getDstAdjustmentMillis(),
+                        baseData.getCurrentTimeInMillis() + incrementMillis,
+                        baseData.getEmulatorHostTimeZone()));
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineImplTest.java b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineImplTest.java
index 98e27cb..c433bd0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineImplTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineImplTest.java
@@ -19,7 +19,6 @@
 import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY;
 import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
 
-import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.ARBITRARY_AGE;
 import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.ARBITRARY_SYSTEM_CLOCK_TIME;
 import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.UNIQUE_US_ZONE_SCENARIO1;
 import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.UNITED_KINGDOM_SCENARIO;
@@ -36,9 +35,11 @@
 
 import android.app.timedetector.TelephonyTimeSuggestion;
 import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
+import android.os.TimestampedValue;
 
 import com.android.internal.telephony.IndentingPrintWriter;
-import com.android.internal.telephony.NitzSignal;
+import com.android.internal.telephony.NitzData;
+import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.nitz.NitzStateMachineImpl.NitzSignalInputFilterPredicate;
 import com.android.internal.telephony.nitz.NitzStateMachineTestSupport.FakeDeviceState;
 import com.android.internal.telephony.nitz.NitzStateMachineTestSupport.Scenario;
@@ -51,7 +52,8 @@
 import java.util.LinkedList;
 import java.util.concurrent.TimeUnit;
 
-public class NitzStateMachineImplTest {
+public class NitzStateMachineImplTest extends TelephonyTest {
+
     private static final int SLOT_INDEX = 99999;
     private static final TelephonyTimeZoneSuggestion EMPTY_TIME_ZONE_SUGGESTION =
             createEmptyTimeZoneSuggestion(SLOT_INDEX);
@@ -61,11 +63,15 @@
     private FakeTimeServiceHelper mFakeTimeServiceHelper;
     private FakeDeviceState mFakeDeviceState;
     private TimeZoneSuggesterImpl mRealTimeZoneSuggester;
+
     private NitzStateMachineImpl mNitzStateMachineImpl;
 
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
+        TelephonyTest.logd("NitzStateMachineImplTest +Setup!");
+        super.setUp("NitzStateMachineImplTest");
+
         // In tests we use a fake impls for NewTimeServiceHelper and DeviceState.
         mFakeDeviceState = new FakeDeviceState();
         mFakeTimeServiceHelper = new FakeTimeServiceHelper(mFakeDeviceState);
@@ -84,24 +90,23 @@
         mRealTimeZoneSuggester = new TimeZoneSuggesterImpl(mFakeDeviceState, timeZoneLookupHelper);
 
         mNitzStateMachineImpl = new NitzStateMachineImpl(
-                SLOT_INDEX, mFakeDeviceState, mFakeNitzSignalInputFilter, mRealTimeZoneSuggester,
+                SLOT_INDEX, mFakeNitzSignalInputFilter, mRealTimeZoneSuggester,
                 mFakeTimeServiceHelper);
+
+        TelephonyTest.logd("NewNitzStateMachineImplTest -Setup!");
     }
 
     @After
-    public void tearDown() {
-        mFakeTimeServiceHelper = null;
-        mFakeDeviceState = null;
-        mRealTimeZoneSuggester = null;
-        mNitzStateMachineImpl = null;
+    public void tearDown() throws Exception {
+        super.tearDown();
     }
 
     @Test
-    public void test_countryThenNitz() {
+    public void test_countryThenNitz() throws Exception {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
         String networkCountryIsoCode = scenario.getNetworkCountryIsoCode();
-        NitzSignal nitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> nitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
 
         // Capture expected results from the real suggester and confirm we can tell the difference
         // between them.
@@ -123,9 +128,8 @@
 
         script.verifyOnlyTimeZoneWasSuggestedAndReset(expectedTimeZoneSuggestion1);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertNull(mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check NitzStateMachine exposed state.
+        assertNull(mNitzStateMachineImpl.getCachedNitzData());
 
         // Simulate NITZ being received and verify the behavior.
         script.nitzReceived(nitzSignal);
@@ -135,16 +139,15 @@
         script.verifyTimeAndTimeZoneSuggestedAndReset(
                 expectedTimeSuggestion, expectedTimeZoneSuggestion2);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check NitzStateMachine exposed state.
+        assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
     }
 
     @Test
     public void test_nitzThenCountry() throws Exception {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        NitzSignal nitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> nitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
 
         String networkCountryIsoCode = scenario.getNetworkCountryIsoCode();
 
@@ -171,24 +174,22 @@
         script.verifyTimeAndTimeZoneSuggestedAndReset(
                 expectedTimeSuggestion, expectedTimeZoneSuggestion1);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check NitzStateMachine exposed state.
+        assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
 
         // Simulate country being known and verify the behavior.
         script.countryReceived(networkCountryIsoCode)
                 .verifyOnlyTimeZoneWasSuggestedAndReset(expectedTimeZoneSuggestion2);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check NitzStateMachine exposed state.
+        assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
     }
 
     @Test
     public void test_emptyCountryString_countryReceivedFirst() throws Exception {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        NitzSignal nitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> nitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
 
         Script script = new Script()
                 .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
@@ -200,9 +201,8 @@
         // Nothing should be set. The country is not valid.
         script.verifyOnlyTimeZoneWasSuggestedAndReset(EMPTY_TIME_ZONE_SUGGESTION);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertNull(mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check NitzStateMachine exposed state.
+        assertNull(mNitzStateMachineImpl.getCachedNitzData());
 
         // Simulate receiving the NITZ signal.
         script.nitzReceived(nitzSignal);
@@ -223,16 +223,15 @@
         script.verifyTimeAndTimeZoneSuggestedAndReset(
                 expectedTimeSuggestion, expectedTimeZoneSuggestion);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check NitzStateMachine exposed state.
+        assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
     }
 
     @Test
     public void test_emptyCountryStringUsTime_nitzReceivedFirst() throws Exception {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        NitzSignal nitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> nitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
 
         Script script = new Script()
                 .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
@@ -248,9 +247,8 @@
         script.verifyTimeAndTimeZoneSuggestedAndReset(
                 expectedTimeSuggestion, EMPTY_TIME_ZONE_SUGGESTION);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check NitzStateMachine exposed state.
+        assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
 
         // Simulate an empty country being set.
         script.countryReceived("");
@@ -268,9 +266,8 @@
         // Verify the state machine did the right thing.
         script.verifyOnlyTimeZoneWasSuggestedAndReset(expectedTimeZoneSuggestion);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check NitzStateMachine exposed state.
+        assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
     }
 
     @Test
@@ -284,8 +281,8 @@
 
         // Pre-flight: Simulate a device receiving signals that allow it to detect time and time
         // zone.
-        NitzSignal preFlightNitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> preFlightNitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
         TelephonyTimeSuggestion expectedPreFlightTimeSuggestion =
                 createTimeSuggestionFromNitzSignal(SLOT_INDEX, preFlightNitzSignal);
         String preFlightCountryIsoCode = scenario.getNetworkCountryIsoCode();
@@ -301,9 +298,8 @@
         script.verifyTimeAndTimeZoneSuggestedAndReset(
                 expectedPreFlightTimeSuggestion, expectedPreFlightTimeZoneSuggestion);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(preFlightNitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check state that NitzStateMachine must expose.
+        assertEquals(preFlightNitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
 
         // Boarded flight: Airplane mode turned on / time zone detection still enabled.
         // The NitzStateMachine must lose all state and stop having an opinion about time zone.
@@ -320,9 +316,8 @@
         script.verifyTimeAndTimeZoneSuggestedAndReset(
                 EMPTY_TIME_SUGGESTION, EMPTY_TIME_ZONE_SUGGESTION);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertNull(mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check state that NitzStateMachine must expose.
+        assertNull(mNitzStateMachineImpl.getCachedNitzData());
 
         // During flight: Airplane mode turned off / time zone detection still enabled.
         // The NitzStateMachine still must not have an opinion about time zone / hold any state.
@@ -337,9 +332,8 @@
         // Verify nothing was suggested: The last suggestion was empty so nothing has changed.
         script.verifyNothingWasSuggested();
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertNull(mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check the state that NitzStateMachine must expose.
+        assertNull(mNitzStateMachineImpl.getCachedNitzData());
 
         // Post flight: Device has moved and receives new signals.
 
@@ -353,8 +347,8 @@
 
         // Simulate the device receiving NITZ signal and country again after the flight. Now the
         // NitzStateMachine should be opinionated again.
-        NitzSignal postFlightNitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> postFlightNitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
         String postFlightCountryCode = scenario.getNetworkCountryIsoCode();
         script.countryReceived(postFlightCountryCode)
                 .nitzReceived(postFlightNitzSignal);
@@ -368,32 +362,26 @@
         script.verifyTimeAndTimeZoneSuggestedAndReset(
                 expectedPostFlightTimeSuggestion, expectedPostFlightTimeZoneSuggestion);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(postFlightNitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check state that NitzStateMachine must expose.
+        assertEquals(postFlightNitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
     }
 
     /**
      * Confirm losing the network / NITZ doesn't clear country state.
      */
     @Test
-    public void test_handleNetworkUnavailableClearsNetworkState_noRestoreOfClearedNitz()
-            throws Exception {
+    public void test_handleNetworkUnavailableClearsNetworkState() throws Exception {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1.mutableCopy();
         int timeStepMillis = (int) TimeUnit.HOURS.toMillis(3);
         String countryIsoCode = scenario.getNetworkCountryIsoCode();
 
-        // Set retention threshold to zero to prevent NITZ being restored when the network is
-        // reported unavailable / available again.
-        mFakeDeviceState.setNitzNetworkDisconnectRetentionMillis(0);
-
         Script script = new Script()
                 .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
                 .networkAvailable();
 
         // Simulate a device receiving signals that allow it to detect time and time zone.
-        NitzSignal initialNitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> initialNitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
         TelephonyTimeSuggestion expectedInitialTimeSuggestion =
                 createTimeSuggestionFromNitzSignal(SLOT_INDEX, initialNitzSignal);
 
@@ -408,9 +396,8 @@
         script.verifyTimeAndTimeZoneSuggestedAndReset(
                 expectedInitialTimeSuggestion, expectedInitialTimeZoneSuggestion);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(initialNitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check state that NitzStateMachine must expose.
+        assertEquals(initialNitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
 
         // Simulate the passage of time and update the device realtime clock.
         scenario.incrementTime(timeStepMillis);
@@ -426,10 +413,8 @@
         script.verifyTimeAndTimeZoneSuggestedAndReset(
                 EMPTY_TIME_SUGGESTION, expectedMiddleTimeZoneSuggestion);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertNull(mNitzStateMachineImpl.getLatestNitzData());
-        assertEquals(initialNitzSignal.getNitzData(),
-                mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check state that NitzStateMachine must expose.
+        assertNull(mNitzStateMachineImpl.getCachedNitzData());
 
         // Simulate the passage of time and update the device realtime clock.
         scenario.incrementTime(timeStepMillis);
@@ -439,10 +424,8 @@
         script.networkAvailable()
                 .verifyNothingWasSuggested();
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertNull(mNitzStateMachineImpl.getLatestNitzData());
-        assertEquals(initialNitzSignal.getNitzData(),
-                mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check the state that NitzStateMachine must expose.
+        assertNull(mNitzStateMachineImpl.getCachedNitzData());
 
         // Simulate the passage of time and update the device realtime clock.
         scenario.incrementTime(timeStepMillis);
@@ -450,8 +433,8 @@
 
         // Simulate the device receiving NITZ signal again. Now the NitzStateMachine should be
         // opinionated again.
-        NitzSignal finalNitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> finalNitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
         script.nitzReceived(finalNitzSignal);
 
         // Verify the state machine did the right thing.
@@ -463,191 +446,15 @@
         script.verifyTimeAndTimeZoneSuggestedAndReset(
                 expectedFinalTimeSuggestion, expectedFinalTimeZoneSuggestion);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(finalNitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
-    }
-
-    /**
-     * Tests the NITZ retention / restore behavior when networkAvailable() is called after
-     * networkUnavailable() inside the retention threshold.
-     */
-    @Test
-    public void test_handleNetworkUnavailableClearsNetworkState_withinRetentionThreshold()
-            throws Exception {
-        Scenario scenario = UNIQUE_US_ZONE_SCENARIO1.mutableCopy();
-        int timeStepMillis = (int) TimeUnit.HOURS.toMillis(3);
-        String countryIsoCode = scenario.getNetworkCountryIsoCode();
-
-        // Set the retention threshold to effectively infinite.
-        mFakeDeviceState.setNitzNetworkDisconnectRetentionMillis(Integer.MAX_VALUE);
-
-        Script script = new Script()
-                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
-                .networkAvailable();
-
-        // Simulate a device receiving signals that allow it to detect time and time zone.
-        NitzSignal initialNitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
-        TelephonyTimeSuggestion expectedInitialTimeSuggestion =
-                createTimeSuggestionFromNitzSignal(SLOT_INDEX, initialNitzSignal);
-
-        // Simulate receiving the NITZ signal and country.
-        script.nitzReceived(initialNitzSignal)
-                .countryReceived(countryIsoCode);
-
-        // Verify the state machine did the right thing.
-        TelephonyTimeZoneSuggestion expectedInitialTimeZoneSuggestion =
-                mRealTimeZoneSuggester.getTimeZoneSuggestion(
-                        SLOT_INDEX, countryIsoCode, initialNitzSignal);
-        script.verifyTimeAndTimeZoneSuggestedAndReset(
-                expectedInitialTimeSuggestion, expectedInitialTimeZoneSuggestion);
-
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(initialNitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
-
-        // Simulate the passage of time and update the device realtime clock.
-        scenario.incrementTime(timeStepMillis);
-        script.incrementTime(timeStepMillis);
-
-        // Simulate network being lost.
-        script.networkUnavailable();
-
-        // Check the "no NITZ" time and time zone suggestions are made.
-        TelephonyTimeZoneSuggestion expectedMiddleTimeZoneSuggestion =
-                mRealTimeZoneSuggester.getTimeZoneSuggestion(
-                        SLOT_INDEX, countryIsoCode, null /* nitzSignal */);
-        script.verifyTimeAndTimeZoneSuggestedAndReset(
-                EMPTY_TIME_SUGGESTION, expectedMiddleTimeZoneSuggestion);
-
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertNull(mNitzStateMachineImpl.getLatestNitzData());
-        assertEquals(initialNitzSignal.getNitzData(),
-                mNitzStateMachineImpl.getLastNitzDataCleared());
-
-        // Simulate the passage of time and update the device realtime clock.
-        scenario.incrementTime(timeStepMillis);
-        script.incrementTime(timeStepMillis);
-
-        // Simulate the network being found. As we are inside the NITZ retention threshold, the
-        // initial NITZ signal should be restored, and the same suggestion made.
-        script.networkAvailable()
-                .verifyTimeAndTimeZoneSuggestedAndReset(
-                        expectedInitialTimeSuggestion, expectedInitialTimeZoneSuggestion);
-
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(initialNitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
-
-        // Simulate the passage of time and update the device realtime clock.
-        scenario.incrementTime(timeStepMillis);
-        script.incrementTime(timeStepMillis);
-
-        // Simulate the device receiving another NITZ signal.
-        NitzSignal finalNitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
-        script.nitzReceived(finalNitzSignal);
-
-        // Verify the state machine did the right thing.
-        TelephonyTimeSuggestion expectedFinalTimeSuggestion =
-                createTimeSuggestionFromNitzSignal(SLOT_INDEX, finalNitzSignal);
-        TelephonyTimeZoneSuggestion expectedFinalTimeZoneSuggestion =
-                mRealTimeZoneSuggester.getTimeZoneSuggestion(
-                        SLOT_INDEX, countryIsoCode, finalNitzSignal);
-        script.verifyTimeAndTimeZoneSuggestedAndReset(
-                expectedFinalTimeSuggestion, expectedFinalTimeZoneSuggestion);
-
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(finalNitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
-    }
-
-    /**
-     * b/220839115 - handleNetworkAvailable() cannot be relied upon. Sometimes a NITZ signal is
-     * received without it, which can be taken as an implicit "network available".
-     */
-    @Test
-    public void test_handleNetworkUnavailable_noNetworkAvailableCall_withinRetentionThreshold()
-            throws Exception {
-        Scenario scenario = UNIQUE_US_ZONE_SCENARIO1.mutableCopy();
-        int timeStepMillis = (int) TimeUnit.HOURS.toMillis(3);
-        String countryIsoCode = scenario.getNetworkCountryIsoCode();
-
-        // Set the retention threshold to effectively infinite.
-        mFakeDeviceState.setNitzNetworkDisconnectRetentionMillis(Integer.MAX_VALUE);
-
-        Script script = new Script()
-                .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME);
-
-        // Simulate a device receiving signals that allow it to detect time and time zone.
-        NitzSignal initialNitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
-        TelephonyTimeSuggestion expectedInitialTimeSuggestion =
-                createTimeSuggestionFromNitzSignal(SLOT_INDEX, initialNitzSignal);
-
-        // Simulate receiving the NITZ signal and country.
-        script.nitzReceived(initialNitzSignal)
-                .countryReceived(countryIsoCode);
-
-        // Verify the state machine did the right thing.
-        TelephonyTimeZoneSuggestion expectedInitialTimeZoneSuggestion =
-                mRealTimeZoneSuggester.getTimeZoneSuggestion(
-                        SLOT_INDEX, countryIsoCode, initialNitzSignal);
-        script.verifyTimeAndTimeZoneSuggestedAndReset(
-                expectedInitialTimeSuggestion, expectedInitialTimeZoneSuggestion);
-
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(initialNitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
-
-        // Simulate the passage of time and update the device realtime clock.
-        scenario.incrementTime(timeStepMillis);
-        script.incrementTime(timeStepMillis);
-
-        // Simulate network being lost.
-        script.networkUnavailable();
-
-        // Check the "no NITZ" time and time zone suggestions are made.
-        TelephonyTimeZoneSuggestion expectedMiddleTimeZoneSuggestion =
-                mRealTimeZoneSuggester.getTimeZoneSuggestion(
-                        SLOT_INDEX, countryIsoCode, null /* nitzSignal */);
-        script.verifyTimeAndTimeZoneSuggestedAndReset(
-                EMPTY_TIME_SUGGESTION, expectedMiddleTimeZoneSuggestion);
-
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertNull(mNitzStateMachineImpl.getLatestNitzData());
-        assertEquals(initialNitzSignal.getNitzData(),
-                mNitzStateMachineImpl.getLastNitzDataCleared());
-
-        // Simulate the passage of time and update the device realtime clock.
-        scenario.incrementTime(timeStepMillis);
-        script.incrementTime(timeStepMillis);
-
-        // Simulate the device receiving another NITZ signal (without a network available call).
-        NitzSignal finalNitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
-        script.nitzReceived(finalNitzSignal);
-
-        // Verify the state machine did the right thing.
-        TelephonyTimeSuggestion expectedFinalTimeSuggestion =
-                createTimeSuggestionFromNitzSignal(SLOT_INDEX, finalNitzSignal);
-        TelephonyTimeZoneSuggestion expectedFinalTimeZoneSuggestion =
-                mRealTimeZoneSuggester.getTimeZoneSuggestion(
-                        SLOT_INDEX, countryIsoCode, finalNitzSignal);
-        script.verifyTimeAndTimeZoneSuggestedAndReset(
-                expectedFinalTimeSuggestion, expectedFinalTimeZoneSuggestion);
-
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(finalNitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check state that NitzStateMachine must expose.
+        assertEquals(finalNitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
     }
 
     @Test
     public void test_countryUnavailableClearsTimeZoneSuggestion() throws Exception {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        NitzSignal nitzSignal =
-                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> nitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
 
         Script script = new Script()
                 .initializeSystemClock(ARBITRARY_SYSTEM_CLOCK_TIME)
@@ -670,9 +477,8 @@
         script.verifyTimeAndTimeZoneSuggestedAndReset(
                 expectedTimeSuggestion, expectedTimeZoneSuggestion2);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check state that NitzStateMachine must expose.
+        assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
 
         // Simulate the country becoming unavailable and verify the state machine does the right
         // thing.
@@ -682,9 +488,8 @@
                         SLOT_INDEX, null /* countryIsoCode */, nitzSignal);
         script.verifyOnlyTimeZoneWasSuggestedAndReset(expectedTimeZoneSuggestion3);
 
-        // Check NitzStateMachineImpl internal state exposed for tests.
-        assertEquals(nitzSignal.getNitzData(), mNitzStateMachineImpl.getLatestNitzData());
-        assertNull(mNitzStateMachineImpl.getLastNitzDataCleared());
+        // Check state that NitzStateMachine must expose.
+        assertEquals(nitzSignal.getValue(), mNitzStateMachineImpl.getCachedNitzData());
     }
 
     /**
@@ -719,7 +524,7 @@
             return this;
         }
 
-        Script nitzReceived(NitzSignal nitzSignal) {
+        Script nitzReceived(TimestampedValue<NitzData> nitzSignal) {
             mNitzStateMachineImpl.handleNitzReceived(nitzSignal);
             return this;
         }
@@ -856,9 +661,9 @@
         @Override
         public void suggestDeviceTime(TelephonyTimeSuggestion timeSuggestion) {
             suggestedTimes.set(timeSuggestion);
-            if (timeSuggestion.getUnixEpochTime() != null) {
+            if (timeSuggestion.getUtcTime() != null) {
                 // The fake time service just uses the latest suggestion.
-                mFakeDeviceState.currentTimeMillis = timeSuggestion.getUnixEpochTime().getValue();
+                mFakeDeviceState.currentTimeMillis = timeSuggestion.getUtcTime().getValue();
             }
         }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineTestSupport.java b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineTestSupport.java
index bcc7267..ed1c98b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineTestSupport.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineTestSupport.java
@@ -23,9 +23,9 @@
 import android.icu.util.Calendar;
 import android.icu.util.GregorianCalendar;
 import android.icu.util.TimeZone;
+import android.os.TimestampedValue;
 
 import com.android.internal.telephony.NitzData;
-import com.android.internal.telephony.NitzSignal;
 import com.android.internal.telephony.NitzStateMachine;
 import com.android.internal.telephony.NitzStateMachine.DeviceState;
 
@@ -34,12 +34,9 @@
  */
 final class NitzStateMachineTestSupport {
 
-    /** Used to indicate that a NitzSignal ageMillis is unimportant for the test. */
-    static final int ARBITRARY_AGE = 54321;
-
     // Values used to when initializing device state but where the value isn't important.
-    static final long ARBITRARY_SYSTEM_CLOCK_TIME = createUnixEpochTime(1977, 1, 1, 12, 0, 0);
-    static final long ARBITRARY_ELAPSED_REALTIME = 123456789L;
+    static final long ARBITRARY_SYSTEM_CLOCK_TIME = createUtcTime(1977, 1, 1, 12, 0, 0);
+    static final long ARBITRARY_REALTIME_MILLIS = 123456789L;
     static final String ARBITRARY_DEBUG_INFO = "Test debug info";
 
     // A country with a single zone : the zone can be guessed from the country.
@@ -123,11 +120,9 @@
             mNetworkCountryIsoCode = countryIsoCode;
         }
 
-        /**
-         * Creates an NITZ signal to match the scenario with the specified receipt / age properties.
-         */
-        NitzSignal createNitzSignal(long receiptElapsedMillis, long ageMillis) {
-            return new NitzSignal(receiptElapsedMillis, createNitzData(), ageMillis);
+        /** Creates an NITZ signal to match the scenario. */
+        TimestampedValue<NitzData> createNitzSignal(long elapsedRealtimeClock) {
+            return new TimestampedValue<>(elapsedRealtimeClock, createNitzData());
         }
 
         /** Creates an NITZ signal to match the scenario. */
@@ -184,7 +179,7 @@
 
             Builder setActualTimeUtc(int year, int monthInYear, int day, int hourOfDay,
                     int minute, int second) {
-                mActualTimeMillis = createUnixEpochTime(year, monthInYear, day, hourOfDay, minute,
+                mActualTimeMillis = createUtcTime(year, monthInYear, day, hourOfDay, minute,
                         second);
                 return this;
             }
@@ -211,7 +206,6 @@
         public boolean ignoreNitz;
         public int nitzUpdateDiffMillis;
         public int nitzUpdateSpacingMillis;
-        public int nitzNetworkDisconnectRetentionMillis;
         public long elapsedRealtime;
         public long currentTimeMillis;
 
@@ -220,8 +214,7 @@
             ignoreNitz = false;
             nitzUpdateDiffMillis = 2000;
             nitzUpdateSpacingMillis = 1000 * 60 * 10;
-            nitzNetworkDisconnectRetentionMillis = 1000 * 60 * 5;
-            elapsedRealtime = ARBITRARY_ELAPSED_REALTIME;
+            elapsedRealtime = ARBITRARY_REALTIME_MILLIS;
         }
 
         @Override
@@ -229,36 +222,18 @@
             return nitzUpdateSpacingMillis;
         }
 
-        public void setNitzUpdateSpacingMillis(int nitzUpdateSpacingMillis) {
-            this.nitzUpdateSpacingMillis = nitzUpdateSpacingMillis;
-        }
-
         @Override
         public int getNitzUpdateDiffMillis() {
             return nitzUpdateDiffMillis;
         }
 
-        public void setNitzUpdateDiffMillis(int nitzUpdateDiffMillis) {
-            this.nitzUpdateDiffMillis = nitzUpdateDiffMillis;
-        }
-
-        @Override
-        public int getNitzNetworkDisconnectRetentionMillis() {
-            return nitzNetworkDisconnectRetentionMillis;
-        }
-
-        public void setNitzNetworkDisconnectRetentionMillis(
-                int nitzNetworkDisconnectRetectionMillis) {
-            this.nitzNetworkDisconnectRetentionMillis = nitzNetworkDisconnectRetectionMillis;
-        }
-
         @Override
         public boolean getIgnoreNitz() {
             return ignoreNitz;
         }
 
         @Override
-        public long elapsedRealtimeMillis() {
+        public long elapsedRealtime() {
             return elapsedRealtime;
         }
 
@@ -279,8 +254,8 @@
 
     private NitzStateMachineTestSupport() {}
 
-    private static long createUnixEpochTime(int year, int monthInYear, int day, int hourOfDay,
-            int minute, int second) {
+    private static long createUtcTime(int year, int monthInYear, int day, int hourOfDay, int minute,
+            int second) {
         Calendar cal = new GregorianCalendar(zone("Etc/UTC"));
         cal.clear();
         cal.set(year, monthInYear - 1, day, hourOfDay, minute, second);
@@ -300,13 +275,20 @@
     }
 
     static TelephonyTimeSuggestion createTimeSuggestionFromNitzSignal(
-            int slotIndex, NitzSignal nitzSignal) {
+            int slotIndex, TimestampedValue<NitzData> nitzSignal) {
         return new TelephonyTimeSuggestion.Builder(slotIndex)
-                .setUnixEpochTime(nitzSignal.createTimeSignal())
+                .setUtcTime(createTimeSignalFromNitzSignal(nitzSignal))
                 .addDebugInfo("Test")
                 .build();
     }
 
+    private static TimestampedValue<Long> createTimeSignalFromNitzSignal(
+            TimestampedValue<NitzData> nitzSignal) {
+        return new TimestampedValue<>(
+                nitzSignal.getReferenceTimeMillis(),
+                nitzSignal.getValue().getCurrentTimeInMillis());
+    }
+
     private static TimeZone zone(String zoneId) {
         TimeZone timeZone = TimeZone.getFrozenTimeZone(zoneId);
         if (timeZone.getID().equals(TimeZone.UNKNOWN_ZONE_ID)) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineTestSupportTest.java b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineTestSupportTest.java
index b371693..986c8d6 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineTestSupportTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/NitzStateMachineTestSupportTest.java
@@ -42,7 +42,6 @@
 
 import com.android.internal.telephony.nitz.TimeZoneLookupHelper.CountryResult;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -54,16 +53,11 @@
     private TimeZoneLookupHelper mTimeZoneLookupHelper;
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
         // In tests we use the real TimeZoneLookupHelper implementation.
         mTimeZoneLookupHelper = new TimeZoneLookupHelper();
     }
 
-    @After
-    public void tearDown() {
-        mTimeZoneLookupHelper = null;
-    }
-
     @Test
     public void test_uniqueUs_assumptions() {
         // Check we'll get the expected behavior from TimeZoneLookupHelper.
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/TimeZoneLookupHelperTest.java b/tests/telephonytests/src/com/android/internal/telephony/nitz/TimeZoneLookupHelperTest.java
index ca69e88..990f568 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/nitz/TimeZoneLookupHelperTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/TimeZoneLookupHelperTest.java
@@ -35,7 +35,6 @@
 import com.android.internal.telephony.NitzData;
 import com.android.internal.telephony.nitz.TimeZoneLookupHelper.CountryResult;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -48,9 +47,9 @@
 public class TimeZoneLookupHelperTest {
     // Note: Historical dates are used to avoid the test breaking due to data changes.
     /* Arbitrary summer date in the Northern hemisphere. */
-    private static final long NH_SUMMER_TIME_MILLIS = createUnixEpochTime(2015, 6, 20, 1, 2, 3);
+    private static final long NH_SUMMER_TIME_MILLIS = createUtcTime(2015, 6, 20, 1, 2, 3);
     /* Arbitrary winter date in the Northern hemisphere. */
-    private static final long NH_WINTER_TIME_MILLIS = createUnixEpochTime(2015, 1, 20, 1, 2, 3);
+    private static final long NH_WINTER_TIME_MILLIS = createUtcTime(2015, 1, 20, 1, 2, 3);
 
     private TimeZoneLookupHelper mTimeZoneLookupHelper;
 
@@ -59,18 +58,13 @@
         mTimeZoneLookupHelper = new TimeZoneLookupHelper();
     }
 
-    @After
-    public void tearDown() {
-        mTimeZoneLookupHelper = null;
-    }
-
     @Test
     public void testLookupByNitzByNitz() {
         // Historical dates are used to avoid the test breaking due to data changes.
         // However, algorithm updates may change the exact time zone returned, though it shouldn't
         // ever be a less exact match.
-        long nhSummerTimeMillis = createUnixEpochTime(2015, 6, 20, 1, 2, 3);
-        long nhWinterTimeMillis = createUnixEpochTime(2015, 1, 20, 1, 2, 3);
+        long nhSummerTimeMillis = createUtcTime(2015, 6, 20, 1, 2, 3);
+        long nhWinterTimeMillis = createUtcTime(2015, 1, 20, 1, 2, 3);
 
         String nhSummerTimeString = "15/06/20,01:02:03";
         String nhWinterTimeString = "15/01/20,01:02:03";
@@ -220,8 +214,8 @@
         // Historical dates are used to avoid the test breaking due to data changes.
         // However, algorithm updates may change the exact time zone returned, though it shouldn't
         // ever be a less exact match.
-        long nhSummerTimeMillis = createUnixEpochTime(2015, 6, 20, 1, 2, 3);
-        long nhWinterTimeMillis = createUnixEpochTime(2015, 1, 20, 1, 2, 3);
+        long nhSummerTimeMillis = createUtcTime(2015, 6, 20, 1, 2, 3);
+        long nhWinterTimeMillis = createUtcTime(2015, 1, 20, 1, 2, 3);
 
         // A country in the northern hemisphere with one time zone.
         String adIso = "AD"; // Andora
@@ -337,8 +331,8 @@
         // DE has two time zones according to IANA data: Europe/Berlin and Europe/Busingen, but they
         // become effectively identical after 338950800000 millis (Sun, 28 Sep 1980 01:00:00 GMT).
         // Android data tells us that Europe/Berlin the one that was "kept".
-        long nhSummerTimeMillis = createUnixEpochTime(1975, 6, 20, 1, 2, 3);
-        long nhWinterTimeMillis = createUnixEpochTime(1975, 1, 20, 1, 2, 3);
+        long nhSummerTimeMillis = createUtcTime(1975, 6, 20, 1, 2, 3);
+        long nhWinterTimeMillis = createUtcTime(1975, 1, 20, 1, 2, 3);
 
         // Before 1980, quality == QUALITY_MULTIPLE_ZONES_SAME_OFFSET because Europe/Busingen was
         // relevant.
@@ -351,8 +345,8 @@
 
         // And in 2015, quality == QUALITY_SINGLE_ZONE because Europe/Busingen became irrelevant
         // after 1980.
-        nhSummerTimeMillis = createUnixEpochTime(2015, 6, 20, 1, 2, 3);
-        nhWinterTimeMillis = createUnixEpochTime(2015, 1, 20, 1, 2, 3);
+        nhSummerTimeMillis = createUtcTime(2015, 6, 20, 1, 2, 3);
+        nhWinterTimeMillis = createUtcTime(2015, 1, 20, 1, 2, 3);
 
         expectedResult =
                 new CountryResult("Europe/Berlin", QUALITY_SINGLE_ZONE, ARBITRARY_DEBUG_INFO);
@@ -364,7 +358,7 @@
 
     @Test
     public void testDefaultBoostBehavior() {
-        long timeMillis = createUnixEpochTime(2015, 6, 20, 1, 2, 3);
+        long timeMillis = createUtcTime(2015, 6, 20, 1, 2, 3);
 
         // An example known to be explicitly boosted. New Zealand has two zones but the vast
         // majority of the population use one of them so Android's data file explicitly boosts the
@@ -408,7 +402,7 @@
 
     @Test
     public void testNoDefaultBoostBehavior() {
-        long timeMillis = createUnixEpochTime(2015, 6, 20, 1, 2, 3);
+        long timeMillis = createUtcTime(2015, 6, 20, 1, 2, 3);
 
         // An example known to not be explicitly boosted. Micronesia is spread out and there's no
         // suitable default.
@@ -495,7 +489,7 @@
         assertEquals(isOnlyMatch, lookupResult.isOnlyMatch());
     }
 
-    private static long createUnixEpochTime(
+    private static long createUtcTime(
             int year, int monthOfYear, int dayOfMonth, int hourOfDay, int minute, int second) {
         GregorianCalendar calendar = new GregorianCalendar(zone("UTC"));
         calendar.clear(); // Clear millis, etc.
diff --git a/tests/telephonytests/src/com/android/internal/telephony/nitz/TimeZoneSuggesterImplTest.java b/tests/telephonytests/src/com/android/internal/telephony/nitz/TimeZoneSuggesterImplTest.java
index 84214ec..708d3de 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/nitz/TimeZoneSuggesterImplTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/nitz/TimeZoneSuggesterImplTest.java
@@ -24,8 +24,7 @@
 import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET;
 import static android.app.timezonedetector.TelephonyTimeZoneSuggestion.QUALITY_SINGLE_ZONE;
 
-import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.ARBITRARY_AGE;
-import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.ARBITRARY_ELAPSED_REALTIME;
+import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.ARBITRARY_REALTIME_MILLIS;
 import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.CZECHIA_SCENARIO;
 import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.NEW_ZEALAND_COUNTRY_DEFAULT_ZONE_ID;
 import static com.android.internal.telephony.nitz.NitzStateMachineTestSupport.NEW_ZEALAND_DEFAULT_SCENARIO;
@@ -41,9 +40,10 @@
 import static org.junit.Assert.assertTrue;
 
 import android.app.timezonedetector.TelephonyTimeZoneSuggestion;
+import android.os.TimestampedValue;
 
 import com.android.internal.telephony.NitzData;
-import com.android.internal.telephony.NitzSignal;
+import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.nitz.NitzStateMachineImpl.TimeZoneSuggester;
 import com.android.internal.telephony.nitz.NitzStateMachineTestSupport.FakeDeviceState;
 import com.android.internal.telephony.nitz.NitzStateMachineTestSupport.Scenario;
@@ -55,7 +55,8 @@
 import java.util.Arrays;
 import java.util.List;
 
-public class TimeZoneSuggesterImplTest {
+public class TimeZoneSuggesterImplTest extends TelephonyTest {
+
     private static final int SLOT_INDEX = 99999;
     private static final TelephonyTimeZoneSuggestion EMPTY_TIME_ZONE_SUGGESTION =
             new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX).build();
@@ -64,7 +65,10 @@
     private TimeZoneSuggester mTimeZoneSuggester;
 
     @Before
-    public void setUp() {
+    public void setUp() throws Exception {
+        TelephonyTest.logd("TimeZoneSuggesterImplTest +Setup!");
+        super.setUp("TimeZoneSuggesterImplTest");
+
         // In tests a fake impl is used for DeviceState, which allows historic data to be used.
         mFakeDeviceState = new FakeDeviceState();
 
@@ -72,12 +76,13 @@
         // construct tests using known historic examples.
         TimeZoneLookupHelper timeZoneLookupHelper = new TimeZoneLookupHelper();
         mTimeZoneSuggester = new TimeZoneSuggesterImpl(mFakeDeviceState, timeZoneLookupHelper);
+
+        TelephonyTest.logd("TimeZoneSuggesterImplTest -Setup!");
     }
 
     @After
-    public void tearDown() {
-        mFakeDeviceState = null;
-        mTimeZoneSuggester = null;
+    public void tearDown() throws Exception {
+        super.tearDown();
     }
 
     @Test
@@ -90,8 +95,8 @@
     @Test
     public void test_emptySuggestionForNullCountryWithNitz() throws Exception {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-        NitzSignal nitzSignal =
-                scenario.createNitzSignal(ARBITRARY_ELAPSED_REALTIME, ARBITRARY_AGE);
+        TimestampedValue<NitzData> nitzSignal =
+                scenario.createNitzSignal(ARBITRARY_REALTIME_MILLIS);
         assertEquals(EMPTY_TIME_ZONE_SUGGESTION,
                 mTimeZoneSuggester.getTimeZoneSuggestion(
                         SLOT_INDEX, null /* countryIsoCode */, nitzSignal));
@@ -132,10 +137,9 @@
         // NITZ with a "" country code is interpreted as a test network so only offset is used
         // to get a match.
         {
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, "" /* countryIsoCode */, nitzSignal);
+                    SLOT_INDEX, "" /* countryIsoCode */,
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
             assertEquals(SLOT_INDEX, actualSuggestion.getSlotIndex());
             assertEquals(MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY, actualSuggestion.getMatchType());
             assertEquals(QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, actualSuggestion.getQuality());
@@ -143,10 +147,9 @@
 
         // NITZ alone is not enough to get a result when the country is not available.
         {
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, null /* countryIsoCode */, nitzSignal);
+                    SLOT_INDEX, null /* countryIsoCode */,
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
             assertEquals(EMPTY_TIME_ZONE_SUGGESTION, actualSuggestion);
         }
 
@@ -158,10 +161,9 @@
                             .setMatchType(MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET)
                             .setQuality(QUALITY_SINGLE_ZONE)
                             .build();
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(), nitzSignal);
+                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
             assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
         }
 
@@ -169,11 +171,12 @@
         // since there are multiple zones to choose from.
         {
             // We use an NITZ from CZ to generate an NITZ signal with a bad offset.
-            NitzSignal badNitzSignal = CZECHIA_SCENARIO.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+            TimestampedValue<NitzData> badNitzSignal =
+                    CZECHIA_SCENARIO.createNitzSignal(mFakeDeviceState.elapsedRealtime());
             TelephonyTimeZoneSuggestion expectedTimeZoneSuggestion = EMPTY_TIME_ZONE_SUGGESTION;
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(), badNitzSignal);
+                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
+                    badNitzSignal);
             assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
         }
     }
@@ -206,10 +209,9 @@
         // NITZ with a "" country code is interpreted as a test network so only offset is used
         // to get a match.
         {
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, "" /* countryIsoCode */, nitzSignal);
+                    SLOT_INDEX, "" /* countryIsoCode */,
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
             assertEquals(SLOT_INDEX, actualSuggestion.getSlotIndex());
             assertEquals(MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY, actualSuggestion.getMatchType());
             assertEquals(QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, actualSuggestion.getQuality());
@@ -217,19 +219,17 @@
 
         // NITZ alone is not enough to get a result when the country is not available.
         {
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, null /* countryIsoCode */, nitzSignal);
+                    SLOT_INDEX, null /* countryIsoCode */,
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
             assertEquals(EMPTY_TIME_ZONE_SUGGESTION, actualSuggestion);
         }
 
         // Country + NITZ is not enough for a unique time zone detection result for this scenario.
         {
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(), nitzSignal);
+                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
             assertEquals(SLOT_INDEX, actualSuggestion.getSlotIndex());
             assertEquals(MATCH_TYPE_NETWORK_COUNTRY_AND_OFFSET, actualSuggestion.getMatchType());
             assertEquals(QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, actualSuggestion.getQuality());
@@ -241,11 +241,12 @@
         // since there are multiple zones to choose from.
         {
             // We use an NITZ from CZ to generate an NITZ signal with a bad offset.
-            NitzSignal badNitzSignal = CZECHIA_SCENARIO.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+            TimestampedValue<NitzData> badNitzSignal =
+                    CZECHIA_SCENARIO.createNitzSignal(mFakeDeviceState.elapsedRealtime());
             TelephonyTimeZoneSuggestion expectedTimeZoneSuggestion = EMPTY_TIME_ZONE_SUGGESTION;
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(), badNitzSignal);
+                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
+                    badNitzSignal);
             assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
         }
     }
@@ -277,10 +278,9 @@
         // NITZ with a "" country code is interpreted as a test network so only offset is used
         // to get a match.
         {
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, "" /* countryIsoCode */, nitzSignal);
+                    SLOT_INDEX, "" /* countryIsoCode */,
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
             assertEquals(SLOT_INDEX, actualSuggestion.getSlotIndex());
             assertEquals(MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY, actualSuggestion.getMatchType());
             assertEquals(QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, actualSuggestion.getQuality());
@@ -289,10 +289,9 @@
 
         // NITZ alone is not enough to get a result when the country is not available.
         {
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, null /* countryIsoCode */, nitzSignal);
+                    SLOT_INDEX, null /* countryIsoCode */,
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
             assertEquals(EMPTY_TIME_ZONE_SUGGESTION, actualSuggestion);
         }
 
@@ -305,10 +304,9 @@
                             .setQuality(QUALITY_SINGLE_ZONE)
                             .build();
 
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(), nitzSignal);
+                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
             assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
         }
 
@@ -316,8 +314,8 @@
         // there's only one zone.
         {
             // We use an NITZ from Czechia to generate an NITZ signal with a bad offset.
-            NitzSignal badNitzSignal = CZECHIA_SCENARIO.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+            TimestampedValue<NitzData> badNitzSignal =
+                    CZECHIA_SCENARIO.createNitzSignal(mFakeDeviceState.elapsedRealtime());
             TelephonyTimeZoneSuggestion expectedTimeZoneSuggestion =
                     new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
                             .setZoneId(scenario.getTimeZoneId())
@@ -326,7 +324,8 @@
                             .build();
 
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(), badNitzSignal);
+                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
+                    badNitzSignal);
             assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
         }
     }
@@ -357,22 +356,21 @@
         // NITZ with a "" country code is interpreted as a test network so only offset is used
         // to get a match.
         {
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
             TelephonyTimeZoneSuggestion actualSuggestion =
                     mTimeZoneSuggester.getTimeZoneSuggestion(
-                            SLOT_INDEX, "" /* countryIsoCode */, nitzSignal);
+                            SLOT_INDEX, "" /* countryIsoCode */,
+                            scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
             assertEquals(SLOT_INDEX, actualSuggestion.getSlotIndex());
             assertEquals(MATCH_TYPE_TEST_NETWORK_OFFSET_ONLY, actualSuggestion.getMatchType());
             assertEquals(QUALITY_MULTIPLE_ZONES_WITH_SAME_OFFSET, actualSuggestion.getQuality());
+
         }
 
         // NITZ alone is not enough to get a result when the country is not available.
         {
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, null /* countryIsoCode */, nitzSignal);
+                    SLOT_INDEX, null /* countryIsoCode */,
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
             assertEquals(EMPTY_TIME_ZONE_SUGGESTION, actualSuggestion);
         }
 
@@ -385,10 +383,9 @@
                             .setQuality(QUALITY_SINGLE_ZONE)
                             .build();
 
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(), nitzSignal);
+                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime()));
             assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
         }
 
@@ -396,8 +393,8 @@
         // there's only one zone.
         {
             // We use an NITZ from the US to generate an NITZ signal with a bad offset.
-            NitzSignal badNitzSignal = UNIQUE_US_ZONE_SCENARIO1.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+            TimestampedValue<NitzData> badNitzSignal =
+                    UNIQUE_US_ZONE_SCENARIO1.createNitzSignal(mFakeDeviceState.elapsedRealtime());
             TelephonyTimeZoneSuggestion expectedTimeZoneSuggestion =
                     new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
                             .setZoneId(scenario.getTimeZoneId())
@@ -406,7 +403,8 @@
                             .build();
 
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
-                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(), badNitzSignal);
+                    SLOT_INDEX, scenario.getNetworkCountryIsoCode(),
+                    badNitzSignal);
             assertEquals(expectedTimeZoneSuggestion, actualSuggestion);
         }
     }
@@ -432,15 +430,14 @@
         // NITZ + bogus NITZ is not enough to get a result.
         {
             // Create a corrupted NITZ signal, where the offset information has been lost.
-            NitzSignal goodNitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+            TimestampedValue<NitzData> goodNitzSignal =
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
             NitzData bogusNitzData = NitzData.createForTests(
                     0 /* UTC! */, null /* dstOffsetMillis */,
-                    goodNitzSignal.getNitzData().getCurrentTimeInMillis(),
+                    goodNitzSignal.getValue().getCurrentTimeInMillis(),
                     null /* emulatorHostTimeZone */);
-            NitzSignal badNitzSignal = new NitzSignal(
-                    goodNitzSignal.getReceiptElapsedRealtimeMillis(), bogusNitzData,
-                    goodNitzSignal.getAgeMillis());
+            TimestampedValue<NitzData> badNitzSignal = new TimestampedValue<>(
+                    goodNitzSignal.getReferenceTimeMillis(), bogusNitzData);
 
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
                     SLOT_INDEX, scenario.getNetworkCountryIsoCode(), badNitzSignal);
@@ -469,15 +466,14 @@
         // NITZ + bogus NITZ is not enough to get a result.
         {
             // Create a corrupted NITZ signal, where the offset information has been lost.
-            NitzSignal goodNitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+            TimestampedValue<NitzData> goodNitzSignal =
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
             NitzData bogusNitzData = NitzData.createForTests(
                     0 /* UTC! */, null /* dstOffsetMillis */,
-                    goodNitzSignal.getNitzData().getCurrentTimeInMillis(),
+                    goodNitzSignal.getValue().getCurrentTimeInMillis(),
                     null /* emulatorHostTimeZone */);
-            NitzSignal badNitzSignal = new NitzSignal(
-                    goodNitzSignal.getReceiptElapsedRealtimeMillis(), bogusNitzData,
-                    goodNitzSignal.getAgeMillis());
+            TimestampedValue<NitzData> badNitzSignal = new TimestampedValue<>(
+                    goodNitzSignal.getReferenceTimeMillis(), bogusNitzData);
 
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
                     SLOT_INDEX, scenario.getNetworkCountryIsoCode(), badNitzSignal);
@@ -489,11 +485,11 @@
     public void test_emulatorNitzExtensionUsedForTimeZone() throws Exception {
         Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
 
-        NitzSignal originalNitzSignal = scenario.createNitzSignal(
-                mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+        TimestampedValue<NitzData> originalNitzSignal =
+                scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
 
         // Create an NITZ signal with an explicit time zone (as can happen on emulators).
-        NitzData originalNitzData = originalNitzSignal.getNitzData();
+        NitzData originalNitzData = originalNitzSignal.getValue();
 
         // A time zone that is obviously not in the US, but because the explicit value is present it
         // should not be questioned.
@@ -503,9 +499,8 @@
                 originalNitzData.getDstAdjustmentMillis(),
                 originalNitzData.getCurrentTimeInMillis(),
                 java.util.TimeZone.getTimeZone(emulatorTimeZoneId) /* emulatorHostTimeZone */);
-        NitzSignal emulatorNitzSignal = new NitzSignal(
-                originalNitzSignal.getReceiptElapsedRealtimeMillis(), emulatorNitzData,
-                originalNitzSignal.getAgeMillis());
+        TimestampedValue<NitzData> emulatorNitzSignal = new TimestampedValue<>(
+                originalNitzSignal.getReferenceTimeMillis(), emulatorNitzData);
 
         TelephonyTimeZoneSuggestion expectedTimeZoneSuggestion =
                 new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
@@ -540,8 +535,8 @@
         // Confirm what happens when NITZ is correct for the country default.
         {
             Scenario scenario = NEW_ZEALAND_DEFAULT_SCENARIO;
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+            TimestampedValue<NitzData> nitzSignal =
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
             TelephonyTimeZoneSuggestion expectedSuggestion =
                     new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
                             .setZoneId(scenario.getTimeZoneId())
@@ -557,8 +552,8 @@
         // A valid NITZ signal for the non-default zone should still be correctly detected.
         {
             Scenario scenario = NEW_ZEALAND_OTHER_SCENARIO;
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+            TimestampedValue<NitzData> nitzSignal =
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
             TelephonyTimeZoneSuggestion expectedSuggestion =
                     new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
                             .setZoneId(scenario.getTimeZoneId())
@@ -576,8 +571,8 @@
         {
             Scenario scenario = NEW_ZEALAND_DEFAULT_SCENARIO;
             // Use a scenario that has a different offset than NZ to generate the NITZ signal.
-            NitzSignal nitzSignal = CZECHIA_SCENARIO.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+            TimestampedValue<NitzData> nitzSignal =
+                    CZECHIA_SCENARIO.createNitzSignal(mFakeDeviceState.elapsedRealtime());
             TelephonyTimeZoneSuggestion expectedSuggestion =
                     new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
                             .setZoneId(NEW_ZEALAND_COUNTRY_DEFAULT_ZONE_ID)
@@ -612,8 +607,8 @@
         // Confirm what happens when NITZ is correct for the country default.
         {
             Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+            TimestampedValue<NitzData> nitzSignal =
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
             TelephonyTimeZoneSuggestion expectedSuggestion =
                     new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
                             .setZoneId(scenario.getTimeZoneId())
@@ -629,8 +624,8 @@
         // A valid NITZ signal for the non-default zone should still be correctly detected.
         {
             Scenario scenario = UNIQUE_US_ZONE_SCENARIO2;
-            NitzSignal nitzSignal = scenario.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+            TimestampedValue<NitzData> nitzSignal =
+                    scenario.createNitzSignal(mFakeDeviceState.elapsedRealtime());
             TelephonyTimeZoneSuggestion expectedSuggestion =
                     new TelephonyTimeZoneSuggestion.Builder(SLOT_INDEX)
                             .setZoneId(scenario.getTimeZoneId())
@@ -649,8 +644,8 @@
             // A scenario that has a different offset than US.
             Scenario scenario = UNIQUE_US_ZONE_SCENARIO1;
             // Use a scenario that has a different offset than the US to generate the NITZ signal.
-            NitzSignal nitzSignal = CZECHIA_SCENARIO.createNitzSignal(
-                    mFakeDeviceState.elapsedRealtimeMillis(), ARBITRARY_AGE);
+            TimestampedValue<NitzData> nitzSignal =
+                    CZECHIA_SCENARIO.createNitzSignal(mFakeDeviceState.elapsedRealtime());
             TelephonyTimeZoneSuggestion expectedSuggestion = EMPTY_TIME_ZONE_SUGGESTION;
             TelephonyTimeZoneSuggestion actualSuggestion = mTimeZoneSuggester.getTimeZoneSuggestion(
                     SLOT_INDEX, scenario.getNetworkCountryIsoCode(), nitzSignal);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/AnswerToResetTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/AnswerToResetTest.java
index 3dba439..e136e96 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/AnswerToResetTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/AnswerToResetTest.java
@@ -260,26 +260,6 @@
 
     @Test
     @SmallTest
-    public void testAnswerToRestEuiccMultipleEnabledProfilesSupported() {
-        String str = "3B9F97C00AB1FE453FC6838031E073FE211F65D002341561810F29";
-        AnswerToReset atr = AnswerToReset.parseAtr(str);
-        assertNotNull(atr);
-        assertTrue(atr.isEuiccSupported());
-        assertTrue(atr.isMultipleEnabledProfilesSupported());
-    }
-
-    @Test
-    @SmallTest
-    public void testAnswerToRestEuiccMultipleEnabledProfilesNotSupported() {
-        String str = "3B9F97C00A3FC6828031E073FE211F65D002341512810F51";
-        AnswerToReset atr = AnswerToReset.parseAtr(str);
-        assertNotNull(atr);
-        assertTrue(atr.isEuiccSupported());
-        assertFalse(atr.isMultipleEnabledProfilesSupported());
-    }
-
-    @Test
-    @SmallTest
     public void testAnswerToRestEuiccNotSupportedDueToIncorrectT() {
         String str = "3F979580BEFE8210428031A073BE211797";
         AnswerToReset atr = AnswerToReset.parseAtr(str);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccCardStatusTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccCardStatusTest.java
index 5d759c2..3f7bbc0 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccCardStatusTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccCardStatusTest.java
@@ -15,27 +15,27 @@
  */
 package com.android.internal.telephony.uicc;
 
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Log;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import static org.junit.Assert.assertEquals;
 
 public class IccCardStatusTest {
 
     private IccCardStatus mIccCardStatus;
     private static final String TAG = "ICCCardStatusTest";
-
-    // Mocked classes
+    @Mock
     private IccCardApplicationStatus mApplicationStatus;
 
     @Before
     public void setUp() throws Exception {
-        mApplicationStatus = mock(IccCardApplicationStatus.class);
+        MockitoAnnotations.initMocks(this);
         mIccCardStatus = new IccCardStatus();
         /* set only one applications for cdma */
         mIccCardStatus.mApplications = new IccCardApplicationStatus[]{mApplicationStatus};
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccPhoneBookInterfaceManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccPhoneBookInterfaceManagerTest.java
index 143a530..47ebc67 100755
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccPhoneBookInterfaceManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccPhoneBookInterfaceManagerTest.java
@@ -23,12 +23,11 @@
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 
 import android.content.ContentValues;
-import android.os.AsyncResult;
 import android.os.HandlerThread;
 import android.os.Message;
+import android.os.AsyncResult;
 import android.test.suitebuilder.annotation.SmallTest;
 
 import com.android.internal.telephony.IccPhoneBookInterfaceManager;
@@ -38,6 +37,7 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
@@ -45,11 +45,13 @@
 import java.util.List;
 
 public class IccPhoneBookInterfaceManagerTest extends TelephonyTest {
-    // Mocked classes
-    private AdnRecordCache mAdnRecordCache;
-    private AdnRecord mAdnRecord;
-    private SimPhonebookRecordCache mSimPhonebookRecordCache;
 
+    @Mock
+    private AdnRecordCache mAdnRecordCache;
+    @Mock
+    private AdnRecord mAdnRecord;
+    @Mock
+    private SimPhonebookRecordCache mSimPhonebookRecordCache;
     private IccPhoneBookInterfaceManager mIccPhoneBookInterfaceMgr;
     private IccPhoneBookInterfaceManagerHandler mIccPhoneBookInterfaceManagerHandler;
     private List<AdnRecord> mAdnList = Arrays.asList(mAdnRecord);
@@ -69,10 +71,7 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mAdnRecordCache = mock(AdnRecordCache.class);
-        mAdnRecord = mock(AdnRecord.class);
-        mSimPhonebookRecordCache = mock(SimPhonebookRecordCache.class);
+        super.setUp(this.getClass().getSimpleName());
         //APP_FAM_3GPP default mPhone is GSM
         doReturn(mSimRecords).when(mPhone).getIccRecords();
         doReturn(mAdnRecordCache).when(mSimRecords).getAdnCache();
@@ -107,10 +106,6 @@
     public void tearDown() throws Exception {
         mIccPhoneBookInterfaceManagerHandler.quit();
         mIccPhoneBookInterfaceManagerHandler.join();
-        mIccPhoneBookInterfaceManagerHandler = null;
-        mIccPhoneBookInterfaceMgr = null;
-        mSimPhonebookRecordCache = null;
-        mAdnList = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccRecordsTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccRecordsTest.java
index b7a1a04..500821b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/IccRecordsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/IccRecordsTest.java
@@ -87,7 +87,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mIccRecords = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/IsimUiccRecordsTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/IsimUiccRecordsTest.java
index b97ae1f..7b4b9f3 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/IsimUiccRecordsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/IsimUiccRecordsTest.java
@@ -29,21 +29,21 @@
 
 package com.android.internal.telephony.uicc;
 
+import org.mockito.Mock;
 import static org.junit.Assert.assertEquals;
 import static org.mockito.Mockito.*;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import com.android.internal.telephony.TelephonyTest;
+import org.mockito.ArgumentCaptor;
 
+import android.content.Context;
 import android.content.Intent;
 import android.os.AsyncResult;
 import android.os.HandlerThread;
 import android.os.Message;
 
-import com.android.internal.telephony.TelephonyTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
 public class IsimUiccRecordsTest extends TelephonyTest {
 
     private IsimUiccRecords mIsimUiccRecords;
@@ -62,16 +62,16 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
+        super.setUp(this.getClass().getSimpleName());
         new IsimUiccRecordsTestHandler(TAG).start();
         waitUntilReady();
     }
 
     @After
     public void tearDown() throws Exception {
-        mIsimUiccRecords.dispose();
-        mIsimUiccRecords = null;
         super.tearDown();
+        mIsimUiccRecords.dispose();
+
     }
 
     @Test
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/PinStorageTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/PinStorageTest.java
index a8c74d5..a26c0f9 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/PinStorageTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/PinStorageTest.java
@@ -25,7 +25,6 @@
 
 import android.content.Intent;
 import android.os.PersistableBundle;
-import android.os.WorkSource;
 import android.preference.PreferenceManager;
 import android.provider.Settings;
 import android.telephony.CarrierConfigManager;
@@ -51,9 +50,6 @@
     private static final String ICCID_1 = "89010003006562472370";
     private static final String ICCID_2 = "89010003006562472399";
     private static final String ICCID_INVALID = "1234";
-    private static final String PACKAGE_NAME = "com.package.name";
-    private static final int UID = -1;
-    private static final WorkSource sWorkSource = new WorkSource(UID, PACKAGE_NAME);
 
     private int mBootCount;
     private int mSimulatedRebootsCount;
@@ -70,7 +66,7 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
+        super.setUp(this.getClass().getSimpleName());
 
         // Store boot count, so that correct value can be restored at the end.
         mBootCount = Settings.Global.getInt(
@@ -95,7 +91,8 @@
 
     @After
     public void tearDown() throws Exception {
-        mPinStorage = null;
+        super.tearDown();
+
         // Restore boot count
         if (mBootCount == -1) {
             Settings.Global.resetToDefaults(
@@ -104,7 +101,6 @@
             Settings.Global.putInt(
                     mContext.getContentResolver(), Settings.Global.BOOT_COUNT, mBootCount);
         }
-        super.tearDown();
     }
 
     @Test
@@ -142,7 +138,7 @@
     public void storePin_unattendedReboot_pinCanBeRetrievedOnce() {
         mPinStorage.storePin("1234", 0);
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -162,7 +158,7 @@
 
         mPinStorage.storePin("1234", 0);
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_ERROR);
 
         simulateReboot();
@@ -176,7 +172,7 @@
     public void storePin_unattendedReboot_pinIsRemovedAfterDelay() {
         mPinStorage.storePin("1234", 0);
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -188,7 +184,7 @@
         assertThat(mPinStorage.getPin(0, ICCID_1)).isEqualTo("");
 
         // Simulate a second unattended reboot to make sure that PIN was deleted.
-        result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -201,7 +197,7 @@
     public void storePin_unattendedRebootNotDone_pinCannotBeRetrieved() {
         mPinStorage.storePin("1234", 0);
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         // Move time forward by 60 seconds before simulating reboot
@@ -217,7 +213,7 @@
     public void storePin_unattendedReboot_iccidChange() {
         mPinStorage.storePin("1234", 0);
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -239,7 +235,7 @@
         mPinStorage.storePin("1234", 0);
         mPinStorage.clearPin(0);
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -253,7 +249,7 @@
         mPinStorage.storePin("1234", 0);
         mPinStorage.storePin("5678", 0);
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -266,7 +262,7 @@
     public void storePin_pinTooShort_pinIsNotStored() {
         mPinStorage.storePin("12", 0);
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -279,7 +275,7 @@
     public void storePin_pinTooLong_pinIsNotStored() {
         mPinStorage.storePin("123456789", 0);
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -293,7 +289,7 @@
         doReturn(ICCID_INVALID).when(mPhone).getFullIccSerialNumber();
 
         mPinStorage.storePin("1234", 0);
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
 
         simulateReboot();
 
@@ -308,7 +304,7 @@
 
         mPinStorage.storePin("1234", 0);
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -327,7 +323,7 @@
 
         mPinStorage.storePin("1234", 0);
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_PIN_REQUIRED);
 
         simulateReboot();
@@ -345,7 +341,7 @@
 
         mPinStorage.storePin("1234", 0);
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -368,7 +364,7 @@
         mContext.sendBroadcast(intent);
         processAllMessages();
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -388,7 +384,7 @@
         mContext.sendBroadcast(intent);
         processAllMessages();
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
@@ -401,7 +397,7 @@
     public void storePin_simReadyAfterUnattendedReboot_pinIsRemoved() {
         mPinStorage.storePin("1234", 0);
 
-        int result = mPinStorage.prepareUnattendedReboot(sWorkSource);
+        int result = mPinStorage.prepareUnattendedReboot();
         assertThat(result).isEqualTo(TelephonyManager.PREPARE_UNATTENDED_REBOOT_SUCCESS);
 
         simulateReboot();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/RuimRecordsTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/RuimRecordsTest.java
index a9b433f..70a1577 100755
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/RuimRecordsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/RuimRecordsTest.java
@@ -16,16 +16,18 @@
 
 package com.android.internal.telephony.uicc;
 
-import static org.junit.Assert.*;
-
+import android.content.Context;
 import android.os.AsyncResult;
 import android.os.HandlerThread;
-
 import com.android.internal.telephony.TelephonyTest;
 
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+
 
 public class RuimRecordsTest extends TelephonyTest {
 
@@ -45,14 +47,13 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
+        super.setUp(this.getClass().getSimpleName());
         new RuimRecordsTestHandler(TAG).start();
         waitUntilReady();
     }
 
     @After
     public void tearDown() throws Exception {
-        mRuimRecords = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/SIMRecordsTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/SIMRecordsTest.java
index 9183235..2e37575 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/SIMRecordsTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/SIMRecordsTest.java
@@ -24,7 +24,6 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import android.content.Context;
@@ -46,6 +45,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -60,13 +60,13 @@
     private static final int EF_SIZE = 12;
     private static final int MAX_NUM_FPLMN = 4;
 
-    // Mocked classes
-    private IccFileHandler mFhMock;
+    @Mock private IccFileHandler mFhMock;
 
     private SIMRecordsUT mSIMRecordsUT;
     private TestLooper mTestLooper;
     private Handler mTestHandler;
     private SIMRecordsReceiver mSIMRecordsReceiver;
+    private SIMRecords mSIMRecord;
 
     private class SIMRecordsUT extends SIMRecords {
         SIMRecordsUT(UiccCardApplication app, Context c,
@@ -91,7 +91,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mFhMock = mock(IccFileHandler.class);
         mTestLooper = new TestLooper();
         mTestHandler = new Handler(mTestLooper.getLooper());
         mSIMRecordsReceiver = new SIMRecordsReceiver();
@@ -111,14 +110,6 @@
 
     @After
     public void tearDown() throws Exception {
-        if (mTestLooper != null) {
-            mTestLooper.dispatchAll();
-            mTestLooper = null;
-        }
-        mTestHandler.removeCallbacksAndMessages(null);
-        mTestHandler = null;
-        mSIMRecordsReceiver = null;
-        mSIMRecordsUT = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/SimPhonebookRecordCacheTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/SimPhonebookRecordCacheTest.java
index 1855276..24db77d 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/SimPhonebookRecordCacheTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/SimPhonebookRecordCacheTest.java
@@ -23,17 +23,18 @@
 
 import android.os.AsyncResult;
 import android.os.HandlerThread;
+import android.os.Handler;
 import android.os.Message;
 
 import com.android.internal.telephony.TelephonyTest;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.ArrayList;
-import java.util.List;
-
 public class SimPhonebookRecordCacheTest extends TelephonyTest {
     private static final int EVENT_PHONEBOOK_RECORDS_RECEIVED = 2;
 
@@ -56,8 +57,8 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mSimPhonebookRecordHandler = new SimPhonebookRecordHandler(getClass().getSimpleName());
+        super.setUp(this.getClass().getSimpleName());
+        mSimPhonebookRecordHandler = new SimPhonebookRecordHandler(this.getClass().getSimpleName());
         mSimPhonebookRecordHandler.start();
         waitUntilReady();
     }
@@ -66,8 +67,6 @@
     public void tearDown() throws Exception {
         mSimPhonebookRecordHandler.quit();
         mSimPhonebookRecordHandler.join();
-        mSimPhonebookRecordHandler = null;
-        mSimPhonebookRecordCacheUt = null;
         super.tearDown();
     }
 
@@ -94,10 +93,8 @@
         mSimPhonebookRecordCacheUt.requestLoadAllPbRecords(null);
         waitForLastHandlerAction(mSimPhonebookRecordCacheUt);
 
-        mSimPhonebookRecordCacheUt.clear();
-
         List<SimPhonebookRecord> records = new ArrayList<SimPhonebookRecord>();
-        records.add(new SimPhonebookRecord(1, "ABC", "12345", null, null));
+        records.add(new SimPhonebookRecord(10, "ABC", "12345", null, null));
         AsyncResult ar = new AsyncResult(null, new ReceivedPhonebookRecords(4, records), null);
         Message msg = Message.obtain(mSimPhonebookRecordCacheUt,
                 EVENT_PHONEBOOK_RECORDS_RECEIVED, ar);
@@ -106,7 +103,7 @@
         assertFalse(mSimPhonebookRecordCacheUt.isLoading());
         List<AdnRecord> adnRecords = mSimPhonebookRecordCacheUt.getAdnRecords();
         assertEquals(adnRecords.size(), 1);
-        assertEquals(adnRecords.get(0).getRecId(), 1);
+        assertEquals(adnRecords.get(0).getRecId(), 10);
     }
 
     @Test
@@ -120,46 +117,34 @@
 
     @Test
     public void testUpdatePhonebookRecord() {
-        mSimulatedCommands.notifySimPhonebookChanged();
-        waitForLastHandlerAction(mSimPhonebookRecordCacheUt);
         List<AdnRecord> adnRecords = mSimPhonebookRecordCacheUt.getAdnRecords();
-        if (mSimPhonebookRecordCacheUt.ENABLE_INFLATE_WITH_EMPTY_RECORDS) {
-            assertEquals(adnRecords.size(), 1); // Max ADN from capacity
-        } else {
-            assertEquals(adnRecords.size(), 0);
-        }
-        mSimPhonebookRecordCacheUt.clear();
+        assertEquals(adnRecords.size(), 0);
 
-        AdnRecord newAdn = new AdnRecord(IccConstants.EF_ADN, 1, "AB", "123", null, null);
+        AdnRecord newAdn = new AdnRecord(0, 20, "AB", "123", null, null);
         // add
         mSimPhonebookRecordCacheUt.updateSimPbAdnBySearch(null, newAdn, null);
         waitForLastHandlerAction(mSimPhonebookRecordCacheUt);
         adnRecords = mSimPhonebookRecordCacheUt.getAdnRecords();
         assertEquals(adnRecords.size(), 1);
         AdnRecord oldAdn = adnRecords.get(0);
-        assertEquals(oldAdn.getRecId(), 1);
+        assertEquals(oldAdn.getRecId(), 20);
         assertEquals(oldAdn.getAlphaTag(), "AB");
         assertEquals(oldAdn.getNumber(), "123");
         // update
-        newAdn = new AdnRecord(IccConstants.EF_ADN, 1, "ABCD", "123456789", null, null);
+        newAdn = new AdnRecord(0, 20, "ABCD", "123456789", null, null);
         mSimPhonebookRecordCacheUt.updateSimPbAdnBySearch(oldAdn, newAdn, null);
         waitForLastHandlerAction(mSimPhonebookRecordCacheUt);
         adnRecords = mSimPhonebookRecordCacheUt.getAdnRecords();
         assertEquals(adnRecords.size(), 1);
         oldAdn = adnRecords.get(0);
-        assertEquals(oldAdn.getRecId(), 1);
+        assertEquals(oldAdn.getRecId(), 20);
         assertEquals(oldAdn.getAlphaTag(), "ABCD");
         assertEquals(oldAdn.getNumber(), "123456789");
         // Delete
-        newAdn = new AdnRecord(IccConstants.EF_ADN, 1, null, null, null, null);
+        newAdn = new AdnRecord(0, 20, null, null, null, null);
         mSimPhonebookRecordCacheUt.updateSimPbAdnBySearch(oldAdn, newAdn, null);
         waitForLastHandlerAction(mSimPhonebookRecordCacheUt);
         adnRecords = mSimPhonebookRecordCacheUt.getAdnRecords();
-        if (mSimPhonebookRecordCacheUt.ENABLE_INFLATE_WITH_EMPTY_RECORDS) {
-            assertEquals(adnRecords.size(), 1);
-            assertTrue(adnRecords.get(0).isEmpty());
-        } else {
-            assertEquals(adnRecords.size(), 0);
-        }
+        assertEquals(adnRecords.size(), 0);
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardApplicationTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardApplicationTest.java
index 59bb239..5b57765 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardApplicationTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardApplicationTest.java
@@ -22,7 +22,6 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import android.os.AsyncResult;
@@ -40,15 +39,16 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class UiccCardApplicationTest extends TelephonyTest {
-    // Mocked classes
-    private IccCardApplicationStatus mUiccCardAppStatus;
-    private UiccProfile mUiccProfile;
-
     private UiccCardApplication mUiccCardApplication;
+    @Mock
+    private IccCardApplicationStatus mUiccCardAppStatus;
+    @Mock
+    private UiccProfile mUiccProfile;
     private Handler mHandler;
     private int mAttemptsRemaining = -1;
     private CommandException mException = null;
@@ -62,9 +62,7 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mUiccCardAppStatus = mock(IccCardApplicationStatus.class);
-        mUiccProfile = mock(UiccProfile.class);
+        super.setUp(this.getClass().getSimpleName());
         //set initial state of app status
         mUiccCardAppStatus.app_type = IccCardApplicationStatus.AppType.APPTYPE_SIM;
         mUiccCardAppStatus.aid = TAG;
@@ -104,14 +102,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mUiccProfile = null;
-        if (mHandler != null) {
-            mHandler.removeCallbacksAndMessages(null);
-            mHandler = null;
-        }
-        mException = null;
-        mAppState = null;
-        mUiccCardApplication = null;
         super.tearDown();
     }
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java
index b30c3a7..5ff4aed 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCardTest.java
@@ -16,11 +16,9 @@
 package com.android.internal.telephony.uicc;
 
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.mock;
 
-import android.telephony.TelephonyManager;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
@@ -31,45 +29,50 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
 public class UiccCardTest extends TelephonyTest {
-
-    private static final int INVALID_PORT_ID = -1;
-
     private UiccCard mUiccCard;
 
     private IccIoResult mIccIoResult;
 
-    // Mocked classes
+    @Mock
     private IccCardStatus mIccCardStatus;
 
+    private IccCardApplicationStatus composeUiccApplicationStatus(
+            IccCardApplicationStatus.AppType appType,
+            IccCardApplicationStatus.AppState appState, String aid) {
+        IccCardApplicationStatus mIccCardAppStatus = new IccCardApplicationStatus();
+        mIccCardAppStatus.aid = aid;
+        mIccCardAppStatus.app_type = appType;
+        mIccCardAppStatus.app_state = appState;
+        mIccCardAppStatus.pin1 = mIccCardAppStatus.pin2 =
+                IccCardStatus.PinState.PINSTATE_ENABLED_VERIFIED;
+        return mIccCardAppStatus;
+    }
+
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mIccCardStatus = mock(IccCardStatus.class);
         /* initially there are no application available */
         mIccCardStatus.mApplications = new IccCardApplicationStatus[]{};
         mIccCardStatus.mCdmaSubscriptionAppIndex =
                 mIccCardStatus.mImsSubscriptionAppIndex =
                         mIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1;
         mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
-        mIccCardStatus.mSlotPortMapping = new IccSlotPortMapping();
-        mIccCardStatus.mSlotPortMapping.mPhysicalSlotIndex = 0;
-        mIccCardStatus.mSlotPortMapping.mPortIndex = 0;
+
         mIccIoResult = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes("FF40"));
         mSimulatedCommands.setIccIoResultForApduLogicalChannel(mIccIoResult);
         mUiccCard = new UiccCard(mContext, mSimulatedCommands, mIccCardStatus, 0 /* phoneId */,
-            new Object(), false);
+            new Object());
         processAllMessages();
         logd("create UiccCard");
     }
 
     @After
     public void tearDown() throws Exception {
-        mUiccCard = null;
-        mIccIoResult = null;
         super.tearDown();
     }
 
@@ -77,24 +80,41 @@
     @SmallTest
     public void testUiccCartdInfoCorrectness() {
         /* before update correctness test */
+        assertEquals(0, mUiccCard.getNumApplications());
         assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccCard.getCardState());
-        assertEquals(1, mUiccCard.getUiccPortList().length);
+        assertNull(mUiccCard.getUniversalPinState());
+        assertNull(mUiccCard.getOperatorBrandOverride());
+        /* UiccProfile mock should return false */
+        assertFalse(mUiccCard.areCarrierPriviligeRulesLoaded());
+        for (IccCardApplicationStatus.AppType mAppType :
+                IccCardApplicationStatus.AppType.values()) {
+            assertFalse(mUiccCard.isApplicationOnIcc(mAppType));
+        }
     }
 
     @Test
     @SmallTest
     public void testUpdateUiccCardState() {
+        int mChannelId = 1;
         /* set card as present */
         mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
+        /* Mock open Channel ID 1 */
+        mSimulatedCommands.setOpenChannelId(mChannelId);
         logd("Update UICC Card State");
-        mUiccCard.update(mContext, mSimulatedCommands, mIccCardStatus, 0);
+        mUiccCard.update(mContext, mSimulatedCommands, mIccCardStatus);
         /* try to create a new CarrierPrivilege, loading state -> loaded state */
         processAllMessages();
 
         assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccCard.getCardState());
-        // make sure duplicate UiccPort objects are not created after update API call
-        assertEquals(1, mUiccCard.getUiccPortList().length);
-        assertNull(mUiccCard.getUiccPort(INVALID_PORT_ID));
-        assertNotNull(mUiccCard.getUiccPort(TelephonyManager.DEFAULT_PORT_INDEX));
+
+        /* todo: This part should move to UiccProfileTest
+        assertTrue(mUicccard.areCarrierPriviligeRulesLoaded());
+        verify(mSimulatedCommandsVerifier, times(2)).iccOpenLogicalChannel(isA(String.class),
+                anyInt(), isA(Message.class));
+        verify(mSimulatedCommandsVerifier, times(2)).iccTransmitApduLogicalChannel(
+                eq(mChannelId), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), anyString(),
+                isA(Message.class)
+        );
+        */
     }
 }
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java
index c885f5a..7a16e5b 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccCarrierPrivilegeRulesTest.java
@@ -22,7 +22,6 @@
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
 
 import android.content.pm.Signature;
 import android.os.AsyncResult;
@@ -39,6 +38,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
@@ -56,19 +56,18 @@
     private static final String ARAD = "A00000015144414300";
     private static final String PKCS15_AID = "A000000063504B43532D3135";
 
-    // Mocked classes
+    @Mock
     private UiccProfile mUiccProfile;
 
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mUiccProfile = mock(UiccProfile.class);
     }
 
     @After
     public void tearDown() throws Exception {
-        mUiccCarrierPrivilegeRules = null;
         super.tearDown();
+        mUiccCarrierPrivilegeRules = null;
     }
 
     private void testHelper(String hexString) {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
index 0344e57..a00e110 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccControllerTest.java
@@ -25,7 +25,6 @@
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -35,7 +34,6 @@
 import android.preference.PreferenceManager;
 import android.telephony.TelephonyManager;
 import android.telephony.UiccCardInfo;
-import android.telephony.UiccPortInfo;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
 
@@ -50,9 +48,10 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.ArrayList;
-import java.util.Collections;
+
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -64,16 +63,20 @@
     private static final int EVENT_GET_SLOT_STATUS_DONE = 4;
     private static final int EVENT_SIM_REFRESH = 8;
     private static final int EVENT_EID_READY = 9;
-
-    // Mocked classes
+    @Mock
     private Handler mMockedHandler;
+    @Mock
     private IccCardStatus mIccCardStatus;
+    @Mock
     private UiccSlot mMockSlot;
+    @Mock
     private UiccSlot mMockRemovableEuiccSlot;
+    @Mock
     private UiccCard mMockCard;
+    @Mock
     private EuiccCard mMockEuiccCard;
+    @Mock
     private UiccProfile mMockProfile;
-    private UiccPort mMockPort;
 
     private IccCardApplicationStatus composeUiccApplicationStatus(
             IccCardApplicationStatus.AppType appType,
@@ -89,15 +92,7 @@
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mMockedHandler = mock(Handler.class);
-        mIccCardStatus = mock(IccCardStatus.class);
-        mMockSlot = mock(UiccSlot.class);
-        mMockRemovableEuiccSlot = mock(UiccSlot.class);
-        mMockCard = mock(UiccCard.class);
-        mMockEuiccCard = mock(EuiccCard.class);
-        mMockProfile = mock(UiccProfile.class);
-        mMockPort = mock(UiccPort.class);
+        super.setUp(this.getClass().getSimpleName());
         // some tests use use the shared preferences in the runner context, so reset them here
         PreferenceManager.getDefaultSharedPreferences(InstrumentationRegistry.getContext())
                 .edit().clear().commit();
@@ -117,8 +112,7 @@
         mSimulatedCommands.setIccCardStatus(mIccCardStatus);
         // for testing we pretend slotIndex is set. In reality it would be invalid on older versions
         // (before 1.2) of hal
-        mIccCardStatus.mSlotPortMapping = new IccSlotPortMapping();
-        mIccCardStatus.mSlotPortMapping.mPhysicalSlotIndex = 0;
+        mIccCardStatus.physicalSlotIndex = 0;
         mUiccControllerUT = UiccController.make(mContext);
         // reset sLastSlotStatus so that onGetSlotStatusDone always sees a change in the slot status
         mUiccControllerUT.sLastSlotStatus = null;
@@ -127,7 +121,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mUiccControllerUT = null;
         super.tearDown();
     }
 
@@ -248,9 +241,7 @@
         // Mock out UiccSlots
         mUiccControllerUT.mUiccSlots[0] = mMockSlot;
         doReturn(mMockCard).when(mMockSlot).getUiccCard();
-        doReturn(mMockPort).when(mMockCard).getUiccPort(0);
-        doReturn("A1B2C3D4").when(mMockPort).getIccId();
-
+        doReturn("A1B2C3D4").when(mMockCard).getIccId();
         doReturn("A1B2C3D4").when(mMockCard).getCardId();
         doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mMockCard).getCardState();
 
@@ -261,9 +252,7 @@
         ics.atr = "abcdef0123456789abcdef";
         ics.iccid = "123451234567890";
         ics.eid = "A1B2C3D4";
-        ics.mSlotPortMapping = new IccSlotPortMapping();
-        ics.mSlotPortMapping.mPhysicalSlotIndex = 0;
-        ics.mSlotPortMapping.mPortIndex = 0;
+        ics.physicalSlotIndex = 0;
         AsyncResult ar = new AsyncResult(null, ics, null);
         Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_ICC_STATUS_DONE, ar);
         mUiccControllerUT.handleMessage(msg);
@@ -297,11 +286,7 @@
 
         // simulate slot status loaded so that the UiccController sets the card ID
         IccSlotStatus iss = new IccSlotStatus();
-        IccSimPortInfo simPortInfo = new IccSimPortInfo();
-        simPortInfo.mPortActive = true;
-        simPortInfo.mLogicalSlotIndex = 0;
-        simPortInfo.mIccId = "fake-iccid";
-        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
+        iss.setSlotState(1 /* active */);
         iss.eid = "ABADACB";
         ArrayList<IccSlotStatus> status = new ArrayList<IccSlotStatus>();
         status.add(iss);
@@ -324,11 +309,7 @@
 
         // simulate slot status loaded so that the UiccController sets the card ID
         IccSlotStatus iss = new IccSlotStatus();
-        IccSimPortInfo simPortInfo = new IccSimPortInfo();
-        simPortInfo.mPortActive = true;
-        simPortInfo.mLogicalSlotIndex = 0;
-        simPortInfo.mIccId = "fake-iccid";
-        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
+        iss.setSlotState(1 /* active */);
         iss.eid = "AB123456";
         ArrayList<IccSlotStatus> status = new ArrayList<IccSlotStatus>();
         status.add(iss);
@@ -353,15 +334,8 @@
         doReturn("ASDF1234").when(mMockCard).getCardId();
         doReturn(true).when(mMockSlot).isRemovable();
         doReturn("A1B2C3D4").when(mMockCard).getCardId();
+        doReturn("123451234567890").when(mMockCard).getIccId();
         doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mMockCard).getCardState();
-        doReturn(true).when(mMockSlot).isActive(); //TODO: use UICCPort when ready
-
-        // Mock out UiccPort
-        doReturn(new int[]{0}).when(mMockSlot).getPortList();
-        doReturn(mMockPort).when(mMockCard).getUiccPort(0);
-        doReturn("123451234567890").when(mMockPort).getIccId();
-        doReturn(true).when(mMockSlot).isPortActive(0);
-        doReturn("123451234567890").when(mMockSlot).getIccId(0);
 
         // simulate card status loaded so that the UiccController sets the card ID
         IccCardStatus ics = new IccCardStatus();
@@ -369,9 +343,7 @@
         ics.setUniversalPinState(3 /* disabled */);
         ics.atr = "abcdef0123456789abcdef";
         ics.iccid = "123451234567890";
-        ics.mSlotPortMapping = new IccSlotPortMapping();
-        ics.mSlotPortMapping.mPhysicalSlotIndex = 0;
-        ics.mSlotPortMapping.mPortIndex = 0;
+        ics.physicalSlotIndex = 0;
         AsyncResult ar = new AsyncResult(null, ics, null);
         Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_ICC_STATUS_DONE, ar);
         mUiccControllerUT.handleMessage(msg);
@@ -381,14 +353,9 @@
                 false,     // isEuicc
                 0,         // cardId
                 null,      // eid
+                ics.iccid, // iccid
                 0,         // slotIndex
-                true, // isRemovable
-                false,   //  isMultipleEnabledProfileSupported
-                Collections.singletonList(new UiccPortInfo(
-                        ics.iccid, // iccid
-                        ics.mSlotPortMapping.mPortIndex, //portIdx
-                        0, //logicalSlotIdx
-                        true))); //isActive
+                true);     // isRemovable
         assertEquals(uiccCardInfo, mUiccControllerUT.getAllUiccCardInfos().get(0));
     }
 
@@ -404,15 +371,8 @@
         doReturn("ASDF1234").when(mMockCard).getCardId();
         doReturn(true).when(mMockSlot).isRemovable();
         doReturn("A1B2C3D4").when(mMockCard).getCardId();
+        doReturn("123451234567890F").when(mMockCard).getIccId();
         doReturn(IccCardStatus.CardState.CARDSTATE_PRESENT).when(mMockCard).getCardState();
-        doReturn(true).when(mMockSlot).isActive(); //TODO: use UICCPort when ready
-
-        // Mock out UiccPort
-        doReturn(mMockPort).when(mMockCard).getUiccPort(0);
-        doReturn("123451234567890F").when(mMockPort).getIccId();
-        doReturn(new int[]{0}).when(mMockSlot).getPortList();
-        doReturn(true).when(mMockSlot).isPortActive(0);
-        doReturn("123451234567890F").when(mMockSlot).getIccId(0);
 
         // simulate card status loaded so that the UiccController sets the card ID
         IccCardStatus ics = new IccCardStatus();
@@ -420,9 +380,7 @@
         ics.setUniversalPinState(3 /* disabled */);
         ics.atr = "abcdef0123456789abcdef";
         ics.iccid = "123451234567890F";
-        ics.mSlotPortMapping = new IccSlotPortMapping();
-        ics.mSlotPortMapping.mPhysicalSlotIndex = 0;
-        ics.mSlotPortMapping.mPortIndex = 0;
+        ics.physicalSlotIndex = 0;
         AsyncResult ar = new AsyncResult(null, ics, null);
         Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_ICC_STATUS_DONE, ar);
         mUiccControllerUT.handleMessage(msg);
@@ -432,14 +390,9 @@
                 false,     // isEuicc
                 0,         // cardId
                 null,      // eid
+                IccUtils.stripTrailingFs(ics.iccid), //iccid without ending F
                 0,         // slotIndex
-                true, // isRemovable
-                false,   //  isMultipleEnabledProfileSupported
-                Collections.singletonList(new UiccPortInfo(
-                        IccUtils.stripTrailingFs(ics.iccid), // iccid
-                        0, // portIdx
-                        0, //logicalSlotIdx
-                        true))); //isActive
+                true);     // isRemovable
         assertEquals(uiccCardInfo, mUiccControllerUT.getAllUiccCardInfos().get(0));
     }
 
@@ -452,13 +405,8 @@
         mUiccControllerUT.mUiccSlots[0] = mMockSlot;
         doReturn(true).when(mMockSlot).isEuicc();
         doReturn(null).when(mMockSlot).getUiccCard();
+        doReturn("123451234567890").when(mMockSlot).getIccId();
         doReturn(false).when(mMockSlot).isRemovable();
-        doReturn(true).when(mMockSlot).isActive(); //TODO: use UICCPort when ready
-
-        // Mock out Port Index and IccId
-        doReturn(new int[]{0}).when(mMockSlot).getPortList();
-        doReturn("123451234567890").when(mMockSlot).getIccId(0);
-        doReturn(-1).when(mMockSlot).getPhoneIdFromPortIndex(0);
 
         // simulate card status loaded so that the UiccController sets the card ID
         IccCardStatus ics = new IccCardStatus();
@@ -467,10 +415,6 @@
         ics.atr = "abcdef0123456789abcdef";
         ics.iccid = "123451234567890";
         ics.eid = "A1B2C3D4";
-        ics.mSlotPortMapping = new IccSlotPortMapping();
-        ics.mSlotPortMapping.mPhysicalSlotIndex = 0;
-        ics.mSlotPortMapping.mPortIndex = 0;
-
         AsyncResult ar = new AsyncResult(null, ics, null);
         Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_ICC_STATUS_DONE, ar);
         mUiccControllerUT.handleMessage(msg);
@@ -480,14 +424,9 @@
                 true,                                   // isEuicc
                 TelephonyManager.UNINITIALIZED_CARD_ID, // cardId
                 null,                                   // eid
+                ics.iccid,                              // iccid
                 0,                                      // slotIndex
-                false,                      // isRemovable
-                false,   //  isMultipleEnabledProfileSupported
-                Collections.singletonList(new UiccPortInfo(
-                        ics.iccid, // iccid
-                        0, // portIdx TODO: need to mock UiccPort
-                        -1, //logicalSlotIdx inactive port
-                        false)));    //isActive
+                false);                                 // isRemovable
         assertEquals(uiccCardInfo, mUiccControllerUT.getAllUiccCardInfos().get(0));
     }
 
@@ -508,12 +447,8 @@
         ics.setUniversalPinState(3 /* disabled */);
         ics.atr = "abcdef0123456789abcdef";
         ics.iccid = "123451234567890";
-        ics.mSlotPortMapping = new IccSlotPortMapping();
-        ics.mSlotPortMapping.mPhysicalSlotIndex = UiccController.INVALID_SLOT_ID;
         // make it seem like EID is not supported by setting physical slot = -1 like on HAL < 1.2
-
-        mSimulatedCommands.setSupportsEid(false);
-
+        ics.physicalSlotIndex = UiccController.INVALID_SLOT_ID;
         AsyncResult ar = new AsyncResult(null, ics, null);
         Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_ICC_STATUS_DONE, ar);
         mUiccControllerUT.handleMessage(msg);
@@ -521,8 +456,6 @@
         // assert that the default eUICC card Id is UNSUPPORTED_CARD_ID
         assertEquals(TelephonyManager.UNSUPPORTED_CARD_ID,
                 mUiccControllerUT.getCardIdForDefaultEuicc());
-
-        mSimulatedCommands.setSupportsEid(true);
     }
 
     /**
@@ -549,18 +482,10 @@
 
         // simulate slot status loaded so that the UiccController sets the card ID
         IccSlotStatus iss1 = new IccSlotStatus();
-        IccSimPortInfo simPortInfo1 = new IccSimPortInfo();
-        simPortInfo1.mPortActive = true;
-        simPortInfo1.mLogicalSlotIndex = 0;
-        simPortInfo1.mIccId = "fake-iccid";
-        iss1.mSimPortInfos = new IccSimPortInfo[] {simPortInfo1};
+        iss1.setSlotState(1 /* active */);
         iss1.eid = "AB123456";
         IccSlotStatus iss2 = new IccSlotStatus();
-        IccSimPortInfo simPortInfo2 = new IccSimPortInfo();
-        simPortInfo2.mPortActive = true;
-        simPortInfo2.mLogicalSlotIndex = 1;
-        simPortInfo2.mIccId = "fake-iccid";
-        iss2.mSimPortInfos = new IccSimPortInfo[] {simPortInfo2};
+        iss2.setSlotState(1 /* active */);
         iss2.eid = "ZYW13094";
         ArrayList<IccSlotStatus> status = new ArrayList<IccSlotStatus>();
         status.add(iss1);
@@ -600,18 +525,10 @@
 
         // simulate slot status loaded so that the UiccController sets the card ID
         IccSlotStatus iss1 = new IccSlotStatus();
-        IccSimPortInfo simPortInfo1 = new IccSimPortInfo();
-        simPortInfo1.mPortActive = true;
-        simPortInfo1.mLogicalSlotIndex = 1;
-        simPortInfo1.mIccId = "fake-iccid";
-        iss1.mSimPortInfos = new IccSimPortInfo[] {simPortInfo1};
+        iss1.setSlotState(1 /* active */);
         iss1.eid = "AB123456";
         IccSlotStatus iss2 = new IccSlotStatus();
-        IccSimPortInfo simPortInfo2 = new IccSimPortInfo();
-        simPortInfo2.mPortActive = true;
-        simPortInfo2.mLogicalSlotIndex = 1;
-        simPortInfo2.mIccId = "fake-iccid";
-        iss2.mSimPortInfos = new IccSimPortInfo[] {simPortInfo2};
+        iss2.setSlotState(1 /* active */);
         iss2.eid = "ZYW13094";
         ArrayList<IccSlotStatus> status = new ArrayList<IccSlotStatus>();
         status.add(iss1);
@@ -653,18 +570,10 @@
 
         // simulate slot status loaded with no EID provided (like HAL < 1.4)
         IccSlotStatus iss1 = new IccSlotStatus();
-        IccSimPortInfo simPortInfo1 = new IccSimPortInfo();
-        simPortInfo1.mPortActive = false;
-        simPortInfo1.mLogicalSlotIndex = 1;
-        simPortInfo1.mIccId = "fake-iccid";
-        iss1.mSimPortInfos = new IccSimPortInfo[] {simPortInfo1};
+        iss1.setSlotState(0 /* inactive */);
         iss1.eid = "";
         IccSlotStatus iss2 = new IccSlotStatus();
-        IccSimPortInfo simPortInfo2 = new IccSimPortInfo();
-        simPortInfo2.mPortActive = true;
-        simPortInfo2.mLogicalSlotIndex = 1;
-        simPortInfo2.mIccId = "fake-iccid";
-        iss2.mSimPortInfos = new IccSimPortInfo[] {simPortInfo2};
+        iss2.setSlotState(1 /* active */);
         iss2.eid = "";
         ArrayList<IccSlotStatus> status = new ArrayList<IccSlotStatus>();
         status.add(iss1);
@@ -702,7 +611,7 @@
         mUiccControllerUT.mUiccSlots[0] = mMockSlot;
         doReturn(true).when(mMockSlot).isEuicc();
         doReturn(null).when(mMockSlot).getUiccCard();
-        //doReturn("123451234567890").when(mMockSlot).getIccId();
+        doReturn("123451234567890").when(mMockSlot).getIccId();
         doReturn(false).when(mMockSlot).isRemovable();
 
         // If APDU has already happened, the EuiccCard already knows EID
@@ -718,8 +627,6 @@
         ics.iccid = "123451234567890";
         // the IccCardStatus does not contain EID, but it is known from previous APDU
         ics.eid = null;
-        ics.mSlotPortMapping = new IccSlotPortMapping();
-
         AsyncResult ar = new AsyncResult(null, ics, null);
         Message msg = Message.obtain(mUiccControllerUT, EVENT_GET_ICC_STATUS_DONE, ar);
         mUiccControllerUT.handleMessage(msg);
@@ -733,18 +640,10 @@
     public void testSlotStatusChanged() {
         // simulate slot status loaded so that the UiccController sets the last slot status
         IccSlotStatus iss1 = new IccSlotStatus();
-        IccSimPortInfo simPortInfo1 = new IccSimPortInfo();
-        simPortInfo1.mPortActive = false;
-        simPortInfo1.mLogicalSlotIndex = 1;
-        simPortInfo1.mIccId = "fake-iccid";
-        iss1.mSimPortInfos = new IccSimPortInfo[] {simPortInfo1};
+        iss1.setSlotState(1 /* active */);
         iss1.eid = "eid1";
         IccSlotStatus iss2 = new IccSlotStatus();
-        IccSimPortInfo simPortInfo2 = new IccSimPortInfo();
-        simPortInfo2.mPortActive = true;
-        simPortInfo2.mLogicalSlotIndex = 1;
-        simPortInfo2.mIccId = "fake-iccid";
-        iss2.mSimPortInfos = new IccSimPortInfo[] {simPortInfo2};
+        iss2.setSlotState(1 /* active */);
         iss2.eid = "eid2";
         ArrayList<IccSlotStatus> status = new ArrayList<IccSlotStatus>();
         status.add(iss1);
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java
deleted file mode 100644
index bddb044..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccPortTest.java
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.internal.telephony.uicc;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import android.os.Binder;
-import android.telephony.TelephonyManager;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import com.android.internal.telephony.IccLogicalChannelRequest;
-import com.android.internal.telephony.TelephonyTest;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class UiccPortTest extends TelephonyTest {
-    private static final int CHANNEL_ID = 1;
-
-    // Mocked classes
-    private UiccCard mUiccCard;
-    private IccCardStatus mIccCardStatus;
-
-    private UiccPort mUiccPort;
-
-    private IccIoResult mIccIoResult;
-
-    private int mPhoneId = 0;
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mUiccCard = mock(UiccCard.class);
-        mIccCardStatus = mock(IccCardStatus.class);
-        /* initially there are no application available */
-        mIccCardStatus.mApplications = new IccCardApplicationStatus[]{};
-        mIccCardStatus.mCdmaSubscriptionAppIndex =
-                mIccCardStatus.mImsSubscriptionAppIndex =
-                        mIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1;
-        mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
-        mIccCardStatus.mSlotPortMapping = new IccSlotPortMapping();
-        mIccCardStatus.mSlotPortMapping.mPhysicalSlotIndex = 0;
-        mIccCardStatus.mSlotPortMapping.mPortIndex = 0;
-        mIccIoResult = new IccIoResult(0x90, 0x00, IccUtils.hexStringToBytes("FF40"));
-        mSimulatedCommands.setIccIoResultForApduLogicalChannel(mIccIoResult);
-        mUiccPort = new UiccPort(mContext, mSimulatedCommands, mIccCardStatus,
-                mPhoneId /* phoneId */, new Object(), mUiccCard);
-        processAllMessages();
-        logd("create UiccPort");
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mUiccPort = null;
-        mIccIoResult = null;
-        super.tearDown();
-    }
-
-    @Test
-    @SmallTest
-    public void testUiccPortdInfoCorrectness() {
-        /* before update correctness test */
-        assertEquals(0, mUiccPort.getNumApplications());
-        assertNull(mUiccPort.getUniversalPinState());
-        assertNull(mUiccPort.getOperatorBrandOverride());
-        for (IccCardApplicationStatus.AppType mAppType :
-                IccCardApplicationStatus.AppType.values()) {
-            assertFalse(mUiccPort.isApplicationOnIcc(mAppType));
-        }
-        assertEquals(mPhoneId, mUiccPort.getPhoneId());
-        assertEquals(TelephonyManager.DEFAULT_PORT_INDEX, mUiccPort.getPortIdx());
-    }
-
-    @Test
-    @SmallTest
-    public void testGetOpenLogicalChannelRecord_noChannelOpened_shouldReturnNull() {
-        assertThat(mUiccPort.getOpenLogicalChannelRecord(CHANNEL_ID)).isNull();
-    }
-
-    @Test
-    @SmallTest
-    public void testOnLogicalChannelOpened_withChannelOpen_recordShouldMatch() {
-        IccLogicalChannelRequest request = getIccLogicalChannelRequest();
-
-        mUiccPort.onLogicalChannelOpened(request);
-
-        UiccPort.OpenLogicalChannelRecord record = mUiccPort.getOpenLogicalChannelRecord(
-                CHANNEL_ID);
-        assertThat(record).isNotNull();
-    }
-
-    @Test
-    @SmallTest
-    public void testOnOpenLogicalChannelClosed_withChannelOpenThenClose_noRecordLeft() {
-        IccLogicalChannelRequest request = getIccLogicalChannelRequest();
-
-        mUiccPort.onLogicalChannelOpened(request);
-        mUiccPort.onLogicalChannelClosed(CHANNEL_ID);
-
-        UiccPort.OpenLogicalChannelRecord record = mUiccPort.getOpenLogicalChannelRecord(
-                CHANNEL_ID);
-        assertThat(record).isNull();
-    }
-
-    @Test
-    @SmallTest
-    public void testClientDied_withChannelOpened_shouldGetCleanup() {
-        IccLogicalChannelRequest request = getIccLogicalChannelRequest();
-        mUiccPort.onLogicalChannelOpened(request);
-
-        UiccPort.OpenLogicalChannelRecord record = mUiccPort.getOpenLogicalChannelRecord(
-                CHANNEL_ID);
-        record.binderDied();
-
-        record = mUiccPort.getOpenLogicalChannelRecord(CHANNEL_ID);
-        assertThat(record).isNull();
-        verify(mUiccProfile).iccCloseLogicalChannel(eq(CHANNEL_ID), eq(null));
-    }
-
-    private IccLogicalChannelRequest getIccLogicalChannelRequest() {
-        IccLogicalChannelRequest request = new IccLogicalChannelRequest();
-        request.channel = CHANNEL_ID;
-        request.subId = 0;
-        request.binder = new Binder();
-        return request;
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java
index 856639a..199ff34 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccProfileTest.java
@@ -29,7 +29,6 @@
 import static org.mockito.Mockito.atLeast;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.isA;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
@@ -56,6 +55,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
 
 import java.util.Map;
 
@@ -72,12 +72,14 @@
 
     private static final int UICCPROFILE_CARRIER_PRIVILEGE_LOADED_EVENT = 3;
 
-    // Mocked classes
+    @Mock
     private CatService mCAT;
+    @Mock
     private IccCardStatus mIccCardStatus;
+    @Mock
     private Handler mMockedHandler;
+    @Mock
     private UiccCard mUiccCard;
-    private SubscriptionInfo mSubscriptionInfo;
 
     private IccCardApplicationStatus composeUiccApplicationStatus(
             IccCardApplicationStatus.AppType appType,
@@ -94,11 +96,6 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mCAT = mock(CatService.class);
-        mIccCardStatus = mock(IccCardStatus.class);
-        mMockedHandler = mock(Handler.class);
-        mUiccCard = mock(UiccCard.class);
-        mSubscriptionInfo = mock(SubscriptionInfo.class);
          /* initially there are no application available, but the array should not be empty. */
         IccCardApplicationStatus umtsApp = composeUiccApplicationStatus(
                 IccCardApplicationStatus.AppType.APPTYPE_USIM,
@@ -119,8 +116,6 @@
 
     @After
     public void tearDown() throws Exception {
-        mUiccProfile = null;
-        mIccIoResult = null;
         super.tearDown();
     }
 
@@ -198,7 +193,7 @@
         mUiccProfile.update(mContext, mSimulatedCommands, mIccCardStatus);
         processAllMessages();
 
-        assertTrue(mUiccProfile.areCarrierPrivilegeRulesLoaded());
+        assertTrue(mUiccProfile.areCarrierPriviligeRulesLoaded());
         verify(mSimulatedCommandsVerifier, times(2)).iccOpenLogicalChannel(isA(String.class),
                 anyInt(), isA(Message.class));
         verify(mSimulatedCommandsVerifier, times(2)).iccTransmitApduLogicalChannel(
@@ -218,6 +213,19 @@
 
     @Test
     @SmallTest
+    public void testCarrierPriviledgeLoadedListener() {
+        mUiccProfile.registerForCarrierPrivilegeRulesLoaded(mMockedHandler,
+                UICCPROFILE_CARRIER_PRIVILEGE_LOADED_EVENT, null);
+        ArgumentCaptor<Message> mCaptorMessage = ArgumentCaptor.forClass(Message.class);
+        ArgumentCaptor<Long> mCaptorLong = ArgumentCaptor.forClass(Long.class);
+        testUpdateUiccProfile();
+        verify(mMockedHandler, atLeast(1)).sendMessageDelayed(mCaptorMessage.capture(),
+                mCaptorLong.capture());
+        assertEquals(UICCPROFILE_CARRIER_PRIVILEGE_LOADED_EVENT, mCaptorMessage.getValue().what);
+    }
+
+    @Test
+    @SmallTest
     public void testInitialCardState() {
         // after updateExternalState() is called, the state will not be UNKNOWN
         assertEquals(mUiccProfile.getState(), State.NOT_READY);
@@ -544,6 +552,9 @@
         assertTrue(carrierFound);
     }
 
+    @Mock
+    private SubscriptionInfo mSubscriptionInfo;
+
     @Test
     public void testSetOperatorBrandOverride() {
         testUpdateUiccProfileApplication();
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
index 7bc737b..2f2b582 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccSlotTest.java
@@ -23,7 +23,6 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyObject;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import android.os.Handler;
@@ -32,7 +31,6 @@
 
 import androidx.test.filters.SmallTest;
 
-import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.IccCardConstants;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.uicc.IccCardStatus.CardState;
@@ -40,13 +38,16 @@
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
+import org.mockito.Mock;
 
 public class UiccSlotTest extends TelephonyTest {
     private UiccSlot mUiccSlot;
     private UiccSlotTestHandlerThread mTestHandlerThread;
     private Handler mTestHandler;
 
-    // Mocked classes
+    @Mock
+    private Handler mMockedHandler;
+    @Mock
     private IccCardStatus mIccCardStatus;
 
     private static final int UICCCARD_ABSENT = 1;
@@ -82,14 +83,13 @@
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mIccCardStatus = mock(IccCardStatus.class);
         mContextFixture.putBooleanResource(com.android.internal.R.bool.config_hotswapCapable, true);
         /* initially there are no application available */
         mIccCardStatus.mApplications = new IccCardApplicationStatus[]{};
         mIccCardStatus.mCdmaSubscriptionAppIndex =
                 mIccCardStatus.mImsSubscriptionAppIndex =
                         mIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1;
-        mIccCardStatus.mSlotPortMapping = new IccSlotPortMapping();
+
         /* starting the Handler Thread */
         mTestHandlerThread = new UiccSlotTestHandlerThread(getClass().getSimpleName());
         mTestHandlerThread.start();
@@ -101,10 +101,6 @@
     public void tearDown() throws Exception {
         mTestHandlerThread.quit();
         mTestHandlerThread.join();
-        mTestHandlerThread = null;
-        mTestHandler.removeCallbacksAndMessages(null);
-        mTestHandler = null;
-        mUiccSlot = null;
         super.tearDown();
     }
 
@@ -112,17 +108,16 @@
     @SmallTest
     public void testUpdateInactiveSlotStatus() {
         IccSlotStatus iss = new IccSlotStatus();
-        IccSimPortInfo simPortInfo = new IccSimPortInfo();
-        simPortInfo.mPortActive = false;
-        simPortInfo.mLogicalSlotIndex = 0;
-        simPortInfo.mIccId = "fake-iccid";
-        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
+        iss.logicalSlotIndex = 0;
+        iss.slotState = IccSlotStatus.SlotState.SLOTSTATE_INACTIVE;
         iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
+        iss.iccid = "fake-iccid";
 
         // initial state
         assertTrue(mUiccSlot.isActive());
         assertNull(mUiccSlot.getUiccCard());
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
+        assertNull(mUiccSlot.getIccId());
 
         // update slot to inactive
         mUiccSlot.update(null, iss, 0 /* slotIndex */);
@@ -131,6 +126,7 @@
         assertFalse(mUiccSlot.isActive());
         assertNull(mUiccSlot.getUiccCard());
         assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());
+        assertEquals(iss.iccid, mUiccSlot.getIccId());
     }
 
     @Test
@@ -140,44 +136,49 @@
         assertTrue(mUiccSlot.isActive());
         assertNull(mUiccSlot.getUiccCard());
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
+        assertNull(mUiccSlot.getIccId());
 
         mSimulatedCommands.setRadioPower(true, null);
         int phoneId = 0;
         IccSlotStatus iss = new IccSlotStatus();
-        IccSimPortInfo simPortInfo = new IccSimPortInfo();
-        simPortInfo.mPortActive = true;
-        simPortInfo.mLogicalSlotIndex = phoneId;
-        simPortInfo.mIccId = "fake-iccid";
-        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
+        iss.logicalSlotIndex = phoneId;
+        iss.slotState = IccSlotStatus.SlotState.SLOTSTATE_ACTIVE;
         iss.cardState = IccCardStatus.CardState.CARDSTATE_ABSENT;
+        iss.iccid = "fake-iccid";
 
         // update slot to inactive
-        mUiccSlot.update(new CommandsInterface[] {mSimulatedCommands}, iss, 0 /* slotIndex */);
+        mUiccSlot.update(mSimulatedCommands, iss, 0 /* slotIndex */);
 
         // assert on updated values
         assertTrue(mUiccSlot.isActive());
         assertNull(mUiccSlot.getUiccCard());
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
+        assertEquals(iss.iccid, mUiccSlot.getIccId());
         verify(mSubInfoRecordUpdater).updateInternalIccState(
                 IccCardConstants.INTENT_VALUE_ICC_ABSENT, null, phoneId);
+
+        // update slot to active
+        mUiccSlot.update(mSimulatedCommands, iss, 0 /* slotIndex */);
+
+        // assert on updated values
+        assertTrue(mUiccSlot.isActive());
     }
 
     @Test
     @SmallTest
     public void testUpdateSlotStatusEuiccIsSupported() {
         IccSlotStatus iss = new IccSlotStatus();
-        IccSimPortInfo simPortInfo = new IccSimPortInfo();
-        simPortInfo.mPortActive = false;
-        simPortInfo.mLogicalSlotIndex = 0;
-        simPortInfo.mIccId = "fake-iccid";
-        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
+        iss.logicalSlotIndex = 0;
+        iss.slotState = IccSlotStatus.SlotState.SLOTSTATE_INACTIVE;
         iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
+        iss.iccid = "fake-iccid";
         iss.atr = "3F979580BFFE8210428031A073BE211797";
 
         // initial state
         assertTrue(mUiccSlot.isActive());
         assertNull(mUiccSlot.getUiccCard());
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
+        assertNull(mUiccSlot.getIccId());
 
         // update slot to inactive
         mUiccSlot.update(null, iss, 0 /* slotIndex */);
@@ -186,11 +187,12 @@
         assertFalse(mUiccSlot.isActive());
         assertNull(mUiccSlot.getUiccCard());
         assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());
+        assertEquals(iss.iccid, mUiccSlot.getIccId());
 
-        iss.mSimPortInfos[0].mPortActive = true;
+        iss.slotState = IccSlotStatus.SlotState.SLOTSTATE_ACTIVE;
 
         // update slot to active
-        mUiccSlot.update(new CommandsInterface[] {mSimulatedCommands}, iss, 0 /* slotIndex */);
+        mUiccSlot.update(mSimulatedCommands, iss, 0 /* slotIndex */);
 
         // assert on updated values
         assertTrue(mUiccSlot.isActive());
@@ -201,18 +203,17 @@
     @SmallTest
     public void testUpdateSlotStatusEuiccIsNotSupported() {
         IccSlotStatus iss = new IccSlotStatus();
-        IccSimPortInfo simPortInfo = new IccSimPortInfo();
-        simPortInfo.mPortActive = false;
-        simPortInfo.mLogicalSlotIndex = 0;
-        simPortInfo.mIccId = "fake-iccid";
-        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
+        iss.logicalSlotIndex = 0;
+        iss.slotState = IccSlotStatus.SlotState.SLOTSTATE_INACTIVE;
         iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
+        iss.iccid = "fake-iccid";
         iss.atr = "3F979580BFFE8110428031A073BE211797";
 
         // initial state
         assertTrue(mUiccSlot.isActive());
         assertNull(mUiccSlot.getUiccCard());
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
+        assertNull(mUiccSlot.getIccId());
 
         // update slot to inactive
         mUiccSlot.update(null, iss, 0 /* slotIndex */);
@@ -221,11 +222,12 @@
         assertFalse(mUiccSlot.isActive());
         assertNull(mUiccSlot.getUiccCard());
         assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());
+        assertEquals(iss.iccid, mUiccSlot.getIccId());
 
-        iss.mSimPortInfos[0].mPortActive = true;
+        iss.slotState = IccSlotStatus.SlotState.SLOTSTATE_ACTIVE;
 
         // update slot to active
-        mUiccSlot.update(new CommandsInterface[] {mSimulatedCommands}, iss, 0 /* slotIndex */);
+        mUiccSlot.update(mSimulatedCommands, iss, 0 /* slotIndex */);
 
         // assert on updated values
         assertTrue(mUiccSlot.isActive());
@@ -234,146 +236,6 @@
 
     @Test
     @SmallTest
-    public void testUpdateSlotStatusVoltageClassA() {
-        IccSlotStatus iss = new IccSlotStatus();
-        IccSimPortInfo simPortInfo = new IccSimPortInfo();
-        simPortInfo.mPortActive = false;
-        simPortInfo.mLogicalSlotIndex = 0;
-        simPortInfo.mIccId = "fake-iccid";
-        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
-        iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
-        iss.atr = "3b9795801F018031A073BE211500";
-
-        // initial state
-        assertTrue(mUiccSlot.isActive());
-        assertNull(mUiccSlot.getUiccCard());
-        assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
-
-        // update slot to inactive
-        mUiccSlot.update(null, iss, 0 /* slotIndex */);
-
-        // assert on updated values
-        assertFalse(mUiccSlot.isActive());
-        assertNull(mUiccSlot.getUiccCard());
-        assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());
-
-        iss.mSimPortInfos[0].mPortActive = true;
-
-        // update slot to active
-        mUiccSlot.update(new CommandsInterface[] {mSimulatedCommands}, iss, 0 /* slotIndex */);
-
-        // assert on updated values
-        assertTrue(mUiccSlot.isActive());
-        assertEquals(mUiccSlot.getMinimumVoltageClass(), UiccSlot.VOLTAGE_CLASS_A);
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateSlotStatusVoltageClassANoTa() {
-        IccSlotStatus iss = new IccSlotStatus();
-        IccSimPortInfo simPortInfo = new IccSimPortInfo();
-        simPortInfo.mPortActive = false;
-        simPortInfo.mLogicalSlotIndex = 0;
-        simPortInfo.mIccId = "fake-iccid";
-        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
-        iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
-        iss.atr = "3b9795800F048031A073BE2115";
-
-        // initial state
-        assertTrue(mUiccSlot.isActive());
-        assertNull(mUiccSlot.getUiccCard());
-        assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
-
-        // update slot to inactive
-        mUiccSlot.update(null, iss, 0 /* slotIndex */);
-
-        // assert on updated values
-        assertFalse(mUiccSlot.isActive());
-        assertNull(mUiccSlot.getUiccCard());
-        assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());
-
-        iss.mSimPortInfos[0].mPortActive = true;
-
-        // update slot to active
-        mUiccSlot.update(new CommandsInterface[] {mSimulatedCommands}, iss, 0 /* slotIndex */);
-
-        // assert on updated values
-        assertTrue(mUiccSlot.isActive());
-        assertEquals(UiccSlot.VOLTAGE_CLASS_A, mUiccSlot.getMinimumVoltageClass());
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateSlotStatusVoltageClassB() {
-        IccSlotStatus iss = new IccSlotStatus();
-        IccSimPortInfo simPortInfo = new IccSimPortInfo();
-        simPortInfo.mPortActive = false;
-        simPortInfo.mLogicalSlotIndex = 0;
-        simPortInfo.mIccId = "fake-iccid";
-        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
-        iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
-        iss.atr = "3b9795801F428031A073BE211500";
-
-        // initial state
-        assertTrue(mUiccSlot.isActive());
-        assertNull(mUiccSlot.getUiccCard());
-        assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
-
-        // update slot to inactive
-        mUiccSlot.update(null, iss, 0 /* slotIndex */);
-
-        // assert on updated values
-        assertFalse(mUiccSlot.isActive());
-        assertNull(mUiccSlot.getUiccCard());
-        assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());
-
-        iss.mSimPortInfos[0].mPortActive = true;
-
-        // update slot to active
-        mUiccSlot.update(new CommandsInterface[] {mSimulatedCommands}, iss, 0 /* slotIndex */);
-
-        // assert on updated values
-        assertTrue(mUiccSlot.isActive());
-        assertEquals(UiccSlot.VOLTAGE_CLASS_B, mUiccSlot.getMinimumVoltageClass());
-    }
-
-    @Test
-    @SmallTest
-    public void testUpdateSlotStatusVoltageClassC() {
-        IccSlotStatus iss = new IccSlotStatus();
-        IccSimPortInfo simPortInfo = new IccSimPortInfo();
-        simPortInfo.mPortActive = false;
-        simPortInfo.mLogicalSlotIndex = 0;
-        simPortInfo.mIccId = "fake-iccid";
-        iss.mSimPortInfos = new IccSimPortInfo[] {simPortInfo};
-        iss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
-        iss.atr = "3b9795801F048031A073BE211500";
-
-        // initial state
-        assertTrue(mUiccSlot.isActive());
-        assertNull(mUiccSlot.getUiccCard());
-        assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
-
-        // update slot to inactive
-        mUiccSlot.update(null, iss, 0 /* slotIndex */);
-
-        // assert on updated values
-        assertFalse(mUiccSlot.isActive());
-        assertNull(mUiccSlot.getUiccCard());
-        assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mUiccSlot.getCardState());
-
-        iss.mSimPortInfos[0].mPortActive = true;
-
-        // update slot to active
-        mUiccSlot.update(new CommandsInterface[] {mSimulatedCommands}, iss, 0 /* slotIndex */);
-
-        // assert on updated values
-        assertTrue(mUiccSlot.isActive());
-        assertEquals(UiccSlot.VOLTAGE_CLASS_C, mUiccSlot.getMinimumVoltageClass());
-    }
-
-    @Test
-    @SmallTest
     public void testUpdateAbsentState() {
         int phoneId = 0;
         int slotIndex = 0;
@@ -390,19 +252,15 @@
     @SmallTest
     public void testUpdateAbsentStateInactiveSlotStatus() {
         IccSlotStatus activeIss = new IccSlotStatus();
-        IccSimPortInfo activePortInfo = new IccSimPortInfo();
-        activePortInfo.mPortActive = true;
-        activePortInfo.mLogicalSlotIndex = 0;
-        activePortInfo.mIccId = "fake-iccid";
-        activeIss.mSimPortInfos = new IccSimPortInfo[] {activePortInfo};
+        activeIss.logicalSlotIndex = 0;
+        activeIss.slotState = IccSlotStatus.SlotState.SLOTSTATE_ACTIVE;
         activeIss.cardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
+        activeIss.iccid = "fake-iccid";
         IccSlotStatus inactiveIss = new IccSlotStatus();
-        IccSimPortInfo inactivePortInfo = new IccSimPortInfo();
-        inactivePortInfo.mPortActive = false;
-        inactivePortInfo.mLogicalSlotIndex = 0;
-        inactivePortInfo.mIccId = "fake-iccid";
-        inactiveIss.mSimPortInfos = new IccSimPortInfo[] {inactivePortInfo};
+        inactiveIss.logicalSlotIndex = 0;
+        inactiveIss.slotState = IccSlotStatus.SlotState.SLOTSTATE_INACTIVE;
         inactiveIss.cardState = IccCardStatus.CardState.CARDSTATE_ABSENT;
+        inactiveIss.iccid = "fake-iccid";
 
         // update slot to inactive with absent card
         mUiccSlot.update(null, activeIss, 0 /* slotIndex */);
@@ -414,8 +272,8 @@
         assertEquals(IccCardStatus.CardState.CARDSTATE_ABSENT, mUiccSlot.getCardState());
 
         // assert that we tried to update subscriptions
-        verify(mSubInfoRecordUpdater).updateInternalIccStateForInactivePort(
-                activeIss.mSimPortInfos[0].mLogicalSlotIndex, inactiveIss.mSimPortInfos[0].mIccId);
+        verify(mSubInfoRecordUpdater).updateInternalIccStateForInactiveSlot(
+                activeIss.logicalSlotIndex, inactiveIss.iccid);
     }
 
     @Test
@@ -425,8 +283,6 @@
         int slotIndex = 0;
         // Simulate when SIM is added, UiccCard and UiccProfile should be created.
         mIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
-        mIccCardStatus.mSlotPortMapping.mPhysicalSlotIndex = slotIndex;
-        mIccCardStatus.mSlotPortMapping.mPortIndex = 0;
         mUiccSlot.update(mSimulatedCommands, mIccCardStatus, phoneId, slotIndex);
         verify(mTelephonyComponentFactory).makeUiccProfile(
                 anyObject(), eq(mSimulatedCommands), eq(mIccCardStatus), anyInt(), anyObject(),
@@ -460,7 +316,7 @@
         assertNotNull(mUiccSlot.getUiccCard());
 
         // radio state unavailable
-        mUiccSlot.onRadioStateUnavailable(phoneId);
+        mUiccSlot.onRadioStateUnavailable();
 
         // Verify that UNKNOWN state is sent to SubscriptionInfoUpdater in this case.
         verify(mSubInfoRecordUpdater).updateInternalIccState(
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
index 18247d3..f933596 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/UiccStateChangedLauncherTest.java
@@ -21,7 +21,6 @@
 import static org.mockito.Mockito.anyInt;
 import static org.mockito.Mockito.anyObject;
 import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -44,13 +43,17 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 public class UiccStateChangedLauncherTest extends TelephonyTest {
+    private static final String TAG = UiccStateChangedLauncherTest.class.getName();
     private static final int CARD_COUNT = 1;
     private static final String PROVISIONING_PACKAGE_NAME = "test.provisioning.package";
 
-    // Mocked classes
+    @Mock
     private Context mContext;
+    @Mock
     private Resources mResources;
 
     private IccCardStatus makeCardStatus(CardState state) {
@@ -60,15 +63,14 @@
         status.mCdmaSubscriptionAppIndex = -1;
         status.mGsmUmtsSubscriptionAppIndex = -1;
         status.mImsSubscriptionAppIndex = -1;
-        status.mSlotPortMapping = new IccSlotPortMapping();
         return status;
     }
 
     @Before
     public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mContext = mock(Context.class);
-        mResources = mock(Resources.class);
+        super.setUp(TAG);
+
+        MockitoAnnotations.initMocks(this);
         when(mContext.getResources()).thenReturn(mResources);
         when(TelephonyManager.getDefault().getPhoneCount()).thenReturn(CARD_COUNT);
     }
@@ -99,7 +101,7 @@
 
         // The first broadcast should be sent after initialization.
         UiccCard card = new UiccCard(mContext, mSimulatedCommands,
-                makeCardStatus(CardState.CARDSTATE_PRESENT), 0 /* phoneId */, new Object(), false);
+                makeCardStatus(CardState.CARDSTATE_PRESENT), 0 /* phoneId */, new Object());
         when(UiccController.getInstance().getUiccCardForPhone(0)).thenReturn(card);
         uiccLauncher.handleMessage(msg);
 
@@ -114,7 +116,7 @@
 
         // Card state's changed to restricted. Broadcast should be sent.
         card.update(mContext, mSimulatedCommands,
-                makeCardStatus(CardState.CARDSTATE_RESTRICTED), 0);
+                makeCardStatus(CardState.CARDSTATE_RESTRICTED));
         uiccLauncher.handleMessage(msg);
 
         broadcast_count++;
@@ -129,7 +131,7 @@
 
         // Card state's changed from restricted. Broadcast should be sent.
         card.update(mContext, mSimulatedCommands,
-                makeCardStatus(CardState.CARDSTATE_PRESENT), 0);
+                makeCardStatus(CardState.CARDSTATE_PRESENT));
         uiccLauncher.handleMessage(msg);
 
         broadcast_count++;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
index 79c4af4..383a379 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccCardTest.java
@@ -16,24 +16,43 @@
 
 package com.android.internal.telephony.uicc.euicc;
 
+import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
+import android.content.res.Resources;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.service.carrier.CarrierIdentifier;
+import android.service.euicc.EuiccProfileInfo;
+import android.telephony.UiccAccessRule;
+import android.telephony.euicc.EuiccCardManager;
+import android.telephony.euicc.EuiccNotification;
+import android.telephony.euicc.EuiccRulesAuthTable;
 import android.testing.AndroidTestingRunner;
 import android.testing.TestableLooper;
+import android.util.ExceptionUtils;
+import android.util.Log;
 
 import com.android.internal.telephony.CommandsInterface;
 import com.android.internal.telephony.TelephonyTest;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus;
 import com.android.internal.telephony.uicc.IccCardStatus;
-import com.android.internal.telephony.uicc.IccSlotPortMapping;
+import com.android.internal.telephony.uicc.IccUtils;
+import com.android.internal.telephony.uicc.asn1.Asn1Node;
+import com.android.internal.telephony.uicc.asn1.InvalidAsn1DataException;
+import com.android.internal.telephony.uicc.asn1.TagNotFoundException;
+import com.android.internal.telephony.uicc.euicc.apdu.ApduException;
 import com.android.internal.telephony.uicc.euicc.apdu.LogicalChannelMocker;
 import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback;
 
@@ -41,7 +60,9 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
 
+import java.util.Arrays;
 import java.util.concurrent.CountDownLatch;
 
 @RunWith(AndroidTestingRunner.class)
@@ -71,33 +92,44 @@
         }
     }
 
-    // Mocked classes
+    @Mock
     private CommandsInterface mMockCi;
+    @Mock
     private IccCardStatus mMockIccCardStatus;
 
     private Handler mHandler;
 
     private EuiccCard mEuiccCard;
 
+    @Mock
+    private Resources mMockResources;
+
     @Before
     public void setUp() throws Exception {
         super.setUp(getClass().getSimpleName());
-        mMockCi = mock(CommandsInterface.class);
-        mMockIccCardStatus = mock(IccCardStatus.class);
 
         mMockIccCardStatus.mApplications = new IccCardApplicationStatus[]{};
         mMockIccCardStatus.mCdmaSubscriptionAppIndex =
                 mMockIccCardStatus.mImsSubscriptionAppIndex =
                         mMockIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1;
         mMockIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
-        mMockIccCardStatus.mSlotPortMapping = new IccSlotPortMapping();
 
         mEuiccCard =
             new EuiccCard(mContext, mMockCi, mMockIccCardStatus,
-                0 /* phoneId */, new Object(), false) {
+                0 /* phoneId */, new Object()) {
+                @Override
+                protected byte[] getDeviceId() {
+                    return IccUtils.bcdToBytes("987654321012345");
+                }
 
                 @Override
                 protected void loadEidAndNotifyRegistrants() {}
+
+                @Override
+                protected Resources getResources() {
+                    return mMockResources;
+                }
+
             };
         mHandler = new Handler(Looper.myLooper());
         processAllMessages();
@@ -105,35 +137,21 @@
 
     @After
     public void tearDown() throws Exception {
-        if (mHandler != null) {
-            mHandler.removeCallbacksAndMessages(null);
-            mHandler = null;
-        }
-        mEuiccCard = null;
         super.tearDown();
     }
 
-    @Test
-    public void testEuiccCardInfoCorrectness() {
-        /* before update correctness test */
-        assertEquals(IccCardStatus.CardState.CARDSTATE_PRESENT, mEuiccCard.getCardState());
-        assertEquals(1, mEuiccCard.getUiccPortList().length);
-        // TODO once MEP HAL changes are done, modify port index in cardStatus
-        mEuiccCard.update(mContext, mSimulatedCommands, mMockIccCardStatus, 1);
-        processAllMessages();
-        /*After updating EuiccCard with port index and phoneId */
-        // TODO once the port index is change,update the expected values
-        assertEquals(1, mEuiccCard.getUiccPortList().length);
-        assertEquals(0, mEuiccCard.getUiccPortList()[0].getPhoneId());
-        // TODO uncomment below assertion check along with above MEP HAL changes.
-        //assertNotEquals(mEuiccCard.getUiccPortList()[0].getPortId(),
-        // mEuiccCard.getUiccPortList()[1].getPortId());
+    private void assertUnexpectedException(Throwable e) {
+        if (e != null) {
+            fail("Unexpected exception: " + ExceptionUtils.getCompleteMessage(e) + "\n-----\n"
+                    + Log.getStackTraceString(e.getCause()) + "-----");
+        }
     }
+
     @Test
     public void testPassEidInConstructor() {
         mMockIccCardStatus.eid = "1A2B3C4D";
         mEuiccCard = new EuiccCard(mContextFixture.getTestDouble(), mMockCi,
-                mMockIccCardStatus, 0 /* phoneId */, new Object(), false);
+                mMockIccCardStatus, 0 /* phoneId */, new Object());
 
         final int eventEidReady = 0;
         Handler handler = new Handler(Looper.myLooper()) {
@@ -154,7 +172,7 @@
         int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000");
         mHandler.post(() -> {
             mEuiccCard = new EuiccCard(mContextFixture.getTestDouble(), mMockCi,
-                    mMockIccCardStatus, 0 /* phoneId */, new Object(), false);
+                    mMockIccCardStatus, 0 /* phoneId */, new Object());
         });
         processAllMessages();
 
@@ -174,17 +192,955 @@
     }
 
     @Test
+    public void testGetAllProfiles() {
+        int channel = mockLogicalChannelResponses(
+                "BF2D14A012E3105A0A896700000000004523019F7001019000");
+
+        ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.getAllProfiles(resultCaptor, mHandler);
+        processAllMessages();
+
+        assertUnexpectedException(resultCaptor.exception);
+        EuiccProfileInfo[] profiles = resultCaptor.result;
+        assertEquals(1, profiles.length);
+        assertEquals("98760000000000543210", profiles[0].getIccid());
+        assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState());
+        verifyStoreData(channel, "BF2D0D5C0B5A909192B79F709599BF76");
+    }
+
+    @Test
+    public void testFSuffix() {
+        // iccID is 987600000000005432FF.
+        int channel = mockLogicalChannelResponses(
+                "BF2D14A012E3105A0A896700000000004523FF9F7001019000");
+
+        ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.getAllProfiles(resultCaptor, mHandler);
+        processAllMessages();
+
+        EuiccProfileInfo[] profiles = resultCaptor.result;
+        assertEquals(1, profiles.length);
+        assertEquals("987600000000005432", profiles[0].getIccid());
+        assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState());
+        verifyStoreData(channel, "BF2D0D5C0B5A909192B79F709599BF76");
+    }
+
+    @Test
+    public void testGetProfile() {
+        int channel = mockLogicalChannelResponses("BF2D8184A08181E37F"
+                + "5A0A89670000000000452301" // ICCID
+                + "90046E69636B" // Nickname
+                + "9103746D6F" // Service provider name
+                + "92027031" // Profile name
+                + "B70F800312F34581030102038203040506" // Operator id
+                + "9F700101" // Profile state
+                + "950101" // Profile class
+                + "990206C0" // Policy rules
+                + "BF7645E243E135C114ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4"
+                + "CA1D636F6D2E676F6F676C652E616E64726F69642E617070732E6D79617070"
+                + "E30ADB080000000000000001" // Carrier privilege rules
+                + "9000");
+
+        ResultCaptor<EuiccProfileInfo> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.getProfile("98760000000000543210", resultCaptor, mHandler);
+        processAllMessages();
+
+        EuiccProfileInfo profile = resultCaptor.result;
+        assertEquals("98760000000000543210", profile.getIccid());
+        assertEquals("nick", profile.getNickname());
+        assertEquals("tmo", profile.getServiceProviderName());
+        assertEquals("p1", profile.getProfileName());
+        assertEquals("213", profile.getCarrierIdentifier().getMcc());
+        assertEquals("54", profile.getCarrierIdentifier().getMnc());
+        assertEquals("010203", profile.getCarrierIdentifier().getGid1());
+        assertEquals("040506", profile.getCarrierIdentifier().getGid2());
+        assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profile.getState());
+        assertEquals(EuiccProfileInfo.PROFILE_CLASS_PROVISIONING, profile.getProfileClass());
+        assertEquals(
+                EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE
+                        | EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE,
+                profile.getPolicyRules());
+        assertArrayEquals(
+                new UiccAccessRule[] {
+                        new UiccAccessRule(
+                                IccUtils.hexStringToBytes(
+                                        "ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4"),
+                                "com.google.android.apps.myapp", 1)
+                },
+                profile.getUiccAccessRules().toArray());
+        verifyStoreData(channel, "BF2D1BA00C5A0A896700000000004523015C0B5A909192B79F709599BF76");
+    }
+
+    @Test
+    public void testDisableProfile() {
+        int channel = mockLogicalChannelResponses("BF32038001009000");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.disableProfile("98760000000000543210", true, resultCaptor, mHandler);
+        processAllMessages();
+
+        assertUnexpectedException(resultCaptor.exception);
+        verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF");
+    }
+
+    @Test
+    public void testDisableProfile_SimRefresh() {
+        int channel = mockLogicalChannelResponses("6106", "6f00");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.disableProfile("98760000000000543210", true, resultCaptor, mHandler);
+        processAllMessages();
+
+        assertUnexpectedException(resultCaptor.exception);
+        verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF");
+    }
+
+    @Test
+    public void testDisableProfile_Error() {
+        int channel = mockLogicalChannelResponses("BF32038001039000");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.disableProfile("98760000000000543210", true, resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
+        verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF");
+    }
+
+    @Test
+    public void testSwitchToProfile() {
+        int channel = mockLogicalChannelResponses("BF31038001009000");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.switchToProfile("98760000000000543210", true, resultCaptor, mHandler);
+        processAllMessages();
+
+        assertUnexpectedException(resultCaptor.exception);
+        verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF");
+    }
+
+    @Test
+    public void testSwitchToProfile_SimRefresh() {
+        int channel = mockLogicalChannelResponses("6106", "6f00");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.switchToProfile("98760000000000543210", true, resultCaptor, mHandler);
+        processAllMessages();
+
+        assertUnexpectedException(resultCaptor.exception);
+        verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF");
+    }
+
+    @Test
+    public void testSwitchToProfile_Error() {
+        int channel = mockLogicalChannelResponses("BF31038001039000");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.switchToProfile("98760000000000543210", true, resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
+        verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF");
+    }
+
+    @Test
     public void testGetEid() {
         int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000");
 
         ResultCaptor<String> resultCaptor = new ResultCaptor<>();
-        ((EuiccPort) mEuiccCard.getUiccPort(0)).getEid(resultCaptor, mHandler);
+        mEuiccCard.getEid(resultCaptor, mHandler);
         processAllMessages();
 
         assertEquals("1A2B3C4D", resultCaptor.result);
         verifyStoreData(channel, "BF3E035C015A");
     }
 
+    @Test
+    public void testSetNickname() {
+        int channel = mockLogicalChannelResponses("BF29038001009000");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.setNickname("98760000000000543210", "new nickname", resultCaptor, mHandler);
+        processAllMessages();
+
+        assertUnexpectedException(resultCaptor.exception);
+        verifyStoreData(channel, "BF291A5A0A89670000000000452301900C6E6577206E69636B6E616D65");
+    }
+
+    @Test
+    public void testDeleteProfile() {
+        int channel = mockLogicalChannelResponses("BF33038001009000");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.deleteProfile("98760000000000543210", resultCaptor, mHandler);
+        processAllMessages();
+
+        assertUnexpectedException(resultCaptor.exception);
+        verifyStoreData(channel, "BF330C5A0A89670000000000452301");
+    }
+
+    @Test
+    public void testDeleteProfile_Error() {
+        int channel = mockLogicalChannelResponses("BF33038001039000");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.deleteProfile("98760000000000543210", resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
+        verifyStoreData(channel, "BF330C5A0A89670000000000452301");
+    }
+
+    @Test
+    public void testGetDefaultSmdpAddress() {
+        int channel = mockLogicalChannelResponses(
+                "BF3C148008534D44502E434F4D8108736D64732E636F6D9000");
+
+        ResultCaptor<String> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.getDefaultSmdpAddress(resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals("SMDP.COM", resultCaptor.result);
+        verifyStoreData(channel, "BF3C00");
+    }
+
+    @Test
+    public void testGetSmdsAddress() {
+        int channel = mockLogicalChannelResponses(
+                "BF3C148008534D44502E434F4D8108736D64732E636F6D9000");
+
+        ResultCaptor<String> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.getSmdsAddress(resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals("smds.com", resultCaptor.result);
+        verifyStoreData(channel, "BF3C00");
+    }
+
+    @Test
+    public void testSetDefaultSmdpAddress() {
+        int channel = mockLogicalChannelResponses("BF3F038001009000");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.setDefaultSmdpAddress("smdp.gsma.com", resultCaptor, mHandler);
+        processAllMessages();
+
+        assertUnexpectedException(resultCaptor.exception);
+        verifyStoreData(channel, "BF3F0F800D736D64702E67736D612E636F6D");
+    }
+
+    @Test
+    public void testGetRulesAuthTable() {
+        int channel = mockLogicalChannelResponses("BF434B"
+                + "A0233021" // Rule #1
+                + "800206C0" // Policy rules: DO_NOT_DELETE | DO_NOT_DISABLE
+                + "A118" // Operator IDs
+                + "B70A800312F3458103010203" // ID #1: 213, 54, [1,2,3], null
+                + "B70A800312F3458203040506" // ID #2: 213, 54, null, [4,5,6]
+                + "820108" // Flag (no user consent)
+                + "A0243022" // Rule #2
+                + "80020780" // Policy rules: DO_NOT_DISABLE
+                + "A118" // Operator IDs
+                + "B70A800312E3458103010203" // ID #1: 213, 54E, [1,2,3], null
+                + "B70A8003EEEE458203040506" // ID #2: EEE, 54E, null, [4,5,6]
+                + "82020780" // Flag (user consent)
+                + "9000");
+
+        ResultCaptor<EuiccRulesAuthTable> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.getRulesAuthTable(resultCaptor, mHandler);
+        processAllMessages();
+
+        EuiccRulesAuthTable rat = resultCaptor.result;
+        assertEquals(-1,
+                rat.findIndex(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE,
+                        new CarrierIdentifier(new byte[] {0x12, (byte) 0xF3, 0x45}, null, null)));
+        assertEquals(1,
+                rat.findIndex(EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE,
+                        new CarrierIdentifier(new byte[] {0x23, 0x67, 0x45}, null, "040506")));
+        assertFalse(rat.hasPolicyRuleFlag(0,
+                EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED));
+        assertTrue(rat.hasPolicyRuleFlag(1,
+                EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED));
+        verifyStoreData(channel, "BF4300");
+    }
+
+    @Test
+    public void testResetMemory() {
+        int channel = mockLogicalChannelResponses("BF34038001009000");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.resetMemory(EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES,
+                resultCaptor, mHandler);
+        processAllMessages();
+
+        assertUnexpectedException(resultCaptor.exception);
+        verifyStoreData(channel, "BF340482020640");
+    }
+
+    @Test
+    public void testResetMemory_SimRefresh() {
+        int channel = mockLogicalChannelResponses("6106", "6f00");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.resetMemory(EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES,
+                resultCaptor, mHandler);
+        processAllMessages();
+
+        assertUnexpectedException(resultCaptor.exception);
+        verifyStoreData(channel, "BF340482020640");
+    }
+
+    @Test
+    public void testGetEuiccChallenge() {
+        int channel = mockLogicalChannelResponses("BF2E0580030102039000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.getEuiccChallenge(resultCaptor, mHandler);
+        processAllMessages();
+
+        assertArrayEquals(new byte[] {1, 2, 3}, resultCaptor.result);
+        verifyStoreData(channel, "BF2E00");
+    }
+
+    @Test
+    public void testGetEuiccInfo1() {
+        int channel = mockLogicalChannelResponses("BF20030102039000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.getEuiccInfo1(resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals("BF2003010203", IccUtils.bytesToHexString(resultCaptor.result));
+        verifyStoreData(channel, "BF2000");
+    }
+
+    @Test
+    public void testGetEuiccInfo2() {
+        int channel = mockLogicalChannelResponses("BF22030102039000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.getEuiccInfo2(resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals("BF2203010203", IccUtils.bytesToHexString(resultCaptor.result));
+        verifyStoreData(channel, "BF2200");
+    }
+
+    @Test
+    public void testAuthenticateServer() {
+        when(mMockResources.getStringArray(
+                com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities))
+                .thenReturn(new String[] {});
+
+        int channel = mockLogicalChannelResponses("BF3802A0009000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id
+                Asn1Node.newBuilder(0xA0).build().toBytes(),
+                Asn1Node.newBuilder(0xA1).build().toBytes(),
+                Asn1Node.newBuilder(0xA2).build().toBytes(),
+                Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler);
+        processAllMessages();
+
+        assertUnexpectedException(resultCaptor.exception);
+        assertEquals("BF3802A000", IccUtils.bytesToHexString(resultCaptor.result));
+        verifyStoreData(channel,
+                "BF382D" + "A000" + "A100" + "A200" + "A300" + "A023"
+                        + "800D4131423243332D583459355A36" // Matching id
+                        + "A112800489674523" // TAC
+                        + "A100" // Device capabilities
+                        + "82088967452301214305"); // IMEI
+    }
+
+    @Test
+    public void testAuthenticateServer_Error() {
+        when(mMockResources.getStringArray(
+                com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities))
+                .thenReturn(new String[] {});
+
+        int channel = mockLogicalChannelResponses("BF3805A1030201039000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id
+                Asn1Node.newBuilder(0xA0).build().toBytes(),
+                Asn1Node.newBuilder(0xA1).build().toBytes(),
+                Asn1Node.newBuilder(0xA2).build().toBytes(),
+                Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
+        verifyStoreData(channel,
+                "BF382D" + "A000" + "A100" + "A200" + "A300" + "A023"
+                        + "800D4131423243332D583459355A36" // Matching id
+                        + "A112800489674523" // TAC
+                        + "A100" // Device capabilities
+                        + "82088967452301214305"); // IMEI
+    }
+
+    @Test
+    public void testAuthenticateService_devCap() {
+        when(mMockResources.getStringArray(
+                com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities))
+                .thenReturn(new String[] {
+                        "gsm,11",
+                        "utran,11",
+                        "cdma1x,1",
+                        "hrpd,3",
+                        "ehrpd,12",
+                        "eutran,11"});
+
+        int channel = mockLogicalChannelResponses("BF3802A0009000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.authenticateServer("A1B2C3-X4Y5Z6", // Matching id
+                Asn1Node.newBuilder(0xA0).build().toBytes(),
+                Asn1Node.newBuilder(0xA1).build().toBytes(),
+                Asn1Node.newBuilder(0xA2).build().toBytes(),
+                Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler);
+        processAllMessages();
+
+        assertUnexpectedException(resultCaptor.exception);
+        assertEquals("BF3802A000", IccUtils.bytesToHexString(resultCaptor.result));
+        verifyStoreData(channel,
+                "BF384B" + "A000" + "A100" + "A200" + "A300" + "A041"
+                        + "800D4131423243332D583459355A36" // Matching id
+                        + "A130800489674523" // TAC
+                        // Device capabilities
+                        + "A11E80030B000081030B00008203010000830303000084030C000085030B0000"
+                        + "82088967452301214305"); // IMEI
+    }
+
+    @Test
+    public void testPrepareDownload() {
+        int channel = mockLogicalChannelResponses("BF2102A0009000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.prepareDownload(
+                IccUtils.hexStringToBytes("4131423243332D583459355A36"), // hashCc
+                Asn1Node.newBuilder(0xA0).build().toBytes(),
+                Asn1Node.newBuilder(0xA1).build().toBytes(),
+                Asn1Node.newBuilder(0xA2).build().toBytes(), resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals("BF2102A000", IccUtils.bytesToHexString(resultCaptor.result));
+        verifyStoreData(channel,
+                "BF2115" + "A000" + "A100"
+                        + "040D4131423243332D583459355A36" // hashCc
+                        + "A200");
+    }
+
+    @Test
+    public void testPrepareDownload_Error() {
+        int channel = mockLogicalChannelResponses("BF2105A1030201039000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.prepareDownload(
+                IccUtils.hexStringToBytes("4131423243332D583459355A36"), // hashCc
+                Asn1Node.newBuilder(0xA0).build().toBytes(),
+                Asn1Node.newBuilder(0xA1).build().toBytes(),
+                Asn1Node.newBuilder(0xA2).build().toBytes(), resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
+        verifyStoreData(channel,
+                "BF2115" + "A000" + "A100"
+                        + "040D4131423243332D583459355A36" // hashCc
+                        + "A200");
+    }
+
+    @Test
+    public void testLoadBoundProfilePackage() {
+        int channel = mockLogicalChannelResponses(
+                // For boundProfilePackage head + initialiseSecureChannelRequest
+                // (ES8+.InitialiseSecureChannel)
+                "9000",
+                // For firstSequenceOf87 (ES8+.ConfigureISDP)
+                "9000",
+                // For head of sequenceOf88 (ES8+.StoreMetadata)
+                "9000",
+                // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata)
+                "9000",
+                "9000",
+                // For head of sequenceOf86 (ES8+.LoadProfileElements)
+                "9000",
+                // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements)
+                "9000",
+                // Profile installation result (element 2 of sequenceOf86)
+                "BF37009000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.loadBoundProfilePackage(
+                Asn1Node.newBuilder(0xBF36)
+                        .addChild(Asn1Node.newBuilder(0xBF23))
+                        .addChild(Asn1Node.newBuilder(0xA0)
+                                .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
+                        .addChild(Asn1Node.newBuilder(0xA1)
+                                .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
+                        .addChild(Asn1Node.newBuilder(0xA2))
+                        .addChild(Asn1Node.newBuilder(0xA3)
+                                .addChildAsBytes(0x86, new byte[] {7, 8, 9})
+                                .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
+                        .build().toBytes(),
+                resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals("BF3700", IccUtils.bytesToHexString(resultCaptor.result));
+        verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel
+        verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP
+        verifyStoreData(channel, "A105"); // ES8+.StoreMetadata
+        verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata
+        verifyStoreData(channel, "A200");
+        verifyStoreData(channel, "A30A"); // ES8+.LoadProfileElements
+        verifyStoreData(channel, "8603070809"); // ES8+.LoadProfileElements
+        verifyStoreData(channel, "86030A0B0C"); // ES8+.LoadProfileElements
+    }
+
+    @Test
+    public void testLoadBoundProfilePackage_ErrorAtEnd() {
+        int channel = mockLogicalChannelResponses(
+                // For boundProfilePackage head + initialiseSecureChannelRequest
+                // (ES8+.InitialiseSecureChannel)
+                "9000",
+                // For firstSequenceOf87 (ES8+.ConfigureISDP)
+                "9000",
+                // For head of sequenceOf88 (ES8+.StoreMetadata)
+                "9000",
+                // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata)
+                "9000",
+                "9000",
+                // For head of sequenceOf86 (ES8+.LoadProfileElements)
+                "9000",
+                // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements)
+                "9000",
+                // Profile installation result (element 2 of sequenceOf86)
+                "BF370ABF2707A205A1038101039000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.loadBoundProfilePackage(
+                Asn1Node.newBuilder(0xBF36)
+                        .addChild(Asn1Node.newBuilder(0xBF23))
+                        .addChild(Asn1Node.newBuilder(0xA0)
+                                .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
+                        .addChild(Asn1Node.newBuilder(0xA1)
+                                .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
+                        .addChild(Asn1Node.newBuilder(0xA2))
+                        .addChild(Asn1Node.newBuilder(0xA3)
+                                .addChildAsBytes(0x86, new byte[] {7, 8, 9})
+                                .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
+                        .build().toBytes(),
+                resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
+        verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel
+        verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP
+        verifyStoreData(channel, "A105"); // ES8+.StoreMetadata
+        verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata
+        verifyStoreData(channel, "A200");
+        verifyStoreData(channel, "A30A"); // ES8+.LoadProfileElements
+        verifyStoreData(channel, "8603070809"); // ES8+.LoadProfileElements
+        verifyStoreData(channel, "86030A0B0C"); // ES8+.LoadProfileElements
+    }
+
+    @Test
+    public void testLoadBoundProfilePackage_ErrorInMiddle() {
+        int channel = mockLogicalChannelResponses(
+                // For boundProfilePackage head + initialiseSecureChannelRequest
+                // (ES8+.InitialiseSecureChannel)
+                "9000",
+                // For firstSequenceOf87 (ES8+.ConfigureISDP)
+                "9000",
+                // For head of sequenceOf88 (ES8+.StoreMetadata)
+                "9000",
+                // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata)
+                "BF370ABF2707A205A1038101039000",
+                "9000",
+                // For head of sequenceOf86 (ES8+.LoadProfileElements)
+                "9000",
+                // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements)
+                "9000",
+                // Profile installation result (element 2 of sequenceOf86)
+                "9000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.loadBoundProfilePackage(
+                Asn1Node.newBuilder(0xBF36)
+                        .addChild(Asn1Node.newBuilder(0xBF23))
+                        .addChild(Asn1Node.newBuilder(0xA0)
+                                .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
+                        .addChild(Asn1Node.newBuilder(0xA1)
+                                .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
+                        .addChild(Asn1Node.newBuilder(0xA2))
+                        .addChild(Asn1Node.newBuilder(0xA3)
+                                .addChildAsBytes(0x86, new byte[] {7, 8, 9})
+                                .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
+                        .build().toBytes(),
+                resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
+        verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel
+        verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP
+        verifyStoreData(channel, "A105"); // ES8+.StoreMetadata
+        verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata
+    }
+
+    @Test
+    public void testLoadBoundProfilePackage_ErrorStatus() {
+        int channel = mockLogicalChannelResponses(
+                // For boundProfilePackage head + initialiseSecureChannelRequest
+                // (ES8+.InitialiseSecureChannel)
+                "9000",
+                // For firstSequenceOf87 (ES8+.ConfigureISDP)
+                "9000",
+                // For head of sequenceOf88 (ES8+.StoreMetadata)
+                "9000",
+                // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata)
+                "6985",
+                "9000",
+                // For head of sequenceOf86 (ES8+.LoadProfileElements)
+                "9000",
+                // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements)
+                "9000",
+                // Profile installation result (element 2 of sequenceOf86)
+                "9000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.loadBoundProfilePackage(
+                Asn1Node.newBuilder(0xBF36)
+                        .addChild(Asn1Node.newBuilder(0xBF23))
+                        .addChild(Asn1Node.newBuilder(0xA0)
+                                .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
+                        .addChild(Asn1Node.newBuilder(0xA1)
+                                .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
+                        .addChild(Asn1Node.newBuilder(0xA2))
+                        .addChild(Asn1Node.newBuilder(0xA3)
+                                .addChildAsBytes(0x86, new byte[] {7, 8, 9})
+                                .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
+                        .build().toBytes(),
+                resultCaptor, mHandler);
+        processAllMessages();
+
+        EuiccCardException e = (EuiccCardException) resultCaptor.exception;
+        assertEquals(0x6985, ((ApduException) e.getCause()).getApduStatus());
+        verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel
+        verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP
+        verifyStoreData(channel, "A105"); // ES8+.StoreMetadata
+        verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata
+    }
+
+    @Test
+    public void testLoadBoundProfilePackage_NoProfileElements() {
+        int channel = mockLogicalChannelResponses_sgp22v210();
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.loadBoundProfilePackage(
+                Asn1Node.newBuilder(0xBF36)
+                        .addChild(Asn1Node.newBuilder(0xBF23))
+                        .addChild(Asn1Node.newBuilder(0xA0)
+                                .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
+                        .addChild(Asn1Node.newBuilder(0xA1)
+                                .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
+                        .addChild(Asn1Node.newBuilder(0xA2))
+                        // No children
+                        .addChild(Asn1Node.newBuilder(0xA3))
+                        .build().toBytes(),
+                resultCaptor, mHandler);
+        processAllMessages();
+
+        EuiccCardException e = (EuiccCardException) resultCaptor.exception;
+        assertEquals("No profile elements in BPP", e.getCause().getMessage());
+        verify(mMockCi, never())
+                .iccTransmitApduLogicalChannel(
+                        eq(channel), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), any(),
+                        any());
+    }
+
+    @Test
+    public void testLoadBoundProfilePackage_UnrecognizedTag() {
+        int channel = mockLogicalChannelResponses_sgp22v210();
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.loadBoundProfilePackage(
+                Asn1Node.newBuilder(0xBF36)
+                        .addChild(Asn1Node.newBuilder(0xBF23))
+                        .addChild(Asn1Node.newBuilder(0xA0)
+                                .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
+                        .addChild(Asn1Node.newBuilder(0xA1)
+                                .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
+                        .addChild(Asn1Node.newBuilder(0xA2))
+                        .addChild(Asn1Node.newBuilder(0xA3)
+                                .addChildAsBytes(0x86, new byte[] {7, 8, 9})
+                                .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
+                        // Unrecognized tag
+                        .addChild(Asn1Node.newBuilder(0xA4))
+                        .build().toBytes(),
+                resultCaptor, mHandler);
+        processAllMessages();
+
+        EuiccCardException e = (EuiccCardException) resultCaptor.exception;
+        assertEquals(
+                "Actual BPP length (33) does not match segmented length (31), this must be due to a"
+                        + " malformed BPP",
+                e.getCause().getMessage());
+        verify(mMockCi, never())
+                .iccTransmitApduLogicalChannel(
+                        eq(channel), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), any(),
+                        any());
+    }
+
+    @Test
+    public void testCancelSession() {
+        int channel = mockLogicalChannelResponses("BF41009000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.cancelSession(IccUtils.hexStringToBytes("A1B2C3"),
+                EuiccCardManager.CANCEL_REASON_POSTPONED, resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals("BF4100", IccUtils.bytesToHexString(resultCaptor.result));
+        verifyStoreData(channel, "BF41088003A1B2C3810101");
+    }
+
+    @Test
+    public void testCancelSession_Error() {
+        int channel = mockLogicalChannelResponses("BF41038101039000");
+
+        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.cancelSession(IccUtils.hexStringToBytes("A1B2C3"),
+                EuiccCardManager.CANCEL_REASON_POSTPONED, resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
+        verifyStoreData(channel, "BF41088003A1B2C3810101");
+    }
+
+    @Test
+    public void testListNotifications() {
+        int channel = mockLogicalChannelResponses("BF282BA029"
+                + "BF2F118001010C08736D64702E636F6D81020410" // Notification #1
+                + "BF2F128001020C09736D6470322E636F6D81020420" // Notification #2
+                + "9000");
+
+        ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.listNotifications(
+                EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
+                resultCaptor, mHandler);
+        processAllMessages();
+
+        assertArrayEquals(
+                new EuiccNotification[] {
+                        new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE, null),
+                        new EuiccNotification(2, "smdp2.com", EuiccNotification.EVENT_DISABLE, null)
+                },
+                resultCaptor.result);
+        verifyStoreData(channel, "BF280481020430");
+    }
+
+    @Test
+    public void testListNotifications_Error() {
+        int channel = mockLogicalChannelResponses("BF28038101039000");
+
+        ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.listNotifications(
+                EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
+                resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
+        verifyStoreData(channel, "BF280481020430");
+    }
+
+    @Test
+    public void testRetrieveNotificationList() {
+        int channel = mockLogicalChannelResponses("BF2B2FA02D"
+                // Notification #1
+                + "3014BF2F118001010C08736D64702E636F6D81020410"
+                // Notification #2
+                + "3015BF2F128001020C09736D6470322E636F6D81020420"
+                + "9000");
+
+        ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.retrieveNotificationList(
+                EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
+                resultCaptor, mHandler);
+        processAllMessages();
+
+        assertArrayEquals(
+                new EuiccNotification[] {
+                        new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE,
+                                IccUtils.hexStringToBytes(
+                                        "3014BF2F118001010C08736D64702E636F6D81020410")),
+                        new EuiccNotification(2, "smdp2.com", EuiccNotification.EVENT_DISABLE,
+                                IccUtils.hexStringToBytes(
+                                        "3015BF2F128001020C09736D6470322E636F6D81020420"))
+                },
+                resultCaptor.result);
+        verifyStoreData(channel, "BF2B06A00481020430");
+    }
+
+    @Test
+    public void testRetrieveNotificationList_Empty() {
+        int channel = mockLogicalChannelResponses("BF2B038101019000");
+
+        ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.retrieveNotificationList(
+                EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
+                resultCaptor, mHandler);
+        processAllMessages();
+
+        assertArrayEquals(new EuiccNotification[0], resultCaptor.result);
+        verifyStoreData(channel, "BF2B06A00481020430");
+    }
+
+    @Test
+    public void testRetrieveNotificationList_Error() {
+        int channel = mockLogicalChannelResponses("BF2B038101039000");
+
+        ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.retrieveNotificationList(
+                EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
+                resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
+        verifyStoreData(channel, "BF2B06A00481020430");
+    }
+
+    @Test
+    public void testRetrieveNotification() {
+        int channel = mockLogicalChannelResponses("BF2B18A016"
+                + "3014BF2F118001010C08736D64702E636F6D81020410" // Notification
+                + "9000");
+
+        ResultCaptor<EuiccNotification> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.retrieveNotification(5, resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals(
+                new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE,
+                        IccUtils.hexStringToBytes("3014BF2F118001010C08736D64702E636F6D81020410")),
+                resultCaptor.result);
+        verifyStoreData(channel, "BF2B05A003800105");
+    }
+
+    @Test
+    public void testRetrieveNotification_Error() {
+        int channel = mockLogicalChannelResponses("BF2B038101019000");
+
+        ResultCaptor<EuiccNotification> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.retrieveNotification(5, resultCaptor, mHandler);
+        processAllMessages();
+
+        assertEquals(1, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
+        verifyStoreData(channel, "BF2B05A003800105");
+    }
+
+    @Test
+    public void testRemoveNotificationFromList() {
+        int channel = mockLogicalChannelResponses("BF30038001009000");
+
+        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
+        mEuiccCard.removeNotificationFromList(5, resultCaptor, mHandler);
+        processAllMessages();
+
+        assertUnexpectedException(resultCaptor.exception);
+        verifyStoreData(channel, "BF3003800105");
+    }
+
+    @Test
+    public void testAddDeviceCapability() throws InvalidAsn1DataException, TagNotFoundException {
+        Asn1Node.Builder devCapsBuilder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1);
+
+        String devCapItem = "gsm,11";
+        mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
+        Asn1Node node = devCapsBuilder.build();
+
+        assertTrue(node.hasChild(Tags.TAG_CTX_0));
+        Asn1Node child = node.getChild(Tags.TAG_CTX_0);
+        assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes()));
+
+        devCapItem = "utran,11";
+        mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
+        node = devCapsBuilder.build();
+
+        assertTrue(node.hasChild(Tags.TAG_CTX_1));
+        child = node.getChild(Tags.TAG_CTX_1);
+        assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes()));
+
+        devCapItem = "cdma1x,1";
+        mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
+        node = devCapsBuilder.build();
+
+        assertTrue(node.hasChild(Tags.TAG_CTX_2));
+        child = node.getChild(Tags.TAG_CTX_2);
+        assertTrue(Arrays.equals(new byte[] {1, 0 , 0}, child.asBytes()));
+
+        devCapItem = "hrpd,1";
+        mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
+        node = devCapsBuilder.build();
+
+        assertTrue(node.hasChild(Tags.TAG_CTX_3));
+        child = node.getChild(Tags.TAG_CTX_3);
+        assertTrue(Arrays.equals(new byte[] {1, 0 , 0}, child.asBytes()));
+
+        devCapItem = "ehrpd,12";
+        mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
+        node = devCapsBuilder.build();
+
+        assertTrue(node.hasChild(Tags.TAG_CTX_4));
+        child = node.getChild(Tags.TAG_CTX_4);
+        assertTrue(Arrays.equals(new byte[] {12, 0 , 0}, child.asBytes()));
+
+        devCapItem = "eutran,11";
+        mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
+        node = devCapsBuilder.build();
+
+        assertTrue(node.hasChild(Tags.TAG_CTX_5));
+        child = node.getChild(Tags.TAG_CTX_5);
+        assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes()));
+
+        devCapItem = "nfc,0";
+        mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
+        node = devCapsBuilder.build();
+
+        assertTrue(node.hasChild(Tags.TAG_CTX_6));
+        child = node.getChild(Tags.TAG_CTX_6);
+        assertTrue(Arrays.equals(new byte[] {0, 0 , 0}, child.asBytes()));
+
+        devCapItem = "crl,0";
+        mEuiccCard.addDeviceCapability(devCapsBuilder, devCapItem);
+        node = devCapsBuilder.build();
+
+        assertTrue(node.hasChild(Tags.TAG_CTX_7));
+        child = node.getChild(Tags.TAG_CTX_7);
+        assertTrue(Arrays.equals(new byte[] {0, 0 , 0}, child.asBytes()));
+
+        // Array length should not be 3.
+        Asn1Node.Builder devCapsBuilder2 = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1);
+        devCapItem = "gsm,1,1";
+        mEuiccCard.addDeviceCapability(devCapsBuilder2, devCapItem);
+        node = devCapsBuilder2.build();
+
+        assertFalse(node.hasChild(Tags.TAG_CTX_0));
+    }
+
+    @Test
+    public void testGetDeviceId() {
+        // Unclear v2.0 definition
+        assertArrayEquals(
+                new byte[] {0x21, 0x43, 0x65, (byte) 0x87, 0x09, 0x21, 0x43, 0x05},
+                EuiccCard.getDeviceId("123456789012345", new EuiccSpecVersion(2, 0, 0)));
+        // Clarified v2.1+ definition
+        assertArrayEquals(
+                new byte[] {0x21, 0x43, 0x65, (byte) 0x87, 0x09, 0x21, 0x43, 0x5F},
+                EuiccCard.getDeviceId("123456789012345", new EuiccSpecVersion(2, 1, 0)));
+        // Same definition on v2.2
+        assertArrayEquals(
+                new byte[] {0x21, 0x43, 0x65, (byte) 0x87, 0x09, 0x21, 0x43, 0x5F},
+                EuiccCard.getDeviceId("123456789012345", new EuiccSpecVersion(2, 2, 0)));
+    }
+
     private void verifyStoreData(int channel, String command) {
         verify(mMockCi, times(1))
                 .iccTransmitApduLogicalChannel(eq(channel), eq(0x80 | channel), eq(0xE2), eq(0x91),
@@ -198,4 +1154,12 @@
         LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel);
         return channel;
     }
-}
\ No newline at end of file
+
+    private int mockLogicalChannelResponses_sgp22v210(Object... responses) {
+        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi,
+                "E00582030201009000");
+        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, responses);
+        LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel);
+        return channel;
+    }
+}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccPortTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccPortTest.java
deleted file mode 100644
index 8caa248..0000000
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/EuiccPortTest.java
+++ /dev/null
@@ -1,1196 +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 com.android.internal.telephony.uicc.euicc;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.res.Resources;
-import android.os.Handler;
-import android.os.Looper;
-import android.service.carrier.CarrierIdentifier;
-import android.service.euicc.EuiccProfileInfo;
-import android.telephony.UiccAccessRule;
-import android.telephony.euicc.EuiccCardManager;
-import android.telephony.euicc.EuiccNotification;
-import android.telephony.euicc.EuiccRulesAuthTable;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.util.ExceptionUtils;
-import android.util.Log;
-
-import com.android.internal.telephony.CommandsInterface;
-import com.android.internal.telephony.TelephonyTest;
-import com.android.internal.telephony.uicc.IccCardApplicationStatus;
-import com.android.internal.telephony.uicc.IccCardStatus;
-import com.android.internal.telephony.uicc.IccSlotPortMapping;
-import com.android.internal.telephony.uicc.IccUtils;
-import com.android.internal.telephony.uicc.asn1.Asn1Node;
-import com.android.internal.telephony.uicc.asn1.InvalidAsn1DataException;
-import com.android.internal.telephony.uicc.asn1.TagNotFoundException;
-import com.android.internal.telephony.uicc.euicc.apdu.ApduException;
-import com.android.internal.telephony.uicc.euicc.apdu.LogicalChannelMocker;
-import com.android.internal.telephony.uicc.euicc.async.AsyncResultCallback;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.util.Arrays;
-import java.util.concurrent.CountDownLatch;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class EuiccPortTest extends TelephonyTest {
-
-    private static class ResultCaptor<T> extends AsyncResultCallback<T> {
-        public T result;
-        public Throwable exception;
-
-        private CountDownLatch mLatch;
-
-        private ResultCaptor() {
-            mLatch = new CountDownLatch(1);
-        }
-
-        @Override
-        public void onResult(T r) {
-            result = r;
-            mLatch.countDown();
-        }
-
-        @Override
-        public void onException(Throwable e) {
-            exception = e;
-            mLatch.countDown();
-        }
-    }
-
-    // Mocked classes
-    private CommandsInterface mMockCi;
-    private IccCardStatus mMockIccCardStatus;
-    private EuiccCard mEuiccCard;
-    private Resources mMockResources;
-
-    private Handler mHandler;
-    private EuiccPort mEuiccPort;
-
-
-    @Before
-    public void setUp() throws Exception {
-        super.setUp(getClass().getSimpleName());
-        mMockCi = mock(CommandsInterface.class);
-        mMockIccCardStatus = mock(IccCardStatus.class);
-        mEuiccCard = mock(EuiccCard.class);
-        mMockResources = mock(Resources.class);
-
-        mMockIccCardStatus.mApplications = new IccCardApplicationStatus[]{};
-        mMockIccCardStatus.mCdmaSubscriptionAppIndex =
-                mMockIccCardStatus.mImsSubscriptionAppIndex =
-                        mMockIccCardStatus.mGsmUmtsSubscriptionAppIndex = -1;
-        mMockIccCardStatus.mCardState = IccCardStatus.CardState.CARDSTATE_PRESENT;
-        mMockIccCardStatus.mSlotPortMapping = new IccSlotPortMapping();
-        mEuiccPort =
-            new EuiccPort(mContext, mMockCi, mMockIccCardStatus,
-                0 /* phoneId */, new Object(), mEuiccCard, false) {
-                @Override
-                protected byte[] getDeviceId() {
-                    return IccUtils.bcdToBytes("987654321012345");
-                }
-
-                @Override
-                protected Resources getResources() {
-                    return mMockResources;
-                }
-            };
-        mHandler = new Handler(Looper.myLooper());
-        processAllMessages();
-    }
-
-    @After
-    public void tearDown() throws Exception {
-        mHandler.removeCallbacksAndMessages(null);
-        mHandler = null;
-        mEuiccPort = null;
-        super.tearDown();
-    }
-
-    private void assertUnexpectedException(Throwable e) {
-        if (e != null) {
-            fail("Unexpected exception: " + ExceptionUtils.getCompleteMessage(e) + "\n-----\n"
-                    + Log.getStackTraceString(e.getCause()) + "-----");
-        }
-    }
-
-    @Test
-    public void testEuiccPortProfile() {
-        int channel = mockLogicalChannelResponses(
-                "BF2D14A012E3105A0A896700000000004523019F7001019000");
-
-        ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.getAllProfiles(resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        EuiccProfileInfo[] profiles = resultCaptor.result;
-        assertEquals(1, profiles.length);
-        assertEquals("98760000000000543210", profiles[0].getIccid());
-        assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState());
-        verifyStoreData(channel, "BF2D0D5C0B5A909192B79F709599BF76");
-    }
-
-    @Test
-    public void testEuiccPortProfile_MEP() {
-        int channel = mockLogicalChannelResponses(
-                "BF2D14A012E3105A0A896700000000004523019F7001019000");
-
-        ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.mIsSupportsMultipleEnabledProfiles = true; // MEP capable
-        mEuiccPort.getAllProfiles(resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        EuiccProfileInfo[] profiles = resultCaptor.result;
-        assertEquals(1, profiles.length);
-        assertEquals("98760000000000543210", profiles[0].getIccid());
-        assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState());
-        verifyStoreData(channel, "BF2D0F5C0D5A909192B79F709599BF769F24");
-    }
-
-    @Test
-    public void testGetAllProfiles() {
-        int channel = mockLogicalChannelResponses(
-                "BF2D14A012E3105A0A896700000000004523019F7001019000");
-
-        ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.getAllProfiles(resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        EuiccProfileInfo[] profiles = resultCaptor.result;
-        assertEquals(1, profiles.length);
-        assertEquals("98760000000000543210", profiles[0].getIccid());
-        assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState());
-        verifyStoreData(channel, "BF2D0D5C0B5A909192B79F709599BF76");
-    }
-
-    @Test
-    public void testEnabledOnEsimPort_GetAllProfiles() {
-        int channel = mockLogicalChannelResponses(
-                "BF2D18A016E3145A0A896700000000004523019F7001009F2401019000");
-
-        ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.mIsSupportsMultipleEnabledProfiles = true; // MEP capable
-        mEuiccPort.getAllProfiles(resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        EuiccProfileInfo[] profiles = resultCaptor.result;
-        assertEquals(1, profiles.length);
-        assertEquals("98760000000000543210", profiles[0].getIccid());
-        // Even though profilestate is disabled in the response, enabledOnEsimPort is 1
-        // which is valid port. So the state should be enabled.
-        // (As per MEP state and enabledOnEsimPort concept)
-        assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState());
-        verifyStoreData(channel, "BF2D0F5C0D5A909192B79F709599BF769F24");
-    }
-
-    @Test
-    public void testGetAllProfiles_DisableState() {
-        // iccID is 987600000000005432FF.
-        int channel = mockLogicalChannelResponses(
-                "BF2D14A012E3105A0A896700000000004523FF9F7001009000");
-
-        ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.mIsSupportsMultipleEnabledProfiles = true; // MEP capable
-        mEuiccPort.getAllProfiles(resultCaptor, mHandler);
-        processAllMessages();
-
-        EuiccProfileInfo[] profiles = resultCaptor.result;
-        assertEquals(1, profiles.length);
-        assertEquals(EuiccProfileInfo.PROFILE_STATE_DISABLED, profiles[0].getState());
-        verifyStoreData(channel, "BF2D0F5C0D5A909192B79F709599BF769F24");
-    }
-
-    @Test
-    public void testFSuffix() {
-        // iccID is 987600000000005432FF.
-        int channel = mockLogicalChannelResponses(
-                "BF2D14A012E3105A0A896700000000004523FF9F7001019000");
-
-        ResultCaptor<EuiccProfileInfo[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.getAllProfiles(resultCaptor, mHandler);
-        processAllMessages();
-
-        EuiccProfileInfo[] profiles = resultCaptor.result;
-        assertEquals(1, profiles.length);
-        assertEquals("987600000000005432", profiles[0].getIccid());
-        assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profiles[0].getState());
-        verifyStoreData(channel, "BF2D0D5C0B5A909192B79F709599BF76");
-    }
-
-    @Test
-    public void testGetProfile() {
-        int channel = mockLogicalChannelResponses("BF2D8184A08181E37F"
-                + "5A0A89670000000000452301" // ICCID
-                + "90046E69636B" // Nickname
-                + "9103746D6F" // Service provider name
-                + "92027031" // Profile name
-                + "B70F800312F34581030102038203040506" // Operator id
-                + "9F700101" // Profile state
-                + "950101" // Profile class
-                + "990206C0" // Policy rules
-                + "BF7645E243E135C114ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4"
-                + "CA1D636F6D2E676F6F676C652E616E64726F69642E617070732E6D79617070"
-                + "E30ADB080000000000000001" // Carrier privilege rules
-                + "9000");
-
-        ResultCaptor<EuiccProfileInfo> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.getProfile("98760000000000543210", resultCaptor, mHandler);
-        processAllMessages();
-
-        EuiccProfileInfo profile = resultCaptor.result;
-        assertEquals("98760000000000543210", profile.getIccid());
-        assertEquals("nick", profile.getNickname());
-        assertEquals("tmo", profile.getServiceProviderName());
-        assertEquals("p1", profile.getProfileName());
-        assertEquals("213", profile.getCarrierIdentifier().getMcc());
-        assertEquals("54", profile.getCarrierIdentifier().getMnc());
-        assertEquals("010203", profile.getCarrierIdentifier().getGid1());
-        assertEquals("040506", profile.getCarrierIdentifier().getGid2());
-        assertEquals(EuiccProfileInfo.PROFILE_STATE_ENABLED, profile.getState());
-        assertEquals(EuiccProfileInfo.PROFILE_CLASS_PROVISIONING, profile.getProfileClass());
-        assertEquals(
-                EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE
-                        | EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE,
-                profile.getPolicyRules());
-        assertArrayEquals(
-                new UiccAccessRule[] {
-                        new UiccAccessRule(
-                                IccUtils.hexStringToBytes(
-                                        "ABCD92CBB156B280FA4E1429A6ECEEB6E5C1BFE4"),
-                                "com.google.android.apps.myapp", 1)
-                },
-                profile.getUiccAccessRules().toArray());
-        verifyStoreData(channel,
-                "BF2D1BA00C5A0A896700000000004523015C0B5A909192B79F709599BF76");
-    }
-
-    @Test
-    public void testDisableProfile() {
-        int channel = mockLogicalChannelResponses("BF32038001009000");
-
-        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.disableProfile("98760000000000543210", true, resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF");
-    }
-
-    @Test
-    public void testDisableProfile_SimRefresh() {
-        int channel = mockLogicalChannelResponses("6106", "6f00");
-
-        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.disableProfile("98760000000000543210", true, resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF");
-    }
-
-    @Test
-    public void testDisableProfile_Error() {
-        int channel = mockLogicalChannelResponses("BF32038001039000");
-
-        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.disableProfile("98760000000000543210", true, resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
-        verifyStoreData(channel, "BF3211A00C5A0A896700000000004523018101FF");
-    }
-
-    @Test
-    public void testSwitchToProfile() {
-        int channel = mockLogicalChannelResponses("BF31038001009000");
-
-        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.switchToProfile("98760000000000543210", true, resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF");
-    }
-
-    @Test
-    public void testSwitchToProfile_SimRefresh() {
-        int channel = mockLogicalChannelResponses("6106", "6f00");
-
-        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.switchToProfile("98760000000000543210", true, resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF");
-    }
-
-    @Test
-    public void testSwitchToProfile_Error() {
-        int channel = mockLogicalChannelResponses("BF31038001039000");
-
-        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.switchToProfile("98760000000000543210", true, resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
-        verifyStoreData(channel, "BF3111A00C5A0A896700000000004523018101FF");
-    }
-
-    @Test
-    public void testGetEid() {
-        int channel = mockLogicalChannelResponses("BF3E065A041A2B3C4D9000");
-
-        ResultCaptor<String> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.getEid(resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals("1A2B3C4D", resultCaptor.result);
-        verifyStoreData(channel, "BF3E035C015A");
-    }
-
-    @Test
-    public void testSetNickname() {
-        int channel = mockLogicalChannelResponses("BF29038001009000");
-
-        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.setNickname("98760000000000543210", "new nickname", resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        verifyStoreData(channel, "BF291A5A0A89670000000000452301900C6E6577206E69636B6E616D65");
-    }
-
-    @Test
-    public void testDeleteProfile() {
-        int channel = mockLogicalChannelResponses("BF33038001009000");
-
-        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.deleteProfile("98760000000000543210", resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        verifyStoreData(channel, "BF330C5A0A89670000000000452301");
-    }
-
-    @Test
-    public void testDeleteProfile_Error() {
-        int channel = mockLogicalChannelResponses("BF33038001039000");
-
-        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.deleteProfile("98760000000000543210", resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
-        verifyStoreData(channel, "BF330C5A0A89670000000000452301");
-    }
-
-    @Test
-    public void testGetDefaultSmdpAddress() {
-        int channel = mockLogicalChannelResponses(
-                "BF3C148008534D44502E434F4D8108736D64732E636F6D9000");
-
-        ResultCaptor<String> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.getDefaultSmdpAddress(resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals("SMDP.COM", resultCaptor.result);
-        verifyStoreData(channel, "BF3C00");
-    }
-
-    @Test
-    public void testGetSmdsAddress() {
-        int channel = mockLogicalChannelResponses(
-                "BF3C148008534D44502E434F4D8108736D64732E636F6D9000");
-
-        ResultCaptor<String> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.getSmdsAddress(resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals("smds.com", resultCaptor.result);
-        verifyStoreData(channel, "BF3C00");
-    }
-
-    @Test
-    public void testSetDefaultSmdpAddress() {
-        int channel = mockLogicalChannelResponses("BF3F038001009000");
-
-        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.setDefaultSmdpAddress("smdp.gsma.com", resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        verifyStoreData(channel, "BF3F0F800D736D64702E67736D612E636F6D");
-    }
-
-    @Test
-    public void testGetRulesAuthTable() {
-        int channel = mockLogicalChannelResponses("BF434B"
-                + "A0233021" // Rule #1
-                + "800206C0" // Policy rules: DO_NOT_DELETE | DO_NOT_DISABLE
-                + "A118" // Operator IDs
-                + "B70A800312F3458103010203" // ID #1: 213, 54, [1,2,3], null
-                + "B70A800312F3458203040506" // ID #2: 213, 54, null, [4,5,6]
-                + "820108" // Flag (no user consent)
-                + "A0243022" // Rule #2
-                + "80020780" // Policy rules: DO_NOT_DISABLE
-                + "A118" // Operator IDs
-                + "B70A800312E3458103010203" // ID #1: 213, 54E, [1,2,3], null
-                + "B70A8003EEEE458203040506" // ID #2: EEE, 54E, null, [4,5,6]
-                + "82020780" // Flag (user consent)
-                + "9000");
-
-        ResultCaptor<EuiccRulesAuthTable> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.getRulesAuthTable(resultCaptor, mHandler);
-        processAllMessages();
-
-        EuiccRulesAuthTable rat = resultCaptor.result;
-        assertEquals(-1,
-                rat.findIndex(EuiccProfileInfo.POLICY_RULE_DO_NOT_DELETE,
-                        new CarrierIdentifier(new byte[] {0x12, (byte) 0xF3, 0x45}, null, null)));
-        assertEquals(1,
-                rat.findIndex(EuiccProfileInfo.POLICY_RULE_DO_NOT_DISABLE,
-                        new CarrierIdentifier(new byte[] {0x23, 0x67, 0x45}, null, "040506")));
-        assertFalse(rat.hasPolicyRuleFlag(0,
-                EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED));
-        assertTrue(rat.hasPolicyRuleFlag(1,
-                EuiccRulesAuthTable.POLICY_RULE_FLAG_CONSENT_REQUIRED));
-        verifyStoreData(channel, "BF4300");
-    }
-
-    @Test
-    public void testResetMemory() {
-        int channel = mockLogicalChannelResponses("BF34038001009000");
-
-        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.resetMemory(EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES,
-                resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        verifyStoreData(channel, "BF340482020640");
-    }
-
-    @Test
-    public void testResetMemory_SimRefresh() {
-        int channel = mockLogicalChannelResponses("6106", "6f00");
-
-        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.resetMemory(EuiccCardManager.RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES,
-                resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        verifyStoreData(channel, "BF340482020640");
-    }
-
-    @Test
-    public void testGetEuiccChallenge() {
-        int channel = mockLogicalChannelResponses("BF2E0580030102039000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.getEuiccChallenge(resultCaptor, mHandler);
-        processAllMessages();
-
-        assertArrayEquals(new byte[] {1, 2, 3}, resultCaptor.result);
-        verifyStoreData(channel, "BF2E00");
-    }
-
-    @Test
-    public void testGetEuiccInfo1() {
-        int channel = mockLogicalChannelResponses("BF20030102039000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.getEuiccInfo1(resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals("BF2003010203", IccUtils.bytesToHexString(resultCaptor.result));
-        verifyStoreData(channel, "BF2000");
-    }
-
-    @Test
-    public void testGetEuiccInfo2() {
-        int channel = mockLogicalChannelResponses("BF22030102039000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.getEuiccInfo2(resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals("BF2203010203", IccUtils.bytesToHexString(resultCaptor.result));
-        verifyStoreData(channel, "BF2200");
-    }
-
-    @Test
-    public void testAuthenticateServer() {
-        when(mMockResources.getStringArray(
-                com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities))
-                .thenReturn(new String[] {});
-
-        int channel = mockLogicalChannelResponses("BF3802A0009000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.authenticateServer("A1B2C3-X4Y5Z6", // Matching id
-                Asn1Node.newBuilder(0xA0).build().toBytes(),
-                Asn1Node.newBuilder(0xA1).build().toBytes(),
-                Asn1Node.newBuilder(0xA2).build().toBytes(),
-                Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        assertEquals("BF3802A000", IccUtils.bytesToHexString(resultCaptor.result));
-        verifyStoreData(channel,
-                "BF382D" + "A000" + "A100" + "A200" + "A300" + "A023"
-                        + "800D4131423243332D583459355A36" // Matching id
-                        + "A112800489674523" // TAC
-                        + "A100" // Device capabilities
-                        + "82088967452301214305"); // IMEI
-    }
-
-    @Test
-    public void testAuthenticateServer_Error() {
-        when(mMockResources.getStringArray(
-                com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities))
-                .thenReturn(new String[] {});
-
-        int channel = mockLogicalChannelResponses("BF3805A1030201039000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.authenticateServer("A1B2C3-X4Y5Z6", // Matching id
-                Asn1Node.newBuilder(0xA0).build().toBytes(),
-                Asn1Node.newBuilder(0xA1).build().toBytes(),
-                Asn1Node.newBuilder(0xA2).build().toBytes(),
-                Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
-        verifyStoreData(channel,
-                "BF382D" + "A000" + "A100" + "A200" + "A300" + "A023"
-                        + "800D4131423243332D583459355A36" // Matching id
-                        + "A112800489674523" // TAC
-                        + "A100" // Device capabilities
-                        + "82088967452301214305"); // IMEI
-    }
-
-    @Test
-    public void testAuthenticateService_devCap() {
-        when(mMockResources.getStringArray(
-                com.android.internal.R.array.config_telephonyEuiccDeviceCapabilities))
-                .thenReturn(new String[] {
-                        "gsm,11",
-                        "utran,11",
-                        "cdma1x,1",
-                        "hrpd,3",
-                        "ehrpd,12",
-                        "eutran,11"});
-
-        int channel = mockLogicalChannelResponses("BF3802A0009000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.authenticateServer("A1B2C3-X4Y5Z6", // Matching id
-                Asn1Node.newBuilder(0xA0).build().toBytes(),
-                Asn1Node.newBuilder(0xA1).build().toBytes(),
-                Asn1Node.newBuilder(0xA2).build().toBytes(),
-                Asn1Node.newBuilder(0xA3).build().toBytes(), resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        assertEquals("BF3802A000", IccUtils.bytesToHexString(resultCaptor.result));
-        verifyStoreData(channel,
-                "BF384B" + "A000" + "A100" + "A200" + "A300" + "A041"
-                        + "800D4131423243332D583459355A36" // Matching id
-                        + "A130800489674523" // TAC
-                        // Device capabilities
-                        + "A11E80030B000081030B00008203010000830303000084030C000085030B0000"
-                        + "82088967452301214305"); // IMEI
-    }
-
-    @Test
-    public void testPrepareDownload() {
-        int channel = mockLogicalChannelResponses("BF2102A0009000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.prepareDownload(
-                IccUtils.hexStringToBytes("4131423243332D583459355A36"), // hashCc
-                Asn1Node.newBuilder(0xA0).build().toBytes(),
-                Asn1Node.newBuilder(0xA1).build().toBytes(),
-                Asn1Node.newBuilder(0xA2).build().toBytes(), resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals("BF2102A000", IccUtils.bytesToHexString(resultCaptor.result));
-        verifyStoreData(channel,
-                "BF2115" + "A000" + "A100"
-                        + "040D4131423243332D583459355A36" // hashCc
-                        + "A200");
-    }
-
-    @Test
-    public void testPrepareDownload_Error() {
-        int channel = mockLogicalChannelResponses("BF2105A1030201039000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.prepareDownload(
-                IccUtils.hexStringToBytes("4131423243332D583459355A36"), // hashCc
-                Asn1Node.newBuilder(0xA0).build().toBytes(),
-                Asn1Node.newBuilder(0xA1).build().toBytes(),
-                Asn1Node.newBuilder(0xA2).build().toBytes(), resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
-        verifyStoreData(channel,
-                "BF2115" + "A000" + "A100"
-                        + "040D4131423243332D583459355A36" // hashCc
-                        + "A200");
-    }
-
-    @Test
-    public void testLoadBoundProfilePackage() {
-        int channel = mockLogicalChannelResponses(
-                // For boundProfilePackage head + initialiseSecureChannelRequest
-                // (ES8+.InitialiseSecureChannel)
-                "9000",
-                // For firstSequenceOf87 (ES8+.ConfigureISDP)
-                "9000",
-                // For head of sequenceOf88 (ES8+.StoreMetadata)
-                "9000",
-                // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata)
-                "9000",
-                "9000",
-                // For head of sequenceOf86 (ES8+.LoadProfileElements)
-                "9000",
-                // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements)
-                "9000",
-                // Profile installation result (element 2 of sequenceOf86)
-                "BF37009000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.loadBoundProfilePackage(
-                Asn1Node.newBuilder(0xBF36)
-                        .addChild(Asn1Node.newBuilder(0xBF23))
-                        .addChild(Asn1Node.newBuilder(0xA0)
-                                .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
-                        .addChild(Asn1Node.newBuilder(0xA1)
-                                .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
-                        .addChild(Asn1Node.newBuilder(0xA2))
-                        .addChild(Asn1Node.newBuilder(0xA3)
-                                .addChildAsBytes(0x86, new byte[] {7, 8, 9})
-                                .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
-                        .build().toBytes(),
-                resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals("BF3700", IccUtils.bytesToHexString(resultCaptor.result));
-        verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel
-        verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP
-        verifyStoreData(channel, "A105"); // ES8+.StoreMetadata
-        verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata
-        verifyStoreData(channel, "A200");
-        verifyStoreData(channel, "A30A"); // ES8+.LoadProfileElements
-        verifyStoreData(channel, "8603070809"); // ES8+.LoadProfileElements
-        verifyStoreData(channel, "86030A0B0C"); // ES8+.LoadProfileElements
-    }
-
-    @Test
-    public void testLoadBoundProfilePackage_ErrorAtEnd() {
-        int channel = mockLogicalChannelResponses(
-                // For boundProfilePackage head + initialiseSecureChannelRequest
-                // (ES8+.InitialiseSecureChannel)
-                "9000",
-                // For firstSequenceOf87 (ES8+.ConfigureISDP)
-                "9000",
-                // For head of sequenceOf88 (ES8+.StoreMetadata)
-                "9000",
-                // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata)
-                "9000",
-                "9000",
-                // For head of sequenceOf86 (ES8+.LoadProfileElements)
-                "9000",
-                // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements)
-                "9000",
-                // Profile installation result (element 2 of sequenceOf86)
-                "BF370ABF2707A205A1038101039000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.loadBoundProfilePackage(
-                Asn1Node.newBuilder(0xBF36)
-                        .addChild(Asn1Node.newBuilder(0xBF23))
-                        .addChild(Asn1Node.newBuilder(0xA0)
-                                .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
-                        .addChild(Asn1Node.newBuilder(0xA1)
-                                .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
-                        .addChild(Asn1Node.newBuilder(0xA2))
-                        .addChild(Asn1Node.newBuilder(0xA3)
-                                .addChildAsBytes(0x86, new byte[] {7, 8, 9})
-                                .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
-                        .build().toBytes(),
-                resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
-        verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel
-        verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP
-        verifyStoreData(channel, "A105"); // ES8+.StoreMetadata
-        verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata
-        verifyStoreData(channel, "A200");
-        verifyStoreData(channel, "A30A"); // ES8+.LoadProfileElements
-        verifyStoreData(channel, "8603070809"); // ES8+.LoadProfileElements
-        verifyStoreData(channel, "86030A0B0C"); // ES8+.LoadProfileElements
-    }
-
-    @Test
-    public void testLoadBoundProfilePackage_ErrorInMiddle() {
-        int channel = mockLogicalChannelResponses(
-                // For boundProfilePackage head + initialiseSecureChannelRequest
-                // (ES8+.InitialiseSecureChannel)
-                "9000",
-                // For firstSequenceOf87 (ES8+.ConfigureISDP)
-                "9000",
-                // For head of sequenceOf88 (ES8+.StoreMetadata)
-                "9000",
-                // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata)
-                "BF370ABF2707A205A1038101039000",
-                "9000",
-                // For head of sequenceOf86 (ES8+.LoadProfileElements)
-                "9000",
-                // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements)
-                "9000",
-                // Profile installation result (element 2 of sequenceOf86)
-                "9000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.loadBoundProfilePackage(
-                Asn1Node.newBuilder(0xBF36)
-                        .addChild(Asn1Node.newBuilder(0xBF23))
-                        .addChild(Asn1Node.newBuilder(0xA0)
-                                .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
-                        .addChild(Asn1Node.newBuilder(0xA1)
-                                .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
-                        .addChild(Asn1Node.newBuilder(0xA2))
-                        .addChild(Asn1Node.newBuilder(0xA3)
-                                .addChildAsBytes(0x86, new byte[] {7, 8, 9})
-                                .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
-                        .build().toBytes(),
-                resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
-        verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel
-        verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP
-        verifyStoreData(channel, "A105"); // ES8+.StoreMetadata
-        verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata
-    }
-
-    @Test
-    public void testLoadBoundProfilePackage_ErrorStatus() {
-        int channel = mockLogicalChannelResponses(
-                // For boundProfilePackage head + initialiseSecureChannelRequest
-                // (ES8+.InitialiseSecureChannel)
-                "9000",
-                // For firstSequenceOf87 (ES8+.ConfigureISDP)
-                "9000",
-                // For head of sequenceOf88 (ES8+.StoreMetadata)
-                "9000",
-                // For body (element 1) of sequenceOf88 (ES8+.StoreMetadata)
-                "6985",
-                "9000",
-                // For head of sequenceOf86 (ES8+.LoadProfileElements)
-                "9000",
-                // For body (element 1) of sequenceOf86 (ES8+.LoadProfileElements)
-                "9000",
-                // Profile installation result (element 2 of sequenceOf86)
-                "9000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.loadBoundProfilePackage(
-                Asn1Node.newBuilder(0xBF36)
-                        .addChild(Asn1Node.newBuilder(0xBF23))
-                        .addChild(Asn1Node.newBuilder(0xA0)
-                                .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
-                        .addChild(Asn1Node.newBuilder(0xA1)
-                                .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
-                        .addChild(Asn1Node.newBuilder(0xA2))
-                        .addChild(Asn1Node.newBuilder(0xA3)
-                                .addChildAsBytes(0x86, new byte[] {7, 8, 9})
-                                .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
-                        .build().toBytes(),
-                resultCaptor, mHandler);
-        processAllMessages();
-
-        EuiccCardException e = (EuiccCardException) resultCaptor.exception;
-        assertEquals(0x6985, ((ApduException) e.getCause()).getApduStatus());
-        verifyStoreData(channel, "BF361FBF2300"); // ES8+.InitialiseSecureChannel
-        verifyStoreData(channel, "A0058703010203"); // ES8+.ConfigureISDP
-        verifyStoreData(channel, "A105"); // ES8+.StoreMetadata
-        verifyStoreData(channel, "8803040506"); // ES8+.StoreMetadata
-    }
-
-    @Test
-    public void testLoadBoundProfilePackage_NoProfileElements() {
-        int channel = mockLogicalChannelResponses_sgp22v210();
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.loadBoundProfilePackage(
-                Asn1Node.newBuilder(0xBF36)
-                        .addChild(Asn1Node.newBuilder(0xBF23))
-                        .addChild(Asn1Node.newBuilder(0xA0)
-                                .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
-                        .addChild(Asn1Node.newBuilder(0xA1)
-                                .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
-                        .addChild(Asn1Node.newBuilder(0xA2))
-                        // No children
-                        .addChild(Asn1Node.newBuilder(0xA3))
-                        .build().toBytes(),
-                resultCaptor, mHandler);
-        processAllMessages();
-
-        EuiccCardException e = (EuiccCardException) resultCaptor.exception;
-        assertEquals("No profile elements in BPP", e.getCause().getMessage());
-        verify(mMockCi, never())
-                .iccTransmitApduLogicalChannel(
-                        eq(channel), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), any(),
-                        any());
-    }
-
-    @Test
-    public void testLoadBoundProfilePackage_UnrecognizedTag() {
-        int channel = mockLogicalChannelResponses_sgp22v210();
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.loadBoundProfilePackage(
-                Asn1Node.newBuilder(0xBF36)
-                        .addChild(Asn1Node.newBuilder(0xBF23))
-                        .addChild(Asn1Node.newBuilder(0xA0)
-                                .addChildAsBytes(0x87, new byte[] {1, 2, 3}))
-                        .addChild(Asn1Node.newBuilder(0xA1)
-                                .addChildAsBytes(0x88, new byte[] {4, 5, 6}))
-                        .addChild(Asn1Node.newBuilder(0xA2))
-                        .addChild(Asn1Node.newBuilder(0xA3)
-                                .addChildAsBytes(0x86, new byte[] {7, 8, 9})
-                                .addChildAsBytes(0x86, new byte[] {0xA, 0xB, 0xC}))
-                        // Unrecognized tag
-                        .addChild(Asn1Node.newBuilder(0xA4))
-                        .build().toBytes(),
-                resultCaptor, mHandler);
-        processAllMessages();
-
-        EuiccCardException e = (EuiccCardException) resultCaptor.exception;
-        assertEquals(
-                "Actual BPP length (33) does not match segmented length (31), this must be due to a"
-                        + " malformed BPP",
-                e.getCause().getMessage());
-        verify(mMockCi, never())
-                .iccTransmitApduLogicalChannel(
-                        eq(channel), anyInt(), anyInt(), anyInt(), anyInt(), anyInt(), any(),
-                        any());
-    }
-
-    @Test
-    public void testCancelSession() {
-        int channel = mockLogicalChannelResponses("BF41009000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.cancelSession(IccUtils.hexStringToBytes("A1B2C3"),
-                EuiccCardManager.CANCEL_REASON_POSTPONED, resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals("BF4100", IccUtils.bytesToHexString(resultCaptor.result));
-        verifyStoreData(channel, "BF41088003A1B2C3810101");
-    }
-
-    @Test
-    public void testCancelSession_Error() {
-        int channel = mockLogicalChannelResponses("BF41038101039000");
-
-        ResultCaptor<byte[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.cancelSession(IccUtils.hexStringToBytes("A1B2C3"),
-                EuiccCardManager.CANCEL_REASON_POSTPONED, resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
-        verifyStoreData(channel, "BF41088003A1B2C3810101");
-    }
-
-    @Test
-    public void testListNotifications() {
-        int channel = mockLogicalChannelResponses("BF282BA029"
-                + "BF2F118001010C08736D64702E636F6D81020410" // Notification #1
-                + "BF2F128001020C09736D6470322E636F6D81020420" // Notification #2
-                + "9000");
-
-        ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.listNotifications(
-                EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
-                resultCaptor, mHandler);
-        processAllMessages();
-
-        assertArrayEquals(
-                new EuiccNotification[] {
-                        new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE, null),
-                        new EuiccNotification(2, "smdp2.com", EuiccNotification.EVENT_DISABLE, null)
-                },
-                resultCaptor.result);
-        verifyStoreData(channel, "BF280481020430");
-    }
-
-    @Test
-    public void testListNotifications_Error() {
-        int channel = mockLogicalChannelResponses("BF28038101039000");
-
-        ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.listNotifications(
-                EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
-                resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
-        verifyStoreData(channel, "BF280481020430");
-    }
-
-    @Test
-    public void testRetrieveNotificationList() {
-        int channel = mockLogicalChannelResponses("BF2B2FA02D"
-                // Notification #1
-                + "3014BF2F118001010C08736D64702E636F6D81020410"
-                // Notification #2
-                + "3015BF2F128001020C09736D6470322E636F6D81020420"
-                + "9000");
-
-        ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.retrieveNotificationList(
-                EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
-                resultCaptor, mHandler);
-        processAllMessages();
-
-        assertArrayEquals(
-                new EuiccNotification[] {
-                        new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE,
-                                IccUtils.hexStringToBytes(
-                                        "3014BF2F118001010C08736D64702E636F6D81020410")),
-                        new EuiccNotification(2, "smdp2.com", EuiccNotification.EVENT_DISABLE,
-                                IccUtils.hexStringToBytes(
-                                        "3015BF2F128001020C09736D6470322E636F6D81020420"))
-                },
-                resultCaptor.result);
-        verifyStoreData(channel, "BF2B06A00481020430");
-    }
-
-    @Test
-    public void testRetrieveNotificationList_Empty() {
-        int channel = mockLogicalChannelResponses("BF2B038101019000");
-
-        ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.retrieveNotificationList(
-                EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
-                resultCaptor, mHandler);
-        processAllMessages();
-
-        assertArrayEquals(new EuiccNotification[0], resultCaptor.result);
-        verifyStoreData(channel, "BF2B06A00481020430");
-    }
-
-    @Test
-    public void testRetrieveNotificationList_Error() {
-        int channel = mockLogicalChannelResponses("BF2B038101039000");
-
-        ResultCaptor<EuiccNotification[]> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.retrieveNotificationList(
-                EuiccNotification.EVENT_DELETE | EuiccNotification.EVENT_DISABLE,
-                resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals(3, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
-        verifyStoreData(channel, "BF2B06A00481020430");
-    }
-
-    @Test
-    public void testRetrieveNotification() {
-        int channel = mockLogicalChannelResponses("BF2B18A016"
-                + "3014BF2F118001010C08736D64702E636F6D81020410" // Notification
-                + "9000");
-
-        ResultCaptor<EuiccNotification> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.retrieveNotification(5, resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals(
-                new EuiccNotification(1, "smdp.com", EuiccNotification.EVENT_DELETE,
-                        IccUtils.hexStringToBytes("3014BF2F118001010C08736D64702E636F6D81020410")),
-                resultCaptor.result);
-        verifyStoreData(channel, "BF2B05A003800105");
-    }
-
-    @Test
-    public void testRetrieveNotification_Error() {
-        int channel = mockLogicalChannelResponses("BF2B038101019000");
-
-        ResultCaptor<EuiccNotification> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.retrieveNotification(5, resultCaptor, mHandler);
-        processAllMessages();
-
-        assertEquals(1, ((EuiccCardErrorException) resultCaptor.exception).getErrorCode());
-        verifyStoreData(channel, "BF2B05A003800105");
-    }
-
-    @Test
-    public void testRemoveNotificationFromList() {
-        int channel = mockLogicalChannelResponses("BF30038001009000");
-
-        ResultCaptor<Void> resultCaptor = new ResultCaptor<>();
-        mEuiccPort.removeNotificationFromList(5, resultCaptor, mHandler);
-        processAllMessages();
-
-        assertUnexpectedException(resultCaptor.exception);
-        verifyStoreData(channel, "BF3003800105");
-    }
-
-    @Test
-    public void testAddDeviceCapability() throws InvalidAsn1DataException, TagNotFoundException {
-        Asn1Node.Builder devCapsBuilder = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1);
-
-        String devCapItem = "gsm,11";
-        mEuiccPort.addDeviceCapability(devCapsBuilder, devCapItem);
-        Asn1Node node = devCapsBuilder.build();
-
-        assertTrue(node.hasChild(Tags.TAG_CTX_0));
-        Asn1Node child = node.getChild(Tags.TAG_CTX_0);
-        assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes()));
-
-        devCapItem = "utran,11";
-        mEuiccPort.addDeviceCapability(devCapsBuilder, devCapItem);
-        node = devCapsBuilder.build();
-
-        assertTrue(node.hasChild(Tags.TAG_CTX_1));
-        child = node.getChild(Tags.TAG_CTX_1);
-        assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes()));
-
-        devCapItem = "cdma1x,1";
-        mEuiccPort.addDeviceCapability(devCapsBuilder, devCapItem);
-        node = devCapsBuilder.build();
-
-        assertTrue(node.hasChild(Tags.TAG_CTX_2));
-        child = node.getChild(Tags.TAG_CTX_2);
-        assertTrue(Arrays.equals(new byte[] {1, 0 , 0}, child.asBytes()));
-
-        devCapItem = "hrpd,1";
-        mEuiccPort.addDeviceCapability(devCapsBuilder, devCapItem);
-        node = devCapsBuilder.build();
-
-        assertTrue(node.hasChild(Tags.TAG_CTX_3));
-        child = node.getChild(Tags.TAG_CTX_3);
-        assertTrue(Arrays.equals(new byte[] {1, 0 , 0}, child.asBytes()));
-
-        devCapItem = "ehrpd,12";
-        mEuiccPort.addDeviceCapability(devCapsBuilder, devCapItem);
-        node = devCapsBuilder.build();
-
-        assertTrue(node.hasChild(Tags.TAG_CTX_4));
-        child = node.getChild(Tags.TAG_CTX_4);
-        assertTrue(Arrays.equals(new byte[] {12, 0 , 0}, child.asBytes()));
-
-        devCapItem = "eutran,11";
-        mEuiccPort.addDeviceCapability(devCapsBuilder, devCapItem);
-        node = devCapsBuilder.build();
-
-        assertTrue(node.hasChild(Tags.TAG_CTX_5));
-        child = node.getChild(Tags.TAG_CTX_5);
-        assertTrue(Arrays.equals(new byte[] {11, 0 , 0}, child.asBytes()));
-
-        devCapItem = "nfc,0";
-        mEuiccPort.addDeviceCapability(devCapsBuilder, devCapItem);
-        node = devCapsBuilder.build();
-
-        assertTrue(node.hasChild(Tags.TAG_CTX_6));
-        child = node.getChild(Tags.TAG_CTX_6);
-        assertTrue(Arrays.equals(new byte[] {0, 0 , 0}, child.asBytes()));
-
-        devCapItem = "crl,0";
-        mEuiccPort.addDeviceCapability(devCapsBuilder, devCapItem);
-        node = devCapsBuilder.build();
-
-        assertTrue(node.hasChild(Tags.TAG_CTX_7));
-        child = node.getChild(Tags.TAG_CTX_7);
-        assertTrue(Arrays.equals(new byte[] {0, 0 , 0}, child.asBytes()));
-
-        // Array length should not be 3.
-        Asn1Node.Builder devCapsBuilder2 = Asn1Node.newBuilder(Tags.TAG_CTX_COMP_1);
-        devCapItem = "gsm,1,1";
-        mEuiccPort.addDeviceCapability(devCapsBuilder2, devCapItem);
-        node = devCapsBuilder2.build();
-
-        assertFalse(node.hasChild(Tags.TAG_CTX_0));
-    }
-
-    @Test
-    public void testGetDeviceId() {
-        // Unclear v2.0 definition
-        assertArrayEquals(
-                new byte[] {0x21, 0x43, 0x65, (byte) 0x87, 0x09, 0x21, 0x43, 0x05},
-                EuiccPort.getDeviceId("123456789012345", new EuiccSpecVersion(2, 0, 0)));
-        // Clarified v2.1+ definition
-        assertArrayEquals(
-                new byte[] {0x21, 0x43, 0x65, (byte) 0x87, 0x09, 0x21, 0x43, 0x5F},
-                EuiccPort.getDeviceId("123456789012345", new EuiccSpecVersion(2, 1, 0)));
-        // Same definition on v2.2
-        assertArrayEquals(
-                new byte[] {0x21, 0x43, 0x65, (byte) 0x87, 0x09, 0x21, 0x43, 0x5F},
-                EuiccPort.getDeviceId("123456789012345", new EuiccSpecVersion(2, 2, 0)));
-    }
-
-    private void verifyStoreData(int channel, String command) {
-        verify(mMockCi, times(1))
-                .iccTransmitApduLogicalChannel(eq(channel), eq(0x80 | channel), eq(0xE2), eq(0x91),
-                        eq(0), eq(command.length() / 2), eq(command), any());
-    }
-
-    private int mockLogicalChannelResponses(Object... responses) {
-        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi,
-                "E00582030200009000");
-        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, responses);
-        LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel);
-        return channel;
-    }
-
-    private int mockLogicalChannelResponses_sgp22v210(Object... responses) {
-        int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi,
-                "E00582030201009000");
-        LogicalChannelMocker.mockSendToLogicalChannel(mMockCi, channel, responses);
-        LogicalChannelMocker.mockCloseLogicalChannel(mMockCi, channel);
-        return channel;
-    }
-}
diff --git a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/apdu/ApduSenderTest.java b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/apdu/ApduSenderTest.java
index 2b9e767..4a8b842 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/apdu/ApduSenderTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/uicc/euicc/apdu/ApduSenderTest.java
@@ -22,7 +22,6 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -37,10 +36,11 @@
 import com.android.internal.telephony.uicc.IccIoResult;
 import com.android.internal.telephony.uicc.IccUtils;
 
-import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
 
 @RunWith(AndroidTestingRunner.class)
 @TestableLooper.RunWithLooper
@@ -74,7 +74,7 @@
         }
     }
 
-    // Mocked classes
+    @Mock
     private CommandsInterface mMockCi;
 
     private TestableLooper mLooper;
@@ -86,7 +86,7 @@
 
     @Before
     public void setUp() {
-        mMockCi = mock(CommandsInterface.class);
+        MockitoAnnotations.initMocks(this);
         mHandler = new Handler(Looper.myLooper());
 
         mResponseCaptor = new ResponseCaptor();
@@ -96,16 +96,6 @@
         mLooper = TestableLooper.get(this);
     }
 
-    @After
-    public void tearDown() {
-        mHandler.removeCallbacksAndMessages(null);
-        mHandler = null;
-        mLooper = null;
-        mResponseCaptor = null;
-        mSelectResponse = null;
-        mSender = null;
-    }
-
     @Test
     public void testSendEmptyCommands() throws InterruptedException {
         int channel = LogicalChannelMocker.mockOpenLogicalChannelResponse(mMockCi, "A1A1A19000");